diff options
author | Pete Batard <pbatard@gmail.com> | 2010-03-12 12:59:04 +0000 |
---|---|---|
committer | Pete Batard <pbatard@gmail.com> | 2010-03-12 13:17:04 +0000 |
commit | e12eb306fa09702d15124a73852707997401ac12 (patch) | |
tree | cf5a6c7dcdd108b0bf8694fd22a4c420649e55cf | |
parent | ce66adba57849ca31fbc431369fb10dbe44a4982 (diff) | |
download | libusb-e12eb306fa09702d15124a73852707997401ac12.tar.gz |
remove buggy "completed_synchronously" flag (Graeme Gill)
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.c | 5 | ||||
-rw-r--r-- | libusb/os/poll_windows.h | 8 | ||||
-rw-r--r-- | libusb/os/windows_usb.c | 12 |
3 files changed, 15 insertions, 10 deletions
diff --git a/libusb/os/poll_windows.c b/libusb/os/poll_windows.c index 2075468..7033470 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 { @@ -389,7 +389,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 @@ -702,7 +701,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 c3fa9c3..fb79153 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_2K, @@ -78,7 +85,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 9e43a3d..d15130e 100644 --- a/libusb/os/windows_usb.c +++ b/libusb/os/windows_usb.c @@ -2072,10 +2072,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; @@ -2731,7 +2731,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; } @@ -2814,7 +2814,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; } @@ -4543,7 +4543,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; @@ -4632,7 +4632,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; } |