diff options
author | David Herrmann <dh.herrmann@googlemail.com> | 2012-06-10 09:16:15 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2012-06-18 07:42:00 -0400 |
commit | 1f9dec1e0164b48da9b268a02197f38caa69b118 (patch) | |
tree | 3352f158c7173094f84deb1cbad25a9a40122d32 /drivers/hid/uhid.c | |
parent | ace3d8614ab0e6544f5f85921085b55b915fe9aa (diff) |
HID: uhid: allow poll()'ing on uhid devices
As long as the internal buffer is not empty, we return POLLIN to
user-space.
uhid->head and uhid->tail are no atomics so the comparison may return
inexact results. However, this doesn't matter here as user-space would
need to poll() in two threads simultaneously to trigger this. And in this
case it doesn't matter if a cached result is returned or the exact new
result as user-space does not know which thread returns first from poll()
and the following read(). So it is safe to compare the values without
locking.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/uhid.c')
-rw-r--r-- | drivers/hid/uhid.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 05ef4b05a63e..b1a477f8260c 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c | |||
@@ -117,6 +117,13 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer, | |||
117 | 117 | ||
118 | static unsigned int uhid_char_poll(struct file *file, poll_table *wait) | 118 | static unsigned int uhid_char_poll(struct file *file, poll_table *wait) |
119 | { | 119 | { |
120 | struct uhid_device *uhid = file->private_data; | ||
121 | |||
122 | poll_wait(file, &uhid->waitq, wait); | ||
123 | |||
124 | if (uhid->head != uhid->tail) | ||
125 | return POLLIN | POLLRDNORM; | ||
126 | |||
120 | return 0; | 127 | return 0; |
121 | } | 128 | } |
122 | 129 | ||