ChangeSet 1.1587.3.49, 2004/05/11 15:45:25-07:00, [EMAIL PROTECTED]

[PATCH] USB: fixes of assumptions about waitqueues

quoting Linus:

--
> so there is no need to recheck the bit in do/while loop, because
> there is no false wakeups now.

You should never assume this. You should assume that there are _always_
false wakeups.

Why? Because Linux has always allowed people to leave wait-queues active,
without being "atomic". For example, the tty read/write layer used to
(still does?)  add itself on the wait-queue _once_, and then leave itself
on the wait-queue while in a loop it does copies from/to user space.
--

Unfortunately, this means us. Here's the first fix. Comments?

  - make sure timeouts are observed even if somebody left us on a queue


 drivers/usb/image/mdc800.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)


diff -Nru a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
--- a/drivers/usb/image/mdc800.c        Fri May 14 15:28:47 2004
+++ b/drivers/usb/image/mdc800.c        Fri May 14 15:28:47 2004
@@ -319,7 +319,9 @@
        set_current_state(TASK_INTERRUPTIBLE);
        if (!mdc800->irq_woken)
        {
-               schedule_timeout (msec*HZ/1000);
+               long timeout = msec*HZ/1000;
+               while(timeout)
+                       timeout = schedule_timeout (timeout);
        }
         remove_wait_queue(&mdc800->irq_wait, &wait);
        set_current_state(TASK_RUNNING);
@@ -718,7 +720,9 @@
                                set_current_state(TASK_INTERRUPTIBLE);
                                if (!mdc800->downloaded)
                                {
-                                       schedule_timeout 
(TO_DOWNLOAD_GET_READY*HZ/1000);
+                                       long timeout = TO_DOWNLOAD_GET_READY*HZ/1000;
+                                       while(timeout)
+                                               timeout = schedule_timeout (timeout);
                                }
                                set_current_state(TASK_RUNNING);
                                remove_wait_queue(&mdc800->download_wait, &wait);
@@ -842,7 +846,9 @@
                        set_current_state(TASK_INTERRUPTIBLE);
                        if (!mdc800->written)
                        {
-                               schedule_timeout (TO_WRITE_GET_READY*HZ/1000);
+                               long timeout = TO_WRITE_GET_READY*HZ/1000;
+                               while(timeout)
+                                       timeout = schedule_timeout (timeout);
                        }
                         set_current_state(TASK_RUNNING);
                        remove_wait_queue(&mdc800->write_wait, &wait);



-------------------------------------------------------
This SF.Net email is sponsored by: SourceForge.net Broadband
Sign-up now for SourceForge Broadband and get the fastest
6.0/768 connection for only $19.95/mo for the first 3 months!
http://ads.osdn.com/?ad_id%62&alloc_ida84&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to