Hi Dave,

does this remove your doubts about race conditions in the synchronous API?

        Regards
                Oliver

You can import this changeset into BK by piping this whole message to:
'| bk receive [path to repository]' or apply the patch as usual.

===================================================================


[EMAIL PROTECTED], 2003-03-19 21:40:48+01:00, [EMAIL PROTECTED]
  - cleanup of synchronous API


 drivers/usb/core/message.c |   55 ++++++++++++++++++---------------------------
 include/linux/wait.h       |   26 +++++++++++++++++++++
 2 files changed, 48 insertions(+), 33 deletions(-)


diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c
--- a/drivers/usb/core/message.c        Wed Mar 19 21:41:41 2003
+++ b/drivers/usb/core/message.c        Wed Mar 19 21:41:41 2003
@@ -34,49 +34,34 @@
 
        init_waitqueue_head(&awd.wqh);  
        awd.done = 0;
-
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       add_wait_queue(&awd.wqh, &wait);
-
        urb->context = &awd;
-       status = usb_submit_urb(urb, GFP_ATOMIC);
+       status = usb_submit_urb(urb, GFP_NOIO);
        if (status) {
                // something went wrong
-               usb_free_urb(urb);
-               set_current_state(TASK_RUNNING);
-               remove_wait_queue(&awd.wqh, &wait);
                return status;
        }
 
-       while (timeout && !awd.done)
-       {
-               timeout = schedule_timeout(timeout);
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               rmb();
+       wait_event_timeout(awd.wqh, awd.done != 0, timeout);
+       
+       if (!awd.done) {
+               /* failure, we have to kill the urb */
+               int ulrv;
+               
+               ulrv = usb_unlink_urb(urb);
+               /* we may have lost the race */
+               if (!ulrv) {
+                       /* we've won */
+                       return -ETIMEDOUT;
+               }
+               /* we've lost - falling back to normal path */
        }
 
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&awd.wqh, &wait);
-
-       if (!timeout && !awd.done) {
-               if (urb->status != -EINPROGRESS) {      /* No callback?!! */
-                       printk(KERN_ERR "usb: raced timeout, "
-                           "pipe 0x%x status %d time left %d\n",
-                           urb->pipe, urb->status, timeout);
-                       status = urb->status;
-               } else {
-                       warn("usb_control/bulk_msg: timeout");
-                       usb_unlink_urb(urb);  // remove urb safely
-                       status = -ETIMEDOUT;
-               }
-       } else
-               status = urb->status;
+       status = urb->status;
 
        if (actual_length)
                *actual_length = urb->actual_length;
-
-       usb_free_urb(urb);
-       return status;
+       
+       return status;
 }
 
 /*-------------------------------------------------------------------*/
@@ -96,6 +81,7 @@
                   usb_api_blocking_completion, 0);
 
        retv = usb_start_wait_urb(urb, timeout, &length);
+       usb_free_urb(urb);
        if (retv < 0)
                return retv;
        else
@@ -182,6 +168,7 @@
                        void *data, int len, int *actual_length, int timeout)
 {
        struct urb *urb;
+       int r;
 
        if (len < 0)
                return -EINVAL;
@@ -193,7 +180,9 @@
        usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
                    usb_api_blocking_completion, 0);
 
-       return usb_start_wait_urb(urb,timeout,actual_length);
+       r = usb_start_wait_urb(urb,timeout,actual_length);
+       usb_free_urb(urb);
+       return r;
 }
 
 /*-------------------------------------------------------------------*/
diff -Nru a/include/linux/wait.h b/include/linux/wait.h
--- a/include/linux/wait.h      Wed Mar 19 21:41:41 2003
+++ b/include/linux/wait.h      Wed Mar 19 21:41:41 2003
@@ -173,6 +173,32 @@
        __ret;                                                          \
 })
 
+#define __wait_event_timeout(wq, condition, ret)                       \
+do {                                                                   \
+       wait_queue_t __wait;                                            \
+       init_waitqueue_entry(&__wait, current);                         \
+                                                                       \
+       add_wait_queue(&wq, &__wait);                                   \
+       for (;;) {                                                      \
+               set_current_state(TASK_UNINTERRUPTIBLE);                \
+               if (condition)                                          \
+                       break;                                          \
+               ret = schedule_timeout(ret);                            \
+               if (!ret)                                               \
+                       break;                                          \
+       }                                                               \
+       current->state = TASK_RUNNING;                                  \
+       remove_wait_queue(&wq, &__wait);                                \
+} while (0)
+
+#define wait_event_timeout(wq, condition, ret)                                 \
+do {                                                                   \
+       if (condition)                                                  \
+               break;                                                  \
+       __wait_event_timeout(wq, condition, ret);                       \
+} while (0)
+
+
 #define __wait_event_interruptible_timeout(wq, condition, ret)         \
 do {                                                                   \
        wait_queue_t __wait;                                            \




-------------------------------------------------------
This SF.net email is sponsored by: Does your code think in ink? 
You could win a Tablet PC. Get a free Tablet PC hat just for playing. 
What are you waiting for?
http://ads.sourceforge.net/cgi-bin/redirect.pl?micr5043en
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to