Created
October 24, 2017 13:00
-
-
Save brendanbates89/2a9d748607bf02cc819a1a11f4c8917c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 0036429f2f7fd1dff7a9b80d52e58f2f791e6b2b Mon Sep 17 00:00:00 2001 | |
From: Brendan Bates <--------------> | |
Date: Mon, 8 May 2017 15:19:30 -0400 | |
Subject: [PATCH] DTECTIT-41 - Fix issue stemming from the improper cleanup of uncancelled file descriptors in Win32. | |
--- | |
libusb/io.c | 38 ++++++++++++++++++++++++++++++++++++-- | |
libusb/os/windows_nt_common.c | 10 +++++++--- | |
msvc/libusb_dll_2015.vcxproj | 4 ++-- | |
3 files changed, 45 insertions(+), 7 deletions(-) | |
diff --git a/libusb/io.c b/libusb/io.c | |
index bf2b5fa..f01c8d5 100644 | |
--- a/libusb/io.c | |
+++ b/libusb/io.c | |
@@ -1978,7 +1978,7 @@ int API_EXPORTED libusb_wait_for_event(libusb_context *ctx, struct timeval *tv) | |
return (r == ETIMEDOUT); | |
} | |
-static void handle_timeout(struct usbi_transfer *itransfer) | |
+static int handle_timeout(struct usbi_transfer *itransfer) | |
{ | |
struct libusb_transfer *transfer = | |
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); | |
@@ -1991,6 +1991,8 @@ static void handle_timeout(struct usbi_transfer *itransfer) | |
else | |
usbi_warn(TRANSFER_CTX(transfer), | |
"async cancel failed %d errno=%d", r, errno); | |
+ | |
+ return r; | |
} | |
static int handle_timeouts_locked(struct libusb_context *ctx) | |
@@ -2010,6 +2012,9 @@ static int handle_timeouts_locked(struct libusb_context *ctx) | |
TIMESPEC_TO_TIMEVAL(&systime, &systime_ts); | |
+ int remove_size = 0; | |
+ struct usbi_transfer **remove_list = 0; | |
+ | |
/* iterate through flying transfers list, finding all transfers that | |
* have expired timeouts */ | |
list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) { | |
@@ -2030,8 +2035,37 @@ static int handle_timeouts_locked(struct libusb_context *ctx) | |
return 0; | |
/* otherwise, we've got an expired timeout to handle */ | |
- handle_timeout(transfer); | |
+ int result = handle_timeout(transfer); | |
+ | |
+ // Edge Case | |
+ // | |
+ // If the transfer returned "no device", add this transfer to list of transfers that | |
+ // are unable to be cancelled. | |
+ if (result == LIBUSB_ERROR_NO_DEVICE) { | |
+ // Increment size of the remove list. | |
+ remove_size++; | |
+ | |
+ // Reallocate memory. | |
+ if (!remove_list) { | |
+ remove_list = malloc(sizeof(struct usbi_transfer *)); | |
+ } else { | |
+ remove_list = realloc(remove_list, sizeof(struct usbi_transfer *) * remove_size); | |
+ } | |
+ | |
+ // Add to the list. | |
+ remove_list[remove_size - 1] = transfer; | |
+ } | |
} | |
+ | |
+ // Iterate through transfers unable to be cancelled and complete them with an error. | |
+ if (remove_size) { | |
+ for (int i = 0; i < remove_size; ++i) { | |
+ usbi_handle_transfer_completion(remove_list[i], LIBUSB_TRANSFER_STALL); | |
+ } | |
+ | |
+ free(remove_list); | |
+ } | |
+ | |
return 0; | |
} | |
diff --git a/libusb/os/windows_nt_common.c b/libusb/os/windows_nt_common.c | |
index 68eb4a7..da9a8e6 100644 | |
--- a/libusb/os/windows_nt_common.c | |
+++ b/libusb/os/windows_nt_common.c | |
@@ -577,9 +577,13 @@ int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_N | |
// newly allocated wfd that took the place of the one from the transfer. | |
windows_handle_callback(transfer, io_result, io_size); | |
} else { | |
- usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i]); | |
- r = LIBUSB_ERROR_NOT_FOUND; | |
- break; | |
+ // Remove the offending FD. | |
+ usbi_remove_pollfd(ctx, fds[i].fd); | |
+ | |
+ // Free the memory used by the FD. | |
+ struct winfd removing_fd; | |
+ removing_fd.fd = fds[i].fd; | |
+ usbi_free_fd(&removing_fd); | |
} | |
} | |
usbi_mutex_unlock(&ctx->open_devs_lock); | |
-- | |
libgit2 0.26.0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment