summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Dickens <christopher.a.dickens@gmail.com>2015-08-22 00:41:58 -0700
committerChris Dickens <christopher.a.dickens@gmail.com>2015-09-02 19:47:15 -0700
commit2e1781e7c57384166e04d7728c42e45665d07b09 (patch)
tree8b287f752a464c2a2b61e9a37e818959c5b3323c
parent8c24a1b9302a0b1b921b4ffaefd7bd7c8d0f21e8 (diff)
downloadlibusb-2e1781e7c57384166e04d7728c42e45665d07b09.tar.gz
core: Record when a transfer timeout has been handled
Commit efd02e73 introduced a bug where transfers that timed out would be handled repeatedly if the cancellation was not successful. This behavior blocks any event handling from occurring. This commit adds a new transfer flag to record whether a timeout has been handled. Thanks to Jeffrey Nichols for reporting this. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
-rw-r--r--libusb/io.c7
-rw-r--r--libusb/libusbi.h3
-rw-r--r--libusb/version_nano.h2
3 files changed, 8 insertions, 4 deletions
diff --git a/libusb/io.c b/libusb/io.c
index 420f87a..082441c 100644
--- a/libusb/io.c
+++ b/libusb/io.c
@@ -1332,7 +1332,7 @@ static int arm_timerfd_for_next_timeout(struct libusb_context *ctx)
goto disarm;
/* act on first transfer that is not already cancelled */
- if (!(transfer->flags & USBI_TRANSFER_TIMED_OUT)) {
+ if (!(transfer->flags & USBI_TRANSFER_TIMEOUT_HANDLED)) {
int r;
const struct itimerspec it = { {0, 0},
{ cur_tv->tv_sec, cur_tv->tv_usec * 1000 } };
@@ -1944,6 +1944,7 @@ static void handle_timeout(struct usbi_transfer *itransfer)
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
int r;
+ itransfer->flags |= USBI_TRANSFER_TIMEOUT_HANDLED;
r = libusb_cancel_transfer(transfer);
if (r == 0)
itransfer->flags |= USBI_TRANSFER_TIMED_OUT;
@@ -1979,7 +1980,7 @@ static int handle_timeouts_locked(struct libusb_context *ctx)
return 0;
/* ignore timeouts we've already handled */
- if (transfer->flags & (USBI_TRANSFER_TIMED_OUT | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
+ if (transfer->flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
continue;
/* if transfer has non-expired timeout, nothing more to do */
@@ -2506,7 +2507,7 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
/* find next transfer which hasn't already been processed as timed out */
list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
- if (transfer->flags & (USBI_TRANSFER_TIMED_OUT | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
+ if (transfer->flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
continue;
/* if we've reached transfers of infinte timeout, we're done looking */
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
index cbd1150..822612e 100644
--- a/libusb/libusbi.h
+++ b/libusb/libusbi.h
@@ -435,6 +435,9 @@ enum usbi_transfer_flags {
/* Completion handler has run */
USBI_TRANSFER_COMPLETED = 1 << 6,
+
+ /* The transfer timeout has been handled */
+ USBI_TRANSFER_TIMEOUT_HANDLED = 1 << 7,
};
#define USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer) \
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index 58b4c88..a1bec0a 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 10997
+#define LIBUSB_NANO 10998