From: Chris Dickens Date: Tue, 18 Aug 2020 16:19:03 +0000 (-0700) Subject: Windows: Fix I/O completion port thread behavior on error X-Git-Tag: upstream/1.0.24~46 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=37e8b1334e59485e1d4735f5f67b31eba37ae5c9;p=platform%2Fupstream%2Flibusb.git Windows: Fix I/O completion port thread behavior on error The GetQueuedCompletionStatus() returns FALSE when the I/O operation itself does not complete successfully. The I/O completion thread should therefore not exit on this condition. Adjust the check to verify that an OVERLAPPED structure was provided and use an explicit completion key value in the exit path to disambiguate receiving a valid NULL OVERLAPPED pointer. Signed-off-by: Chris Dickens --- diff --git a/libusb/os/windows_common.c b/libusb/os/windows_common.c index 9406632..2f79928 100644 --- a/libusb/os/windows_common.c +++ b/libusb/os/windows_common.c @@ -418,13 +418,18 @@ static unsigned __stdcall windows_iocp_thread(void *arg) usbi_dbg("I/O completion thread started"); while (true) { - if (!GetQueuedCompletionStatus(iocp, &num_bytes, &completion_key, &overlapped, INFINITE)) { + overlapped = NULL; + if (!GetQueuedCompletionStatus(iocp, &num_bytes, &completion_key, &overlapped, INFINITE) && (overlapped == NULL)) { usbi_err(ctx, "GetQueuedCompletionStatus failed: %s", windows_error_str(0)); break; } - if (overlapped == NULL) - break; // Signal to quit + if (overlapped == NULL) { + // Signal to quit + if (completion_key != (ULONG_PTR)ctx) + usbi_err(ctx, "program assertion failed - overlapped is NULL"); + break; + } transfer_priv = container_of(overlapped, struct windows_transfer_priv, overlapped); itransfer = (struct usbi_transfer *)((unsigned char *)transfer_priv + PTR_ALIGN(sizeof(*transfer_priv))); @@ -556,7 +561,7 @@ static void windows_exit(struct libusb_context *ctx) } // A NULL completion status will indicate to the thread that it is time to exit - if (!PostQueuedCompletionStatus(priv->completion_port, 0, 0, NULL)) + if (!PostQueuedCompletionStatus(priv->completion_port, 0, (ULONG_PTR)ctx, NULL)) usbi_err(ctx, "failed to post I/O completion: %s", windows_error_str(0)); if (WaitForSingleObject(priv->completion_port_thread, INFINITE) == WAIT_FAILED) diff --git a/libusb/version_nano.h b/libusb/version_nano.h index bee4117..dfaf221 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 11537 +#define LIBUSB_NANO 11538