From ced538fde156cff9fba2064542cae607b0c9e07f Mon Sep 17 00:00:00 2001 From: Graeme Gill Date: Fri, 19 Mar 2010 20:31:36 +0000 Subject: further simplification of pipe and other improvements --- libusb/os/poll_windows.c | 103 +++++++++++++++-------------------------------- 1 file changed, 33 insertions(+), 70 deletions(-) (limited to 'libusb/os/poll_windows.c') diff --git a/libusb/os/poll_windows.c b/libusb/os/poll_windows.c index 2e0fd96..268c3e2 100644 --- a/libusb/os/poll_windows.c +++ b/libusb/os/poll_windows.c @@ -101,7 +101,6 @@ struct winfd poll_fd[MAX_FDS]; // internal fd data struct { CRITICAL_SECTION mutex; // lock for fds - BYTE marker; // 1st byte of a usbi_read operation gets stored here // Additional variables for XP CancelIoEx partial emulation HANDLE original_handle; DWORD thread_id; @@ -154,11 +153,11 @@ void init_polling(void) if (!is_polling_set) { pCancelIoEx = (BOOL (__stdcall *)(HANDLE,LPOVERLAPPED)) GetProcAddress(GetModuleHandle("KERNEL32"), "CancelIoEx"); + pCancelIoEx = NULL; usbi_dbg("Will use CancelIo%s for I/O cancellation", CancelIoEx_Available?"Ex":""); for (i=0; iInternal = STATUS_PENDING; - - overlapped[1] = calloc(1, sizeof(OVERLAPPED)); - if (overlapped[1] == NULL) { - goto out0; - } - // Not so important for the write end... - overlapped[1]->Internal = STATUS_PENDING; + // The overlapped must have status pending for signaling to work in poll + overlapped->Internal = STATUS_PENDING; // Read end of the "pipe" - handle[0] = CreateFileA("NUL", 0, 0, NULL, OPEN_EXISTING, 0, NULL); - if (handle[0] == INVALID_HANDLE_VALUE) { - usbi_err(NULL, "could not create pipe (read end): errcode %d", (int)GetLastError()); + handle = CreateFileA("NUL", 0, 0, NULL, OPEN_EXISTING, 0, NULL); + if (handle == INVALID_HANDLE_VALUE) { + usbi_err(NULL, "could not create pipe: errcode %d", (int)GetLastError()); goto out1; } - filedes[0] = _open_osfhandle((intptr_t)handle[0], _O_RDONLY); - poll_dbg("filedes[0] = %d", filedes[0]); + filedes[0] = _open_osfhandle((intptr_t)handle, _O_RDONLY); + // We can use the same handle for both ends + filedes[1] = filedes[0]; + poll_dbg("pipe filedes = %d", filedes[0]); - // Write end of the "pipe" - handle[1] = CreateFileA("NUL", 0, 0, NULL, OPEN_EXISTING, 0, NULL); - if (handle[1] == INVALID_HANDLE_VALUE) { - usbi_err(NULL, "could not create pipe (write end): errcode %d", (int)GetLastError()); - goto out2; - } - filedes[1] = _open_osfhandle((intptr_t)handle[1], _O_WRONLY); - poll_dbg("filedes[1] = %d", filedes[1]); - - // Use the same event for both overlapped // Note: manual reset must be true (second param) as the reset occurs in read - overlapped[0]->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - if(!overlapped[0]->hEvent) { - goto out3; - } - // If we don't duplicate the event handle, MSVC's debug mode will complain on CloseHandle - if (!DuplicateHandle(GetCurrentProcess(), overlapped[0]->hEvent, - GetCurrentProcess(), &overlapped[1]->hEvent, 0, TRUE, DUPLICATE_SAME_ACCESS)) { - usbi_err(NULL, "failed to duplicate pipe overlapped event handle: errcode %d", (int)GetLastError()); - goto out4; + overlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if(!overlapped->hEvent) { + goto out2; } - for (i=0, j=0; i=2) { - return 0; - } + return 0; } } - CloseHandle(overlapped[1]->hEvent); -out4: - CloseHandle(overlapped[0]->hEvent); -out3: - CloseHandle(handle[1]); + CloseHandle(overlapped->hEvent); out2: - CloseHandle(handle[0]); + CloseHandle(handle); out1: - free(overlapped[1]); -out0: - free(overlapped[0]); + free(overlapped); return -1; } @@ -828,8 +797,7 @@ ssize_t usbi_write(int fd, const void *buf, size_t count) index = _fd_to_index_and_lock(fd); - if ( (index < 0) || (poll_fd[index].overlapped == NULL) - || (poll_fd[index].rw != RW_WRITE) ) { + if ( (index < 0) || (poll_fd[index].overlapped == NULL) ) { errno = EBADF; if (index >= 0) { LeaveCriticalSection(&_poll_fd[index].mutex); @@ -837,7 +805,7 @@ ssize_t usbi_write(int fd, const void *buf, size_t count) return -1; } - poll_dbg("Set pipe event"); + poll_dbg("set pipe event (thread = %08X)", GetCurrentThreadId()); SetEvent(poll_fd[index].overlapped->hEvent); LeaveCriticalSection(&_poll_fd[index].mutex); @@ -866,18 +834,13 @@ ssize_t usbi_read(int fd, void *buf, size_t count) return -1; } - if (poll_fd[index].rw != RW_READ) { - errno = EBADF; - goto out; - } - if (WaitForSingleObject(poll_fd[index].overlapped->hEvent, INFINITE) != WAIT_OBJECT_0) { usbi_warn(NULL, "waiting for event failed: %d", (int)GetLastError()); errno = EIO; goto out; } - poll_dbg("Cleared pipe event"); + poll_dbg("clr pipe event (thread = %08X)", GetCurrentThreadId()); ResetEvent(poll_fd[index].overlapped->hEvent); r = sizeof(unsigned char); -- cgit v1.2.1