diff options
author | Brandon Philips <brandon@ifup.org> | 2008-04-02 17:10:59 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-24 13:07:57 -0400 |
commit | 009a90597e177320e47154dd0817d201f52bcd46 (patch) | |
tree | a5aa9215be722997a33a2c4e2a0ff98db0fe5704 /drivers/media/video/videobuf-core.c | |
parent | b608f4323a0e0440d18fa13aea3db98351137487 (diff) |
V4L/DVB (7488): videobuf: Simplify videobuf_waiton logic and possibly avoid missed wakeup
Possible missed wakeup- use kernel helpers for wait queues
http://www.mail-archive.com/linux-usb-devel@lists.sourceforge.net/msg27983.html
Signed-off-by: Brandon Philips <bphilips@suse.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/videobuf-core.c')
-rw-r--r-- | drivers/media/video/videobuf-core.c | 37 |
1 files changed, 15 insertions, 22 deletions
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index e4a864e0d96b..1ba3aaa29dd0 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c | |||
@@ -64,32 +64,25 @@ void *videobuf_alloc(struct videobuf_queue *q) | |||
64 | return vb; | 64 | return vb; |
65 | } | 65 | } |
66 | 66 | ||
67 | #define WAITON_CONDITION (vb->state != VIDEOBUF_ACTIVE &&\ | ||
68 | vb->state != VIDEOBUF_QUEUED) | ||
67 | int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr) | 69 | int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr) |
68 | { | 70 | { |
69 | int retval = 0; | ||
70 | DECLARE_WAITQUEUE(wait, current); | ||
71 | |||
72 | MAGIC_CHECK(vb->magic, MAGIC_BUFFER); | 71 | MAGIC_CHECK(vb->magic, MAGIC_BUFFER); |
73 | add_wait_queue(&vb->done, &wait); | 72 | |
74 | while (vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) { | 73 | if (non_blocking) { |
75 | if (non_blocking) { | 74 | if (WAITON_CONDITION) |
76 | retval = -EAGAIN; | 75 | return 0; |
77 | break; | 76 | else |
78 | } | 77 | return -EAGAIN; |
79 | set_current_state(intr ? TASK_INTERRUPTIBLE | ||
80 | : TASK_UNINTERRUPTIBLE); | ||
81 | if (vb->state == VIDEOBUF_ACTIVE || | ||
82 | vb->state == VIDEOBUF_QUEUED) | ||
83 | schedule(); | ||
84 | set_current_state(TASK_RUNNING); | ||
85 | if (intr && signal_pending(current)) { | ||
86 | dprintk(1, "buffer waiton: -EINTR\n"); | ||
87 | retval = -EINTR; | ||
88 | break; | ||
89 | } | ||
90 | } | 78 | } |
91 | remove_wait_queue(&vb->done, &wait); | 79 | |
92 | return retval; | 80 | if (intr) |
81 | return wait_event_interruptible(vb->done, WAITON_CONDITION); | ||
82 | else | ||
83 | wait_event(vb->done, WAITON_CONDITION); | ||
84 | |||
85 | return 0; | ||
93 | } | 86 | } |
94 | 87 | ||
95 | int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb, | 88 | int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb, |