From 2e1781e7c57384166e04d7728c42e45665d07b09 Mon Sep 17 00:00:00 2001 From: Chris Dickens Date: Sat, 22 Aug 2015 00:41:58 -0700 Subject: [PATCH] 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 --- libusb/io.c | 7 ++++--- libusb/libusbi.h | 3 +++ libusb/version_nano.h | 2 +- 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 -- 2.7.4