Core: libusb_get_next_timeout() must consider all flying transfers
authorPeter Stuge <peter@stuge.se>
Wed, 3 Nov 2010 20:46:53 +0000 (21:46 +0100)
committerPeter Stuge <peter@stuge.se>
Mon, 13 Jun 2011 20:01:42 +0000 (22:01 +0200)
If transfer->flags indicated that a transfer had a timeout, but no
timeout was actually set, then libusb_get_next_timeout() would look
no further for a timeout, ignoring any transfers later in the list
which had a timeout set.

Since libusb has an internal 60 second timeout this bug could not
cause complete lockup, but it could cause a 60 second timeout even
when a transfer was submitted with a shorter timeout.

libusb/io.c

index c6b42fe..2856324 100644 (file)
@@ -2124,24 +2124,22 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
                if (transfer->flags & (USBI_TRANSFER_TIMED_OUT | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
                        continue;
 
+               /* no timeout for this transfer? */
+               if (!timerisset(&transfer->timeout))
+                       continue;
+
                found = 1;
                break;
        }
        usbi_mutex_unlock(&ctx->flying_transfers_lock);
 
        if (!found) {
-               usbi_dbg("all URBs have already been processed for timeouts");
+               usbi_dbg("no URB with timeout or all handled by OS; no timeout!");
                return 0;
        }
 
        next_timeout = &transfer->timeout;
 
-       /* no timeout for next transfer */
-       if (!timerisset(next_timeout)) {
-               usbi_dbg("no URBs with timeouts, no timeout!");
-               return 0;
-       }
-
        r = usbi_backend->clock_gettime(USBI_CLOCK_MONOTONIC, &cur_ts);
        if (r < 0) {
                usbi_err(ctx, "failed to read monotonic clock, errno=%d", errno);