2 * poll_windows: poll compatibility wrapper for Windows
3 * Copyright © 2009-2010 Pete Batard <pbatard@gmail.com>
4 * With contributions from Michael Plante, Orin Eman et al.
5 * Parts of poll implementation from libusb-win32, by Stephan Meyer et al.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 * poll() and pipe() Windows compatibility layer for libusbx 1.0
26 * The way this layer works is by using OVERLAPPED with async I/O transfers, as
27 * OVERLAPPED have an associated event which is flagged for I/O completion.
29 * For USB pollable async I/O, you would typically:
30 * - obtain a Windows HANDLE to a file or device that has been opened in
32 * - call usbi_create_fd with this handle to obtain a custom fd.
33 * Note that if you need simultaneous R/W access, you need to call create_fd
34 * twice, once in RW_READ and once in RW_WRITE mode to obtain 2 separate
36 * - leave the core functions call the poll routine and flag POLLIN/POLLOUT
38 * The pipe pollable synchronous I/O works using the overlapped event associated
39 * with a fake pipe. The read/write functions are only meant to be used in that
48 // Uncomment to debug the polling layer
49 //#define DEBUG_POLL_WINDOWS
50 #if defined(DEBUG_POLL_WINDOWS)
51 #define poll_dbg usbi_dbg
53 // MSVC++ < 2005 cannot use a variadic argument and non MSVC
54 // compilers produce warnings if parenthesis are ommitted.
55 #if defined(_MSC_VER) && _MSC_VER < 1400
62 #if defined(_PREFAST_)
63 #pragma warning(disable:28719)
66 #if defined(_WIN32_WCE)
67 #define usbi_sleep(ms) Sleep(ms)
69 #define usbi_sleep(ms) SleepEx(ms, TRUE)
72 #define CHECK_INIT_POLLING do {if(!is_polling_set) init_polling();} while(0)
75 const struct winfd INVALID_WINFD = {-1, INVALID_HANDLE_VALUE, NULL, NULL, NULL, RW_NONE};
76 struct winfd poll_fd[MAX_FDS];
79 CRITICAL_SECTION mutex; // lock for fds
80 // Additional variables for XP CancelIoEx partial emulation
81 HANDLE original_handle;
86 BOOLEAN is_polling_set = FALSE;
88 static volatile LONG compat_spinlock = 0;
90 #if !defined(_WIN32_WCE)
91 // CancelIoEx, available on Vista and later only, provides the ability to cancel
92 // a single transfer (OVERLAPPED) when used. As it may not be part of any of the
93 // platform headers, we hook into the Kernel32 system DLL directly to seek it.
94 static BOOL (__stdcall *pCancelIoEx)(HANDLE, LPOVERLAPPED) = NULL;
95 #define Use_Duplicate_Handles (pCancelIoEx == NULL)
97 static inline void setup_cancel_io(void)
99 pCancelIoEx = (BOOL (__stdcall *)(HANDLE,LPOVERLAPPED))
100 GetProcAddress(GetModuleHandleA("KERNEL32"), "CancelIoEx");
101 usbi_dbg("Will use CancelIo%s for I/O cancellation",
102 Use_Duplicate_Handles?"":"Ex");
105 static inline BOOL cancel_io(int _index)
107 if ((_index < 0) || (_index >= MAX_FDS)) {
111 if ( (poll_fd[_index].fd < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
112 || (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL) ) {
115 if (poll_fd[_index].itransfer && poll_fd[_index].cancel_fn) {
116 // Cancel outstanding transfer via the specific callback
117 (*poll_fd[_index].cancel_fn)(poll_fd[_index].itransfer);
120 if (pCancelIoEx != NULL) {
121 return (*pCancelIoEx)(poll_fd[_index].handle, poll_fd[_index].overlapped);
123 if (_poll_fd[_index].thread_id == GetCurrentThreadId()) {
124 return CancelIo(poll_fd[_index].handle);
126 usbi_warn(NULL, "Unable to cancel I/O that was started from another thread");
130 #define Use_Duplicate_Handles FALSE
132 static __inline void setup_cancel_io()
134 // No setup needed on WinCE
137 static __inline BOOL cancel_io(int _index)
139 if ((_index < 0) || (_index >= MAX_FDS)) {
142 if ( (poll_fd[_index].fd < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
143 || (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL) ) {
146 if (poll_fd[_index].itransfer && poll_fd[_index].cancel_fn) {
147 // Cancel outstanding transfer via the specific callback
148 (*poll_fd[_index].cancel_fn)(poll_fd[_index].itransfer);
155 void init_polling(void)
159 while (InterlockedExchange((LONG *)&compat_spinlock, 1) == 1) {
162 if (!is_polling_set) {
164 for (i=0; i<MAX_FDS; i++) {
165 poll_fd[i] = INVALID_WINFD;
166 _poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
167 _poll_fd[i].thread_id = 0;
168 InitializeCriticalSection(&_poll_fd[i].mutex);
170 is_polling_set = TRUE;
172 InterlockedExchange((LONG *)&compat_spinlock, 0);
175 // Internal function to retrieve the table index (and lock the fd mutex)
176 static int _fd_to_index_and_lock(int fd)
183 for (i=0; i<MAX_FDS; i++) {
184 if (poll_fd[i].fd == fd) {
185 EnterCriticalSection(&_poll_fd[i].mutex);
186 // fd might have changed before we got to critical
187 if (poll_fd[i].fd != fd) {
188 LeaveCriticalSection(&_poll_fd[i].mutex);
197 static OVERLAPPED *create_overlapped(void)
199 OVERLAPPED *overlapped = (OVERLAPPED*) calloc(1, sizeof(OVERLAPPED));
200 if (overlapped == NULL) {
203 overlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
204 if(overlapped->hEvent == NULL) {
211 static void free_overlapped(OVERLAPPED *overlapped)
213 if (overlapped == NULL)
216 if ( (overlapped->hEvent != 0)
217 && (overlapped->hEvent != INVALID_HANDLE_VALUE) ) {
218 CloseHandle(overlapped->hEvent);
223 static void reset_overlapped(OVERLAPPED *overlapped)
226 if (overlapped == NULL)
229 event_handle = overlapped->hEvent;
230 if (event_handle != NULL) {
231 ResetEvent(event_handle);
233 memset(overlapped, 0, sizeof(OVERLAPPED));
234 overlapped->hEvent = event_handle;
237 void exit_polling(void)
241 while (InterlockedExchange((LONG *)&compat_spinlock, 1) == 1) {
244 if (is_polling_set) {
245 is_polling_set = FALSE;
247 for (i=0; i<MAX_FDS; i++) {
248 // Cancel any async I/O (handle can be invalid)
250 // If anything was pending on that I/O, it should be
251 // terminating, and we should be able to access the fd
252 // mutex lock before too long
253 EnterCriticalSection(&_poll_fd[i].mutex);
254 free_overlapped(poll_fd[i].overlapped);
255 if (Use_Duplicate_Handles) {
256 // Close duplicate handle
257 if (_poll_fd[i].original_handle != INVALID_HANDLE_VALUE) {
258 CloseHandle(poll_fd[i].handle);
261 poll_fd[i] = INVALID_WINFD;
262 LeaveCriticalSection(&_poll_fd[i].mutex);
263 DeleteCriticalSection(&_poll_fd[i].mutex);
266 InterlockedExchange((LONG *)&compat_spinlock, 0);
270 * Create a fake pipe.
271 * As libusbx only uses pipes for signaling, all we need from a pipe is an
272 * event. To that extent, we create a single wfd and overlapped as a means
273 * to access that event.
275 int usbi_pipe(int filedes[2])
278 OVERLAPPED* overlapped;
282 overlapped = create_overlapped();
284 if (overlapped == NULL) {
287 // The overlapped must have status pending for signaling to work in poll
288 overlapped->Internal = STATUS_PENDING;
289 overlapped->InternalHigh = 0;
291 for (i=0; i<MAX_FDS; i++) {
292 if (poll_fd[i].fd < 0) {
293 EnterCriticalSection(&_poll_fd[i].mutex);
294 // fd might have been allocated before we got to critical
295 if (poll_fd[i].fd >= 0) {
296 LeaveCriticalSection(&_poll_fd[i].mutex);
300 // Use index as the unique fd number
302 // Read end of the "pipe"
303 filedes[0] = poll_fd[i].fd;
304 // We can use the same handle for both ends
305 filedes[1] = filedes[0];
307 poll_fd[i].handle = DUMMY_HANDLE;
308 poll_fd[i].overlapped = overlapped;
309 // There's no polling on the write end, so we just use READ for our needs
310 poll_fd[i].rw = RW_READ;
311 _poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
312 LeaveCriticalSection(&_poll_fd[i].mutex);
316 free_overlapped(overlapped);
321 * Create both an fd and an OVERLAPPED from an open Windows handle, so that
322 * it can be used with our polling function
323 * The handle MUST support overlapped transfers (usually requires CreateFile
324 * with FILE_FLAG_OVERLAPPED)
325 * Return a pollable file descriptor struct, or INVALID_WINFD on error
327 * Note that the fd returned by this function is a per-transfer fd, rather
328 * than a per-session fd and cannot be used for anything else but our
329 * custom functions (the fd itself points to the NUL: device)
330 * if you plan to do R/W on the same handle, you MUST create 2 fds: one for
331 * read and one for write. Using a single R/W fd is unsupported and will
332 * produce unexpected results
334 struct winfd usbi_create_fd(HANDLE handle, int access_mode, struct usbi_transfer *itransfer, cancel_transfer *cancel_fn)
337 struct winfd wfd = INVALID_WINFD;
338 OVERLAPPED* overlapped = NULL;
342 if ((handle == 0) || (handle == INVALID_HANDLE_VALUE)) {
343 return INVALID_WINFD;
346 wfd.itransfer = itransfer;
347 wfd.cancel_fn = cancel_fn;
349 if ((access_mode != RW_READ) && (access_mode != RW_WRITE)) {
350 usbi_warn(NULL, "only one of RW_READ or RW_WRITE are supported.\n"
351 "If you want to poll for R/W simultaneously, create multiple fds from the same handle.");
352 return INVALID_WINFD;
354 if (access_mode == RW_READ) {
360 overlapped = create_overlapped();
361 if(overlapped == NULL) {
362 return INVALID_WINFD;
365 for (i=0; i<MAX_FDS; i++) {
366 if (poll_fd[i].fd < 0) {
367 EnterCriticalSection(&_poll_fd[i].mutex);
368 // fd might have been removed before we got to critical
369 if (poll_fd[i].fd >= 0) {
370 LeaveCriticalSection(&_poll_fd[i].mutex);
373 // Use index as the unique fd number
375 // Attempt to emulate some of the CancelIoEx behaviour on platforms
376 // that don't have it
377 if (Use_Duplicate_Handles) {
378 _poll_fd[i].thread_id = GetCurrentThreadId();
379 if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(),
380 &wfd.handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
381 usbi_dbg("could not duplicate handle for CancelIo - using original one");
383 // Make sure we won't close the original handle on fd deletion then
384 _poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
386 _poll_fd[i].original_handle = handle;
391 wfd.overlapped = overlapped;
392 memcpy(&poll_fd[i], &wfd, sizeof(struct winfd));
393 LeaveCriticalSection(&_poll_fd[i].mutex);
397 free_overlapped(overlapped);
398 return INVALID_WINFD;
401 static void _free_index(int _index)
403 // Cancel any async IO (Don't care about the validity of our handles for this)
405 // close the duplicate handle (if we have an actual duplicate)
406 if (Use_Duplicate_Handles) {
407 if (_poll_fd[_index].original_handle != INVALID_HANDLE_VALUE) {
408 CloseHandle(poll_fd[_index].handle);
410 _poll_fd[_index].original_handle = INVALID_HANDLE_VALUE;
411 _poll_fd[_index].thread_id = 0;
413 free_overlapped(poll_fd[_index].overlapped);
414 poll_fd[_index] = INVALID_WINFD;
418 * Release a pollable file descriptor.
420 * Note that the associated Windows handle is not closed by this call
422 void usbi_free_fd(int fd)
428 _index = _fd_to_index_and_lock(fd);
433 LeaveCriticalSection(&_poll_fd[_index].mutex);
437 * The functions below perform various conversions between fd, handle and OVERLAPPED
439 struct winfd fd_to_winfd(int fd)
447 return INVALID_WINFD;
449 for (i=0; i<MAX_FDS; i++) {
450 if (poll_fd[i].fd == fd) {
451 EnterCriticalSection(&_poll_fd[i].mutex);
452 // fd might have been deleted before we got to critical
453 if (poll_fd[i].fd != fd) {
454 LeaveCriticalSection(&_poll_fd[i].mutex);
457 memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
458 LeaveCriticalSection(&_poll_fd[i].mutex);
462 return INVALID_WINFD;
465 struct winfd handle_to_winfd(HANDLE handle)
472 if ((handle == 0) || (handle == INVALID_HANDLE_VALUE))
473 return INVALID_WINFD;
475 for (i=0; i<MAX_FDS; i++) {
476 if (poll_fd[i].handle == handle) {
477 EnterCriticalSection(&_poll_fd[i].mutex);
478 // fd might have been deleted before we got to critical
479 if (poll_fd[i].handle != handle) {
480 LeaveCriticalSection(&_poll_fd[i].mutex);
483 memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
484 LeaveCriticalSection(&_poll_fd[i].mutex);
488 return INVALID_WINFD;
491 struct winfd overlapped_to_winfd(OVERLAPPED* overlapped)
498 if (overlapped == NULL)
499 return INVALID_WINFD;
501 for (i=0; i<MAX_FDS; i++) {
502 if (poll_fd[i].overlapped == overlapped) {
503 EnterCriticalSection(&_poll_fd[i].mutex);
504 // fd might have been deleted before we got to critical
505 if (poll_fd[i].overlapped != overlapped) {
506 LeaveCriticalSection(&_poll_fd[i].mutex);
509 memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
510 LeaveCriticalSection(&_poll_fd[i].mutex);
514 return INVALID_WINFD;
518 * POSIX poll equivalent, using Windows OVERLAPPED
519 * Currently, this function only accepts one of POLLIN or POLLOUT per fd
520 * (but you can create multiple fds from the same handle for read and write)
522 int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout)
525 int _index, object_index, triggered;
526 HANDLE *handles_to_wait_on;
527 int *handle_to_index;
528 DWORD nb_handles_to_wait_on = 0;
534 handles_to_wait_on = (HANDLE*) calloc(nfds+1, sizeof(HANDLE)); // +1 for fd_update
535 handle_to_index = (int*) calloc(nfds, sizeof(int));
536 if ((handles_to_wait_on == NULL) || (handle_to_index == NULL)) {
542 for (i = 0; i < nfds; ++i) {
545 // Only one of POLLIN or POLLOUT can be selected with this version of poll (not both)
546 if ((fds[i].events & ~POLLIN) && (!(fds[i].events & POLLOUT))) {
547 fds[i].revents |= POLLERR;
549 usbi_warn(NULL, "unsupported set of events");
554 _index = _fd_to_index_and_lock(fds[i].fd);
555 poll_dbg("fd[%d]=%d: (overlapped=%p) got events %04X", i, poll_fd[_index].fd, poll_fd[_index].overlapped, fds[i].events);
557 if ( (_index < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
558 || (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL)) {
559 fds[i].revents |= POLLNVAL | POLLERR;
562 LeaveCriticalSection(&_poll_fd[_index].mutex);
564 usbi_warn(NULL, "invalid fd");
569 // IN or OUT must match our fd direction
570 if ((fds[i].events & POLLIN) && (poll_fd[_index].rw != RW_READ)) {
571 fds[i].revents |= POLLNVAL | POLLERR;
573 usbi_warn(NULL, "attempted POLLIN on fd without READ access");
574 LeaveCriticalSection(&_poll_fd[_index].mutex);
579 if ((fds[i].events & POLLOUT) && (poll_fd[_index].rw != RW_WRITE)) {
580 fds[i].revents |= POLLNVAL | POLLERR;
582 usbi_warn(NULL, "attempted POLLOUT on fd without WRITE access");
583 LeaveCriticalSection(&_poll_fd[_index].mutex);
588 // The following macro only works if overlapped I/O was reported pending
589 if ( (HasOverlappedIoCompleted(poll_fd[_index].overlapped))
590 || (HasOverlappedIoCompletedSync(poll_fd[_index].overlapped)) ) {
591 poll_dbg(" completed");
592 // checks above should ensure this works:
593 fds[i].revents = fds[i].events;
596 handles_to_wait_on[nb_handles_to_wait_on] = poll_fd[_index].overlapped->hEvent;
597 handle_to_index[nb_handles_to_wait_on] = i;
598 nb_handles_to_wait_on++;
600 LeaveCriticalSection(&_poll_fd[_index].mutex);
603 // If nothing was triggered, wait on all fds that require it
604 if ((timeout != 0) && (triggered == 0) && (nb_handles_to_wait_on != 0)) {
606 poll_dbg("starting infinite wait for %d handles...", (int)nb_handles_to_wait_on);
608 poll_dbg("starting %d ms wait for %d handles...", timeout, (int)nb_handles_to_wait_on);
610 ret = WaitForMultipleObjects(nb_handles_to_wait_on, handles_to_wait_on,
611 FALSE, (timeout<0)?INFINITE:(DWORD)timeout);
612 object_index = ret-WAIT_OBJECT_0;
613 if ((object_index >= 0) && ((DWORD)object_index < nb_handles_to_wait_on)) {
614 poll_dbg(" completed after wait");
615 i = handle_to_index[object_index];
616 _index = _fd_to_index_and_lock(fds[i].fd);
617 fds[i].revents = fds[i].events;
620 LeaveCriticalSection(&_poll_fd[_index].mutex);
622 } else if (ret == WAIT_TIMEOUT) {
623 poll_dbg(" timed out");
624 triggered = 0; // 0 = timeout
627 triggered = -1; // error
632 if (handles_to_wait_on != NULL) {
633 free(handles_to_wait_on);
635 if (handle_to_index != NULL) {
636 free(handle_to_index);
642 * close a fake pipe fd
644 int usbi_close(int fd)
651 _index = _fd_to_index_and_lock(fd);
656 free_overlapped(poll_fd[_index].overlapped);
657 poll_fd[_index] = INVALID_WINFD;
658 LeaveCriticalSection(&_poll_fd[_index].mutex);
664 * synchronous write for fake "pipe" signaling
666 ssize_t usbi_write(int fd, const void *buf, size_t count)
673 if (count != sizeof(unsigned char)) {
674 usbi_err(NULL, "this function should only used for signaling");
678 _index = _fd_to_index_and_lock(fd);
680 if ( (_index < 0) || (poll_fd[_index].overlapped == NULL) ) {
683 LeaveCriticalSection(&_poll_fd[_index].mutex);
688 poll_dbg("set pipe event (fd = %d, thread = %08X)", _index, GetCurrentThreadId());
689 SetEvent(poll_fd[_index].overlapped->hEvent);
690 poll_fd[_index].overlapped->Internal = STATUS_WAIT_0;
691 // If two threads write on the pipe at the same time, we need to
692 // process two separate reads => use the overlapped as a counter
693 poll_fd[_index].overlapped->InternalHigh++;
695 LeaveCriticalSection(&_poll_fd[_index].mutex);
696 return sizeof(unsigned char);
700 * synchronous read for fake "pipe" signaling
702 ssize_t usbi_read(int fd, void *buf, size_t count)
710 if (count != sizeof(unsigned char)) {
711 usbi_err(NULL, "this function should only used for signaling");
715 _index = _fd_to_index_and_lock(fd);
722 if (WaitForSingleObject(poll_fd[_index].overlapped->hEvent, INFINITE) != WAIT_OBJECT_0) {
723 usbi_warn(NULL, "waiting for event failed: %d", (int)GetLastError());
728 poll_dbg("clr pipe event (fd = %d, thread = %08X)", _index, GetCurrentThreadId());
729 poll_fd[_index].overlapped->InternalHigh--;
730 // Don't reset unless we don't have any more events to process
731 if (poll_fd[_index].overlapped->InternalHigh <= 0) {
732 ResetEvent(poll_fd[_index].overlapped->hEvent);
733 poll_fd[_index].overlapped->Internal = STATUS_PENDING;
736 r = sizeof(unsigned char);
739 LeaveCriticalSection(&_poll_fd[_index].mutex);