summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPete Batard <pbatard@gmail.com>2010-03-12 12:59:04 +0000
committerPete Batard <pbatard@gmail.com>2010-03-12 12:59:04 +0000
commit8c1de7a64d44cf8176836a514ba332cde10484a4 (patch)
tree79522ed99363044baefecff72de2c503c39c3eb1
parent2b47cdb7c8b20fbab0abbaa9ef66d7725af2b94d (diff)
downloadlibusb-r205.tar.gz
remove buggy "completed_synchronously" flag (Graeme Gill)r205
setting this flag in windows_usb.c could be missed by poll use the overlapped.Internal status instead
-rw-r--r--libusb/os/poll_windows.c5
-rw-r--r--libusb/os/poll_windows.h8
-rw-r--r--libusb/os/windows_usb.c12
3 files changed, 15 insertions, 10 deletions
diff --git a/libusb/os/poll_windows.c b/libusb/os/poll_windows.c
index 3bbe615..0fa2dce 100644
--- a/libusb/os/poll_windows.c
+++ b/libusb/os/poll_windows.c
@@ -117,7 +117,7 @@ static inline int _open_osfhandle(intptr_t osfhandle, int flags)
#define CHECK_INIT_POLLING do {if(!is_polling_set) init_polling();} while(0)
// public fd data
-const struct winfd INVALID_WINFD = {-1, NULL, NULL, RW_NONE, FALSE};
+const struct winfd INVALID_WINFD = {-1, NULL, NULL, RW_NONE};
struct winfd poll_fd[MAX_FDS];
// internal fd data
struct {
@@ -385,7 +385,6 @@ int usbi_pipe(int filedes[2])
poll_fd[i].handle = handle[j];
poll_fd[i].overlapped = (j==0)?overlapped0:overlapped1;
poll_fd[i].rw = RW_READ+j;
- poll_fd[i].completed_synchronously = FALSE;
j++;
if (j==1) {
// Start a 1 byte nonblocking read operation
@@ -691,7 +690,7 @@ int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout)
// The following macro only works if overlapped I/O was reported pending
if ( (HasOverlappedIoCompleted(poll_fd[index].overlapped))
- || (poll_fd[index].completed_synchronously) ) {
+ || (HasOverlappedIoCompletedSync(poll_fd[index].overlapped)) ) {
poll_dbg(" completed");
// checks above should ensure this works:
fds[i].revents = fds[i].events;
diff --git a/libusb/os/poll_windows.h b/libusb/os/poll_windows.h
index 0da805b..5de9867 100644
--- a/libusb/os/poll_windows.h
+++ b/libusb/os/poll_windows.h
@@ -39,6 +39,13 @@
#endif
#endif
+// Handle synchronous completion through the overlapped structure
+#if !defined(STATUS_REPARSE) // reuse the REPARSE status code
+#define STATUS_REPARSE ((NTSTATUS)0x00000104L)
+#endif
+#define STATUS_COMPLETED_SYNCHRONOUSLY STATUS_REPARSE
+#define HasOverlappedIoCompletedSync(lpOverlapped) (((DWORD)(lpOverlapped)->Internal) == STATUS_COMPLETED_SYNCHRONOUSLY)
+
enum windows_version {
WINDOWS_UNSUPPORTED,
WINDOWS_XP,
@@ -77,7 +84,6 @@ struct winfd {
HANDLE handle; // what we need to attach overlapped to the I/O op, so we can poll it
OVERLAPPED* overlapped; // what will report our I/O status
enum rw_type rw; // I/O transfer direction: read *XOR* write (NOT BOTH)
- BOOLEAN completed_synchronously;// flag for async transfers that completed during request
};
extern const struct winfd INVALID_WINFD;
diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c
index dd4dac0..53a6a96 100644
--- a/libusb/os/windows_usb.c
+++ b/libusb/os/windows_usb.c
@@ -1933,10 +1933,10 @@ static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds,
if (found) {
// Handle async requests that completed synchronously first
- if (transfer_priv->pollable_fd.completed_synchronously) {
+ if (HasOverlappedIoCompletedSync(transfer_priv->pollable_fd.overlapped)) {
io_result = NO_ERROR;
io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh;
- // Regular saync overlapped
+ // Regular async overlapped
} else if (GetOverlappedResult(transfer_priv->pollable_fd.handle,
transfer_priv->pollable_fd.overlapped, &io_size, false)) {
io_result = NO_ERROR;
@@ -2566,7 +2566,7 @@ static int winusb_submit_control_transfer(struct usbi_transfer *itransfer)
return LIBUSB_ERROR_IO;
}
} else {
- wfd.completed_synchronously = true;
+ wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
wfd.overlapped->InternalHigh = (DWORD)size;
}
@@ -2649,7 +2649,7 @@ static int winusb_submit_bulk_transfer(struct usbi_transfer *itransfer)
return LIBUSB_ERROR_IO;
}
} else {
- wfd.completed_synchronously = true;
+ wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
wfd.overlapped->InternalHigh = (DWORD)transfer->length;
}
@@ -3649,7 +3649,7 @@ static int hid_submit_control_transfer(struct usbi_transfer *itransfer)
if (r == LIBUSB_COMPLETED) {
// Force request to be completed synchronously. Transferred size has been set by previous call
- wfd.completed_synchronously = true;
+ wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
// http://msdn.microsoft.com/en-us/library/ms684342%28VS.85%29.aspx
// set InternalHigh to the number of bytes transferred
wfd.overlapped->InternalHigh = (DWORD)size;
@@ -3738,7 +3738,7 @@ static int hid_submit_bulk_transfer(struct usbi_transfer *itransfer) {
usbi_err(ctx, "OVERFLOW!");
r = LIBUSB_ERROR_OVERFLOW;
}
- wfd.completed_synchronously = true;
+ wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
wfd.overlapped->InternalHigh = size;
}