2 * poll_windows: poll compatibility wrapper for Windows
3 * Copyright © 2012-2013 RealVNC Ltd.
4 * Copyright © 2009-2010 Pete Batard <pete@akeo.ie>
5 * With contributions from Michael Plante, Orin Eman et al.
6 * Parts of poll implementation from libusb-win32, by Stephan Meyer et al.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 * poll() and pipe() Windows compatibility layer for libusbx 1.0
27 * The way this layer works is by using OVERLAPPED with async I/O transfers, as
28 * OVERLAPPED have an associated event which is flagged for I/O completion.
30 * For USB pollable async I/O, you would typically:
31 * - obtain a Windows HANDLE to a file or device that has been opened in
33 * - call usbi_create_fd with this handle to obtain a custom fd.
34 * Note that if you need simultaneous R/W access, you need to call create_fd
35 * twice, once in RW_READ and once in RW_WRITE mode to obtain 2 separate
37 * - leave the core functions call the poll routine and flag POLLIN/POLLOUT
39 * The pipe pollable synchronous I/O works using the overlapped event associated
40 * with a fake pipe. The read/write functions are only meant to be used in that
49 // Uncomment to debug the polling layer
50 //#define DEBUG_POLL_WINDOWS
51 #if defined(DEBUG_POLL_WINDOWS)
52 #define poll_dbg usbi_dbg
54 // MSVC++ < 2005 cannot use a variadic argument and non MSVC
55 // compilers produce warnings if parenthesis are ommitted.
56 #if defined(_MSC_VER) && (_MSC_VER < 1400)
63 #if defined(_PREFAST_)
64 #pragma warning(disable:28719)
67 #define CHECK_INIT_POLLING do {if(!is_polling_set) init_polling();} while(0)
70 const struct winfd INVALID_WINFD = {-1, INVALID_HANDLE_VALUE, NULL, NULL, NULL, RW_NONE};
71 struct winfd poll_fd[MAX_FDS];
74 CRITICAL_SECTION mutex; // lock for fds
75 // Additional variables for XP CancelIoEx partial emulation
76 HANDLE original_handle;
81 BOOLEAN is_polling_set = FALSE;
83 static volatile LONG compat_spinlock = 0;
85 #if !defined(_WIN32_WCE)
86 // CancelIoEx, available on Vista and later only, provides the ability to cancel
87 // a single transfer (OVERLAPPED) when used. As it may not be part of any of the
88 // platform headers, we hook into the Kernel32 system DLL directly to seek it.
89 static BOOL (__stdcall *pCancelIoEx)(HANDLE, LPOVERLAPPED) = NULL;
90 #define Use_Duplicate_Handles (pCancelIoEx == NULL)
92 static inline void setup_cancel_io(void)
94 pCancelIoEx = (BOOL (__stdcall *)(HANDLE,LPOVERLAPPED))
95 GetProcAddress(GetModuleHandleA("KERNEL32"), "CancelIoEx");
96 usbi_dbg("Will use CancelIo%s for I/O cancellation",
97 Use_Duplicate_Handles?"":"Ex");
100 static inline BOOL cancel_io(int _index)
102 if ((_index < 0) || (_index >= MAX_FDS)) {
106 if ( (poll_fd[_index].fd < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
107 || (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL) ) {
110 if (poll_fd[_index].itransfer && poll_fd[_index].cancel_fn) {
111 // Cancel outstanding transfer via the specific callback
112 (*poll_fd[_index].cancel_fn)(poll_fd[_index].itransfer);
115 if (pCancelIoEx != NULL) {
116 return (*pCancelIoEx)(poll_fd[_index].handle, poll_fd[_index].overlapped);
118 if (_poll_fd[_index].thread_id == GetCurrentThreadId()) {
119 return CancelIo(poll_fd[_index].handle);
121 usbi_warn(NULL, "Unable to cancel I/O that was started from another thread");
125 #define Use_Duplicate_Handles FALSE
127 static __inline void setup_cancel_io()
129 // No setup needed on WinCE
132 static __inline BOOL cancel_io(int _index)
134 if ((_index < 0) || (_index >= MAX_FDS)) {
137 if ( (poll_fd[_index].fd < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
138 || (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL) ) {
141 if (poll_fd[_index].itransfer && poll_fd[_index].cancel_fn) {
142 // Cancel outstanding transfer via the specific callback
143 (*poll_fd[_index].cancel_fn)(poll_fd[_index].itransfer);
150 void init_polling(void)
154 while (InterlockedExchange((LONG *)&compat_spinlock, 1) == 1) {
157 if (!is_polling_set) {
159 for (i=0; i<MAX_FDS; i++) {
160 poll_fd[i] = INVALID_WINFD;
161 _poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
162 _poll_fd[i].thread_id = 0;
163 InitializeCriticalSection(&_poll_fd[i].mutex);
165 is_polling_set = TRUE;
167 InterlockedExchange((LONG *)&compat_spinlock, 0);
170 // Internal function to retrieve the table index (and lock the fd mutex)
171 static int _fd_to_index_and_lock(int fd)
178 for (i=0; i<MAX_FDS; i++) {
179 if (poll_fd[i].fd == fd) {
180 EnterCriticalSection(&_poll_fd[i].mutex);
181 // fd might have changed before we got to critical
182 if (poll_fd[i].fd != fd) {
183 LeaveCriticalSection(&_poll_fd[i].mutex);
192 static OVERLAPPED *create_overlapped(void)
194 OVERLAPPED *overlapped = (OVERLAPPED*) calloc(1, sizeof(OVERLAPPED));
195 if (overlapped == NULL) {
198 overlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
199 if(overlapped->hEvent == NULL) {
206 static void free_overlapped(OVERLAPPED *overlapped)
208 if (overlapped == NULL)
211 if ( (overlapped->hEvent != 0)
212 && (overlapped->hEvent != INVALID_HANDLE_VALUE) ) {
213 CloseHandle(overlapped->hEvent);
218 void exit_polling(void)
222 while (InterlockedExchange((LONG *)&compat_spinlock, 1) == 1) {
225 if (is_polling_set) {
226 is_polling_set = FALSE;
228 for (i=0; i<MAX_FDS; i++) {
229 // Cancel any async I/O (handle can be invalid)
231 // If anything was pending on that I/O, it should be
232 // terminating, and we should be able to access the fd
233 // mutex lock before too long
234 EnterCriticalSection(&_poll_fd[i].mutex);
235 free_overlapped(poll_fd[i].overlapped);
236 if (Use_Duplicate_Handles) {
237 // Close duplicate handle
238 if (_poll_fd[i].original_handle != INVALID_HANDLE_VALUE) {
239 CloseHandle(poll_fd[i].handle);
242 poll_fd[i] = INVALID_WINFD;
243 LeaveCriticalSection(&_poll_fd[i].mutex);
244 DeleteCriticalSection(&_poll_fd[i].mutex);
247 InterlockedExchange((LONG *)&compat_spinlock, 0);
251 * Create a fake pipe.
252 * As libusbx only uses pipes for signaling, all we need from a pipe is an
253 * event. To that extent, we create a single wfd and overlapped as a means
254 * to access that event.
256 int usbi_pipe(int filedes[2])
259 OVERLAPPED* overlapped;
263 overlapped = create_overlapped();
265 if (overlapped == NULL) {
268 // The overlapped must have status pending for signaling to work in poll
269 overlapped->Internal = STATUS_PENDING;
270 overlapped->InternalHigh = 0;
272 for (i=0; i<MAX_FDS; i++) {
273 if (poll_fd[i].fd < 0) {
274 EnterCriticalSection(&_poll_fd[i].mutex);
275 // fd might have been allocated before we got to critical
276 if (poll_fd[i].fd >= 0) {
277 LeaveCriticalSection(&_poll_fd[i].mutex);
281 // Use index as the unique fd number
283 // Read end of the "pipe"
284 filedes[0] = poll_fd[i].fd;
285 // We can use the same handle for both ends
286 filedes[1] = filedes[0];
288 poll_fd[i].handle = DUMMY_HANDLE;
289 poll_fd[i].overlapped = overlapped;
290 // There's no polling on the write end, so we just use READ for our needs
291 poll_fd[i].rw = RW_READ;
292 _poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
293 LeaveCriticalSection(&_poll_fd[i].mutex);
297 free_overlapped(overlapped);
302 * Create both an fd and an OVERLAPPED from an open Windows handle, so that
303 * it can be used with our polling function
304 * The handle MUST support overlapped transfers (usually requires CreateFile
305 * with FILE_FLAG_OVERLAPPED)
306 * Return a pollable file descriptor struct, or INVALID_WINFD on error
308 * Note that the fd returned by this function is a per-transfer fd, rather
309 * than a per-session fd and cannot be used for anything else but our
310 * custom functions (the fd itself points to the NUL: device)
311 * if you plan to do R/W on the same handle, you MUST create 2 fds: one for
312 * read and one for write. Using a single R/W fd is unsupported and will
313 * produce unexpected results
315 struct winfd usbi_create_fd(HANDLE handle, int access_mode, struct usbi_transfer *itransfer, cancel_transfer *cancel_fn)
318 struct winfd wfd = INVALID_WINFD;
319 OVERLAPPED* overlapped = NULL;
323 if ((handle == 0) || (handle == INVALID_HANDLE_VALUE)) {
324 return INVALID_WINFD;
327 wfd.itransfer = itransfer;
328 wfd.cancel_fn = cancel_fn;
330 if ((access_mode != RW_READ) && (access_mode != RW_WRITE)) {
331 usbi_warn(NULL, "only one of RW_READ or RW_WRITE are supported.\n"
332 "If you want to poll for R/W simultaneously, create multiple fds from the same handle.");
333 return INVALID_WINFD;
335 if (access_mode == RW_READ) {
341 overlapped = create_overlapped();
342 if(overlapped == NULL) {
343 return INVALID_WINFD;
346 for (i=0; i<MAX_FDS; i++) {
347 if (poll_fd[i].fd < 0) {
348 EnterCriticalSection(&_poll_fd[i].mutex);
349 // fd might have been removed before we got to critical
350 if (poll_fd[i].fd >= 0) {
351 LeaveCriticalSection(&_poll_fd[i].mutex);
354 // Use index as the unique fd number
356 // Attempt to emulate some of the CancelIoEx behaviour on platforms
357 // that don't have it
358 if (Use_Duplicate_Handles) {
359 _poll_fd[i].thread_id = GetCurrentThreadId();
360 if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(),
361 &wfd.handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
362 usbi_dbg("could not duplicate handle for CancelIo - using original one");
364 // Make sure we won't close the original handle on fd deletion then
365 _poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
367 _poll_fd[i].original_handle = handle;
372 wfd.overlapped = overlapped;
373 memcpy(&poll_fd[i], &wfd, sizeof(struct winfd));
374 LeaveCriticalSection(&_poll_fd[i].mutex);
378 free_overlapped(overlapped);
379 return INVALID_WINFD;
382 static void _free_index(int _index)
384 // Cancel any async IO (Don't care about the validity of our handles for this)
386 // close the duplicate handle (if we have an actual duplicate)
387 if (Use_Duplicate_Handles) {
388 if (_poll_fd[_index].original_handle != INVALID_HANDLE_VALUE) {
389 CloseHandle(poll_fd[_index].handle);
391 _poll_fd[_index].original_handle = INVALID_HANDLE_VALUE;
392 _poll_fd[_index].thread_id = 0;
394 free_overlapped(poll_fd[_index].overlapped);
395 poll_fd[_index] = INVALID_WINFD;
399 * Release a pollable file descriptor.
401 * Note that the associated Windows handle is not closed by this call
403 void usbi_free_fd(int fd)
409 _index = _fd_to_index_and_lock(fd);
414 LeaveCriticalSection(&_poll_fd[_index].mutex);
418 * The functions below perform various conversions between fd, handle and OVERLAPPED
420 struct winfd fd_to_winfd(int fd)
428 return INVALID_WINFD;
430 for (i=0; i<MAX_FDS; i++) {
431 if (poll_fd[i].fd == fd) {
432 EnterCriticalSection(&_poll_fd[i].mutex);
433 // fd might have been deleted before we got to critical
434 if (poll_fd[i].fd != fd) {
435 LeaveCriticalSection(&_poll_fd[i].mutex);
438 memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
439 LeaveCriticalSection(&_poll_fd[i].mutex);
443 return INVALID_WINFD;
446 struct winfd handle_to_winfd(HANDLE handle)
453 if ((handle == 0) || (handle == INVALID_HANDLE_VALUE))
454 return INVALID_WINFD;
456 for (i=0; i<MAX_FDS; i++) {
457 if (poll_fd[i].handle == handle) {
458 EnterCriticalSection(&_poll_fd[i].mutex);
459 // fd might have been deleted before we got to critical
460 if (poll_fd[i].handle != handle) {
461 LeaveCriticalSection(&_poll_fd[i].mutex);
464 memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
465 LeaveCriticalSection(&_poll_fd[i].mutex);
469 return INVALID_WINFD;
472 struct winfd overlapped_to_winfd(OVERLAPPED* overlapped)
479 if (overlapped == NULL)
480 return INVALID_WINFD;
482 for (i=0; i<MAX_FDS; i++) {
483 if (poll_fd[i].overlapped == overlapped) {
484 EnterCriticalSection(&_poll_fd[i].mutex);
485 // fd might have been deleted before we got to critical
486 if (poll_fd[i].overlapped != overlapped) {
487 LeaveCriticalSection(&_poll_fd[i].mutex);
490 memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
491 LeaveCriticalSection(&_poll_fd[i].mutex);
495 return INVALID_WINFD;
499 * POSIX poll equivalent, using Windows OVERLAPPED
500 * Currently, this function only accepts one of POLLIN or POLLOUT per fd
501 * (but you can create multiple fds from the same handle for read and write)
503 int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout)
506 int _index, object_index, triggered;
507 HANDLE *handles_to_wait_on;
508 int *handle_to_index;
509 DWORD nb_handles_to_wait_on = 0;
515 handles_to_wait_on = (HANDLE*) calloc(nfds+1, sizeof(HANDLE)); // +1 for fd_update
516 handle_to_index = (int*) calloc(nfds, sizeof(int));
517 if ((handles_to_wait_on == NULL) || (handle_to_index == NULL)) {
523 for (i = 0; i < nfds; ++i) {
526 // Only one of POLLIN or POLLOUT can be selected with this version of poll (not both)
527 if ((fds[i].events & ~POLLIN) && (!(fds[i].events & POLLOUT))) {
528 fds[i].revents |= POLLERR;
530 usbi_warn(NULL, "unsupported set of events");
535 _index = _fd_to_index_and_lock(fds[i].fd);
536 poll_dbg("fd[%d]=%d: (overlapped=%p) got events %04X", i, poll_fd[_index].fd, poll_fd[_index].overlapped, fds[i].events);
538 if ( (_index < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
539 || (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL)) {
540 fds[i].revents |= POLLNVAL | POLLERR;
543 LeaveCriticalSection(&_poll_fd[_index].mutex);
545 usbi_warn(NULL, "invalid fd");
550 // IN or OUT must match our fd direction
551 if ((fds[i].events & POLLIN) && (poll_fd[_index].rw != RW_READ)) {
552 fds[i].revents |= POLLNVAL | POLLERR;
554 usbi_warn(NULL, "attempted POLLIN on fd without READ access");
555 LeaveCriticalSection(&_poll_fd[_index].mutex);
560 if ((fds[i].events & POLLOUT) && (poll_fd[_index].rw != RW_WRITE)) {
561 fds[i].revents |= POLLNVAL | POLLERR;
563 usbi_warn(NULL, "attempted POLLOUT on fd without WRITE access");
564 LeaveCriticalSection(&_poll_fd[_index].mutex);
569 // The following macro only works if overlapped I/O was reported pending
570 if ( (HasOverlappedIoCompleted(poll_fd[_index].overlapped))
571 || (HasOverlappedIoCompletedSync(poll_fd[_index].overlapped)) ) {
572 poll_dbg(" completed");
573 // checks above should ensure this works:
574 fds[i].revents = fds[i].events;
577 handles_to_wait_on[nb_handles_to_wait_on] = poll_fd[_index].overlapped->hEvent;
578 handle_to_index[nb_handles_to_wait_on] = i;
579 nb_handles_to_wait_on++;
581 LeaveCriticalSection(&_poll_fd[_index].mutex);
584 // If nothing was triggered, wait on all fds that require it
585 if ((timeout != 0) && (triggered == 0) && (nb_handles_to_wait_on != 0)) {
587 poll_dbg("starting infinite wait for %d handles...", (int)nb_handles_to_wait_on);
589 poll_dbg("starting %d ms wait for %d handles...", timeout, (int)nb_handles_to_wait_on);
591 ret = WaitForMultipleObjects(nb_handles_to_wait_on, handles_to_wait_on,
592 FALSE, (timeout<0)?INFINITE:(DWORD)timeout);
593 object_index = ret-WAIT_OBJECT_0;
594 if ((object_index >= 0) && ((DWORD)object_index < nb_handles_to_wait_on)) {
595 poll_dbg(" completed after wait");
596 i = handle_to_index[object_index];
597 _index = _fd_to_index_and_lock(fds[i].fd);
598 fds[i].revents = fds[i].events;
601 LeaveCriticalSection(&_poll_fd[_index].mutex);
603 } else if (ret == WAIT_TIMEOUT) {
604 poll_dbg(" timed out");
605 triggered = 0; // 0 = timeout
608 triggered = -1; // error
613 if (handles_to_wait_on != NULL) {
614 free(handles_to_wait_on);
616 if (handle_to_index != NULL) {
617 free(handle_to_index);
623 * close a fake pipe fd
625 int usbi_close(int fd)
632 _index = _fd_to_index_and_lock(fd);
637 free_overlapped(poll_fd[_index].overlapped);
638 poll_fd[_index] = INVALID_WINFD;
639 LeaveCriticalSection(&_poll_fd[_index].mutex);
645 * synchronous write for fake "pipe" signaling
647 ssize_t usbi_write(int fd, const void *buf, size_t count)
654 if (count != sizeof(unsigned char)) {
655 usbi_err(NULL, "this function should only used for signaling");
659 _index = _fd_to_index_and_lock(fd);
661 if ( (_index < 0) || (poll_fd[_index].overlapped == NULL) ) {
664 LeaveCriticalSection(&_poll_fd[_index].mutex);
669 poll_dbg("set pipe event (fd = %d, thread = %08X)", _index, GetCurrentThreadId());
670 SetEvent(poll_fd[_index].overlapped->hEvent);
671 poll_fd[_index].overlapped->Internal = STATUS_WAIT_0;
672 // If two threads write on the pipe at the same time, we need to
673 // process two separate reads => use the overlapped as a counter
674 poll_fd[_index].overlapped->InternalHigh++;
676 LeaveCriticalSection(&_poll_fd[_index].mutex);
677 return sizeof(unsigned char);
681 * synchronous read for fake "pipe" signaling
683 ssize_t usbi_read(int fd, void *buf, size_t count)
691 if (count != sizeof(unsigned char)) {
692 usbi_err(NULL, "this function should only used for signaling");
696 _index = _fd_to_index_and_lock(fd);
703 if (WaitForSingleObject(poll_fd[_index].overlapped->hEvent, INFINITE) != WAIT_OBJECT_0) {
704 usbi_warn(NULL, "waiting for event failed: %d", (int)GetLastError());
709 poll_dbg("clr pipe event (fd = %d, thread = %08X)", _index, GetCurrentThreadId());
710 poll_fd[_index].overlapped->InternalHigh--;
711 // Don't reset unless we don't have any more events to process
712 if (poll_fd[_index].overlapped->InternalHigh <= 0) {
713 ResetEvent(poll_fd[_index].overlapped->hEvent);
714 poll_fd[_index].overlapped->Internal = STATUS_PENDING;
717 r = sizeof(unsigned char);
720 LeaveCriticalSection(&_poll_fd[_index].mutex);