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