]> err.no Git - linux-2.6/commitdiff
V4L/DVB (7488): videobuf: Simplify videobuf_waiton logic and possibly avoid missed...
authorBrandon Philips <brandon@ifup.org>
Wed, 2 Apr 2008 21:10:59 +0000 (18:10 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Thu, 24 Apr 2008 17:07:57 +0000 (14:07 -0300)
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>
drivers/media/video/videobuf-core.c

index e4a864e0d96b71bfdccc47f61fcdffa1266ffedc..1ba3aaa29dd0666217bde59cf980b42a0a6777c3 100644 (file)
@@ -64,32 +64,25 @@ void *videobuf_alloc(struct videobuf_queue *q)
        return vb;
 }
 
+#define WAITON_CONDITION (vb->state != VIDEOBUF_ACTIVE &&\
+                               vb->state != VIDEOBUF_QUEUED)
 int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr)
 {
-       int retval = 0;
-       DECLARE_WAITQUEUE(wait, current);
-
        MAGIC_CHECK(vb->magic, MAGIC_BUFFER);
-       add_wait_queue(&vb->done, &wait);
-       while (vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) {
-               if (non_blocking) {
-                       retval = -EAGAIN;
-                       break;
-               }
-               set_current_state(intr  ? TASK_INTERRUPTIBLE
-                                       : TASK_UNINTERRUPTIBLE);
-               if (vb->state == VIDEOBUF_ACTIVE ||
-                   vb->state == VIDEOBUF_QUEUED)
-                       schedule();
-               set_current_state(TASK_RUNNING);
-               if (intr && signal_pending(current)) {
-                       dprintk(1, "buffer waiton: -EINTR\n");
-                       retval = -EINTR;
-                       break;
-               }
+
+       if (non_blocking) {
+               if (WAITON_CONDITION)
+                       return 0;
+               else
+                       return -EAGAIN;
        }
-       remove_wait_queue(&vb->done, &wait);
-       return retval;
+
+       if (intr)
+               return wait_event_interruptible(vb->done, WAITON_CONDITION);
+       else
+               wait_event(vb->done, WAITON_CONDITION);
+
+       return 0;
 }
 
 int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb,