summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPete Batard <pbatard@gmail.com>2010-03-20 23:20:52 +0000
committerPete Batard <pbatard@gmail.com>2010-03-20 23:20:52 +0000
commitae3a15f6b69a15f1940c47a8fc698396f6cc4d06 (patch)
treefef7a61c3010441ccd83a00d564683822f4f9a6b
parentaf66ec02a932088a84662d389115dbedf9a6e899 (diff)
downloadlibusb-ae3a15f6b69a15f1940c47a8fc698396f6cc4d06.tar.gz
fixed loss of pipe events (reported by Travis Robinson)r223_
-rw-r--r--libusb/os/poll_windows.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/libusb/os/poll_windows.c b/libusb/os/poll_windows.c
index b39a8dc..6fdf4b5 100644
--- a/libusb/os/poll_windows.c
+++ b/libusb/os/poll_windows.c
@@ -299,6 +299,7 @@ int usbi_pipe(int filedes[2])
}
// The overlapped must have status pending for signaling to work in poll
overlapped->Internal = STATUS_PENDING;
+ overlapped->InternalHigh = 0;
// Read end of the "pipe"
handle = CreateFileA("NUL", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
@@ -671,7 +672,7 @@ int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout)
LeaveCriticalSection(&_poll_fd[index].mutex);
}
#if defined(DYNAMIC_FDS)
- // Add this stage, new_fd[] should only contain events from fds that
+ // At this stage, new_fd[] should only contain events from fds that
// have been added since the last call to poll, but are not (yet) part
// of the pollable fd set. Typically, these would be from fds that have
// been created between the construction of the fd set and the calling
@@ -807,6 +808,9 @@ ssize_t usbi_write(int fd, const void *buf, size_t count)
poll_dbg("set pipe event (thread = %08X)", GetCurrentThreadId());
SetEvent(poll_fd[index].overlapped->hEvent);
poll_fd[index].overlapped->Internal = STATUS_WAIT_0;
+ // If two threads write on the pipe at the same time, we need to
+ // process two separate reads => use the overlapped as a counter
+ poll_fd[index].overlapped->InternalHigh++;
LeaveCriticalSection(&_poll_fd[index].mutex);
return sizeof(unsigned char);
@@ -841,8 +845,12 @@ ssize_t usbi_read(int fd, void *buf, size_t count)
}
poll_dbg("clr pipe event (thread = %08X)", GetCurrentThreadId());
- ResetEvent(poll_fd[index].overlapped->hEvent);
- poll_fd[index].overlapped->Internal = STATUS_PENDING;
+ poll_fd[index].overlapped->InternalHigh--;
+ // Don't reset unless we don't have any more events to process
+ if (poll_fd[index].overlapped->InternalHigh <= 0) {
+ ResetEvent(poll_fd[index].overlapped->hEvent);
+ poll_fd[index].overlapped->Internal = STATUS_PENDING;
+ }
r = sizeof(unsigned char);