diff options
author | Pete Batard <pbatard@gmail.com> | 2010-02-02 23:56:27 +0000 |
---|---|---|
committer | Pete Batard <pbatard@gmail.com> | 2010-02-02 23:56:27 +0000 |
commit | 05ac09d594ac6cbb907e2d39667f23a0462f0405 (patch) | |
tree | 4dd14d692eb712cad369def2c8e54a6788221dc7 /libusb | |
parent | b1b43b6047ff1829e4452ce3e6a0e6334aa0ac36 (diff) | |
download | libusb-05ac09d594ac6cbb907e2d39667f23a0462f0405.tar.gz |
r137: compat layer TODOs and small fixes:r137
- use CancelIoEx when available
- handle pending Overlapped / extra data
- move windows version to compat
Diffstat (limited to 'libusb')
-rw-r--r-- | libusb/os/windows_compat.c | 47 | ||||
-rw-r--r-- | libusb/os/windows_compat.h | 7 | ||||
-rw-r--r-- | libusb/os/windows_usb.c | 3 | ||||
-rw-r--r-- | libusb/os/windows_usb.h | 7 |
4 files changed, 42 insertions, 22 deletions
diff --git a/libusb/os/windows_compat.c b/libusb/os/windows_compat.c index 98eefaf..ee6a8df 100644 --- a/libusb/os/windows_compat.c +++ b/libusb/os/windows_compat.c @@ -60,11 +60,6 @@ * use the OVERLAPPED directly (which is what we do in the USB async I/O * functions), the marker is not used at all. */ - -/* - * TODO: Once MinGW supports it (or for other compilation platforms) use - * CancelIoEx instead of CancelIo for Vista and later platforms - */ #include <windows.h> #include <errno.h> #include <fcntl.h> @@ -138,6 +133,24 @@ BOOLEAN is_polling_set = FALSE; LONG pipe_number = 0; static volatile LONG compat_spinlock = 0; +// Attempt to use CancelIoEx on platforms and environments supporting it +// NB: this fucntion doesn't care about the validity of the handles +__inline BOOL cancel_io(int index) +{ + if ((index < 0) || (index >= MAX_FDS)) { + return FALSE; + } + if (windows_version < WINDOWS_VISTA_AND_LATER) { + return CancelIo(poll_fd[index].handle); + } + // cygwin and MinGW don't have Ex for now... +#if !defined(_MSC_VER) + return CancelIo(poll_fd[index].handle); +#else + return CancelIoEx(poll_fd[index].handle, poll_fd[index].overlapped); +#endif +} + // Init void init_polling(void) { @@ -231,7 +244,7 @@ void exit_polling(void) for (i=0; i<MAX_FDS; i++) { // Cancel any async I/O (handle can be invalid) - CancelIo(poll_fd[i].handle); + cancel_io(i); // If anything was pending on that I/O, it should be // terminating, and we should be able to access the fd // mutex lock before too long @@ -257,7 +270,7 @@ void exit_polling(void) __inline void _init_read_marker(int index) { // Cancel any read operation in progress - CancelIo(poll_fd[index].handle); + cancel_io(index); // Setup a new async read on our marker reset_overlapped(poll_fd[index].overlapped); if (!ReadFile(poll_fd[index].handle, &_poll_fd[index].marker, 1, NULL, poll_fd[index].overlapped)) { @@ -268,7 +281,10 @@ __inline void _init_read_marker(int index) } else { // We got some sync I/O. We'll pretend it's async and set overlapped manually printb("_init_read_marker: marker readout completed before exit!\n"); - // TODO: check IO_PENDING cleared? + if (!HasOverlappedIoCompleted(poll_fd[index].overlapped)) { + printb("_init_read_marker: completed I/O still flagged as pending\n"); + poll_fd[index].overlapped->Internal = 0; + } SetEvent(poll_fd[index].overlapped->hEvent); poll_fd[index].overlapped->InternalHigh = 1; } @@ -298,8 +314,11 @@ int _libusb_pipe(int filedes[2]) return -1; } - our_pipe_number = InterlockedIncrement(&pipe_number) - 1; // - 1 to mirror postfix operation inside _snprintf - our_pipe_number &= 0xFFFF; // Could warn if this was necessary (ToDo) + our_pipe_number = InterlockedIncrement(&pipe_number) - 1; // - 1 to mirror postfix operation inside _snprintf + if (our_pipe_number >= 0x10000) { + fprintf(stderr, "_libusb_pipe: program assertion failed - more than 65536 pipes were used"); + our_pipe_number &= 0xFFFF; + } _snprintf(pipe_name, sizeof(pipe_name), "\\\\.\\pipe\\libusb%08x%04x", (unsigned)GetCurrentProcessId(), our_pipe_number); // Read end of the pipe @@ -446,7 +465,7 @@ struct winfd _libusb_create_fd(HANDLE handle, int access_mode) void _free_index(int index) { // Cancel any async IO (Don't care about the validity of our handles for this) - CancelIo(poll_fd[index].handle); + cancel_io(index); // close fake handle for devices if ( (poll_fd[index].handle != INVALID_HANDLE_VALUE) && (poll_fd[index].handle != 0) && (GetFileType(poll_fd[index].handle) == FILE_TYPE_UNKNOWN) ) { @@ -729,7 +748,7 @@ ssize_t _libusb_write(int fd, const void *buf, size_t count) // For sync mode, we shouldn't get pending async write I/O if (!HasOverlappedIoCompleted(poll_fd[index].overlapped)) { printb("_libusb_write: previous write I/O was flagged pending!\n"); - CancelIo(poll_fd[index].handle); + cancel_io(index); } printb("_libusb_write: writing %d bytes to fd=%d\n", count, poll_fd[index].fd); @@ -842,7 +861,9 @@ ssize_t _libusb_read(int fd, void *buf, size_t count) if (!ReadFile(poll_fd[index].handle, (char*)buf+1, (DWORD)(count-1), &rd_count, poll_fd[index].overlapped)) { if(GetLastError() == ERROR_IO_PENDING) { if (!GetOverlappedResult(poll_fd[index].handle, poll_fd[index].overlapped, &rd_count, TRUE)) { - // TODO: handle more data! + if (GetLastError() == ERROR_MORE_DATA) { + printb("_libusb_read: could not fetch all data\n"); + } printb("_libusb_read: readout of supplementary data failed: %d\n", (int)GetLastError()); errno = EIO; goto out; diff --git a/libusb/os/windows_compat.h b/libusb/os/windows_compat.h index f228782..76f8417 100644 --- a/libusb/os/windows_compat.h +++ b/libusb/os/windows_compat.h @@ -34,6 +34,13 @@ #endif #endif +enum windows_version { + WINDOWS_UNSUPPORTED, + WINDOWS_XP, + WINDOWS_VISTA_AND_LATER, +}; +extern enum windows_version windows_version; + #define MAX_FDS 256 #define POLLIN 0x0001 /* There is data to read */ diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c index 00762fa..aa97ed2 100644 --- a/libusb/os/windows_usb.c +++ b/libusb/os/windows_usb.c @@ -394,7 +394,7 @@ static int windows_init(struct libusb_context *ctx) windows_version = WINDOWS_VISTA_AND_LATER; } } - if (windows_version == WINDOWS_UNSUPPORTED) { + if (windows_version == WINDOWS_UNSUPPORTED) { usbi_err(ctx, "This version of Windows is NOT supported"); r = LIBUSB_ERROR_NOT_SUPPORTED; goto init_exit; @@ -3403,7 +3403,6 @@ static int hid_submit_bulk_transfer(struct usbi_transfer *itransfer) { bool direction_in, ret; int current_interface; DWORD size; - unsigned char buf[256]; CHECK_HID_AVAILABLE; diff --git a/libusb/os/windows_usb.h b/libusb/os/windows_usb.h index ddf1748..12a90c8 100644 --- a/libusb/os/windows_usb.h +++ b/libusb/os/windows_usb.h @@ -147,13 +147,6 @@ extern const struct windows_usb_api_backend usb_api_backend[USB_API_MAX]; #fname "'"); \ return LIBUSB_ERROR_NOT_SUPPORTED; -enum windows_version { - WINDOWS_UNSUPPORTED, - WINDOWS_XP, - WINDOWS_VISTA_AND_LATER, -}; - - /* * private structures definition * with inline pseudo constructors/destructors |