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 _O_RDONLY and once in _O_WRONLY 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
50 // Uncomment to debug the polling layer
51 //#define DEBUG_POLL_WINDOWS
52 #if defined(DEBUG_POLL_WINDOWS)
53 #define poll_dbg usbi_dbg
55 // MSVC++ < 2005 cannot use a variadic argument and non MSVC
56 // compilers produce warnings if parenthesis are ommitted.
57 #if defined(_MSC_VER) && _MSC_VER < 1400
64 #if defined(_PREFAST_)
65 #pragma warning(disable:28719)
68 #if defined(__CYGWIN__)
69 // cygwin produces a warning unless these prototypes are defined
70 extern int _open(char* name, int flags);
71 extern int _close(int fd);
72 extern int _snprintf(char *buffer, size_t count, const char *format, ...);
73 #define NUL_DEVICE "/dev/null"
75 #define NUL_DEVICE "NUL"
78 #define CHECK_INIT_POLLING do {if(!is_polling_set) init_polling();} while(0)
81 const struct winfd INVALID_WINFD = {-1, INVALID_HANDLE_VALUE, NULL, RW_NONE};
82 struct winfd poll_fd[MAX_FDS];
85 CRITICAL_SECTION mutex; // lock for fds
86 // Additional variables for XP CancelIoEx partial emulation
87 HANDLE original_handle;
92 BOOLEAN is_polling_set = FALSE;
94 static volatile LONG compat_spinlock = 0;
96 // CancelIoEx, available on Vista and later only, provides the ability to cancel
97 // a single transfer (OVERLAPPED) when used. As it may not be part of any of the
98 // platform headers, we hook into the Kernel32 system DLL directly to seek it.
99 static BOOL (__stdcall *pCancelIoEx)(HANDLE, LPOVERLAPPED) = NULL;
100 #define CancelIoEx_Available (pCancelIoEx != NULL)
101 static __inline BOOL cancel_io(int _index)
103 if ((_index < 0) || (_index >= MAX_FDS)) {
107 if ( (poll_fd[_index].fd < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
108 || (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL) ) {
111 if (CancelIoEx_Available) {
112 return (*pCancelIoEx)(poll_fd[_index].handle, poll_fd[_index].overlapped);
114 if (_poll_fd[_index].thread_id == GetCurrentThreadId()) {
115 return CancelIo(poll_fd[_index].handle);
117 usbi_warn(NULL, "Unable to cancel I/O that was started from another thread");
122 void init_polling(void)
126 while (InterlockedExchange((LONG *)&compat_spinlock, 1) == 1) {
129 if (!is_polling_set) {
130 pCancelIoEx = (BOOL (__stdcall *)(HANDLE,LPOVERLAPPED))
131 GetProcAddress(GetModuleHandleA("KERNEL32"), "CancelIoEx");
132 usbi_dbg("Will use CancelIo%s for I/O cancellation",
133 CancelIoEx_Available?"Ex":"");
134 for (i=0; i<MAX_FDS; i++) {
135 poll_fd[i] = INVALID_WINFD;
136 _poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
137 _poll_fd[i].thread_id = 0;
138 InitializeCriticalSection(&_poll_fd[i].mutex);
140 is_polling_set = TRUE;
142 InterlockedExchange((LONG *)&compat_spinlock, 0);
145 // Internal function to retrieve the table index (and lock the fd mutex)
146 int _fd_to_index_and_lock(int fd)
153 for (i=0; i<MAX_FDS; i++) {
154 if (poll_fd[i].fd == fd) {
155 EnterCriticalSection(&_poll_fd[i].mutex);
156 // fd might have changed before we got to critical
157 if (poll_fd[i].fd != fd) {
158 LeaveCriticalSection(&_poll_fd[i].mutex);
167 OVERLAPPED *create_overlapped(void)
169 OVERLAPPED *overlapped = (OVERLAPPED*) calloc(1, sizeof(OVERLAPPED));
170 if (overlapped == NULL) {
173 overlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
174 if(overlapped->hEvent == NULL) {
181 void free_overlapped(OVERLAPPED *overlapped)
183 if (overlapped == NULL)
186 if ( (overlapped->hEvent != 0)
187 && (overlapped->hEvent != INVALID_HANDLE_VALUE) ) {
188 CloseHandle(overlapped->hEvent);
193 void reset_overlapped(OVERLAPPED *overlapped)
196 if (overlapped == NULL)
199 event_handle = overlapped->hEvent;
200 if (event_handle != NULL) {
201 ResetEvent(event_handle);
203 memset(overlapped, 0, sizeof(OVERLAPPED));
204 overlapped->hEvent = event_handle;
207 void exit_polling(void)
211 while (InterlockedExchange((LONG *)&compat_spinlock, 1) == 1) {
214 if (is_polling_set) {
215 is_polling_set = FALSE;
217 for (i=0; i<MAX_FDS; i++) {
218 // Cancel any async I/O (handle can be invalid)
220 // If anything was pending on that I/O, it should be
221 // terminating, and we should be able to access the fd
222 // mutex lock before too long
223 EnterCriticalSection(&_poll_fd[i].mutex);
224 if ( (poll_fd[i].fd > 0) && (poll_fd[i].handle != INVALID_HANDLE_VALUE) && (poll_fd[i].handle != 0)
225 && (GetFileType(poll_fd[i].handle) == FILE_TYPE_UNKNOWN) ) {
226 _close(poll_fd[i].fd);
228 free_overlapped(poll_fd[i].overlapped);
229 if (!CancelIoEx_Available) {
230 // Close duplicate handle
231 if (_poll_fd[i].original_handle != INVALID_HANDLE_VALUE) {
232 CloseHandle(poll_fd[i].handle);
235 poll_fd[i] = INVALID_WINFD;
236 LeaveCriticalSection(&_poll_fd[i].mutex);
237 DeleteCriticalSection(&_poll_fd[i].mutex);
240 InterlockedExchange((LONG *)&compat_spinlock, 0);
244 * Create a fake pipe.
245 * As libusbx only uses pipes for signaling, all we need from a pipe is an
246 * event. To that extent, we create a single wfd and overlapped as a means
247 * to access that event.
249 int usbi_pipe(int filedes[2])
252 OVERLAPPED* overlapped;
256 overlapped = (OVERLAPPED*) calloc(1, sizeof(OVERLAPPED));
257 if (overlapped == NULL) {
260 // The overlapped must have status pending for signaling to work in poll
261 overlapped->Internal = STATUS_PENDING;
262 overlapped->InternalHigh = 0;
264 // Read end of the "pipe"
265 filedes[0] = _open(NUL_DEVICE, _O_WRONLY);
266 if (filedes[0] < 0) {
267 usbi_err(NULL, "could not create pipe: errno %d", errno);
270 // We can use the same handle for both ends
271 filedes[1] = filedes[0];
272 poll_dbg("pipe filedes = %d", filedes[0]);
274 // Note: manual reset must be true (second param) as the reset occurs in read
275 overlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
276 if(!overlapped->hEvent) {
280 for (i=0; i<MAX_FDS; i++) {
281 if (poll_fd[i].fd < 0) {
282 EnterCriticalSection(&_poll_fd[i].mutex);
283 // fd might have been allocated before we got to critical
284 if (poll_fd[i].fd >= 0) {
285 LeaveCriticalSection(&_poll_fd[i].mutex);
289 poll_fd[i].fd = filedes[0];
290 poll_fd[i].handle = DUMMY_HANDLE;
291 poll_fd[i].overlapped = overlapped;
292 // There's no polling on the write end, so we just use READ for our needs
293 poll_fd[i].rw = RW_READ;
294 _poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
295 LeaveCriticalSection(&_poll_fd[i].mutex);
300 CloseHandle(overlapped->hEvent);
309 * Create both an fd and an OVERLAPPED from an open Windows handle, so that
310 * it can be used with our polling function
311 * The handle MUST support overlapped transfers (usually requires CreateFile
312 * with FILE_FLAG_OVERLAPPED)
313 * Return a pollable file descriptor struct, or INVALID_WINFD on error
315 * Note that the fd returned by this function is a per-transfer fd, rather
316 * than a per-session fd and cannot be used for anything else but our
317 * custom functions (the fd itself points to the NUL: device)
318 * if you plan to do R/W on the same handle, you MUST create 2 fds: one for
319 * read and one for write. Using a single R/W fd is unsupported and will
320 * produce unexpected results
322 struct winfd usbi_create_fd(HANDLE handle, int access_mode)
325 struct winfd wfd = INVALID_WINFD;
326 OVERLAPPED* overlapped = NULL;
330 if ((handle == 0) || (handle == INVALID_HANDLE_VALUE)) {
331 return INVALID_WINFD;
334 if ((access_mode != _O_RDONLY) && (access_mode != _O_WRONLY)) {
335 usbi_warn(NULL, "only one of _O_RDONLY or _O_WRONLY are supported.\n"
336 "If you want to poll for R/W simultaneously, create multiple fds from the same handle.");
337 return INVALID_WINFD;
339 if (access_mode == _O_RDONLY) {
345 // Ensure that we get a non system conflicting unique fd, using
346 // the same fd attribution system as the pipe ends
347 fd = _open(NUL_DEVICE, _O_WRONLY);
349 return INVALID_WINFD;
352 overlapped = create_overlapped();
353 if(overlapped == NULL) {
355 return INVALID_WINFD;
358 for (i=0; i<MAX_FDS; i++) {
359 if (poll_fd[i].fd < 0) {
360 EnterCriticalSection(&_poll_fd[i].mutex);
361 // fd might have been removed before we got to critical
362 if (poll_fd[i].fd >= 0) {
363 LeaveCriticalSection(&_poll_fd[i].mutex);
367 // Attempt to emulate some of the CancelIoEx behaviour on platforms
368 // that don't have it
369 if (!CancelIoEx_Available) {
370 _poll_fd[i].thread_id = GetCurrentThreadId();
371 if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(),
372 &wfd.handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
373 usbi_dbg("could not duplicate handle for CancelIo - using original one");
375 // Make sure we won't close the original handle on fd deletion then
376 _poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
378 _poll_fd[i].original_handle = handle;
383 wfd.overlapped = overlapped;
384 memcpy(&poll_fd[i], &wfd, sizeof(struct winfd));
385 LeaveCriticalSection(&_poll_fd[i].mutex);
389 free_overlapped(overlapped);
391 return INVALID_WINFD;
394 void _free_index(int _index)
396 // Cancel any async IO (Don't care about the validity of our handles for this)
398 // close fake handle for devices
399 if ( (poll_fd[_index].handle != INVALID_HANDLE_VALUE) && (poll_fd[_index].handle != 0)
400 && (GetFileType(poll_fd[_index].handle) == FILE_TYPE_UNKNOWN) ) {
401 _close(poll_fd[_index].fd);
403 // close the duplicate handle (if we have an actual duplicate)
404 if (!CancelIoEx_Available) {
405 if (_poll_fd[_index].original_handle != INVALID_HANDLE_VALUE) {
406 CloseHandle(poll_fd[_index].handle);
408 _poll_fd[_index].original_handle = INVALID_HANDLE_VALUE;
409 _poll_fd[_index].thread_id = 0;
411 free_overlapped(poll_fd[_index].overlapped);
412 poll_fd[_index] = INVALID_WINFD;
416 * Release a pollable file descriptor.
418 * Note that the associated Windows handle is not closed by this call
420 void usbi_free_fd(int fd)
426 _index = _fd_to_index_and_lock(fd);
431 LeaveCriticalSection(&_poll_fd[_index].mutex);
435 * The functions below perform various conversions between fd, handle and OVERLAPPED
437 struct winfd fd_to_winfd(int fd)
445 return INVALID_WINFD;
447 for (i=0; i<MAX_FDS; i++) {
448 if (poll_fd[i].fd == fd) {
449 EnterCriticalSection(&_poll_fd[i].mutex);
450 // fd might have been deleted before we got to critical
451 if (poll_fd[i].fd != fd) {
452 LeaveCriticalSection(&_poll_fd[i].mutex);
455 memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
456 LeaveCriticalSection(&_poll_fd[i].mutex);
460 return INVALID_WINFD;
463 struct winfd handle_to_winfd(HANDLE handle)
470 if ((handle == 0) || (handle == INVALID_HANDLE_VALUE))
471 return INVALID_WINFD;
473 for (i=0; i<MAX_FDS; i++) {
474 if (poll_fd[i].handle == handle) {
475 EnterCriticalSection(&_poll_fd[i].mutex);
476 // fd might have been deleted before we got to critical
477 if (poll_fd[i].handle != handle) {
478 LeaveCriticalSection(&_poll_fd[i].mutex);
481 memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
482 LeaveCriticalSection(&_poll_fd[i].mutex);
486 return INVALID_WINFD;
489 struct winfd overlapped_to_winfd(OVERLAPPED* overlapped)
496 if (overlapped == NULL)
497 return INVALID_WINFD;
499 for (i=0; i<MAX_FDS; i++) {
500 if (poll_fd[i].overlapped == overlapped) {
501 EnterCriticalSection(&_poll_fd[i].mutex);
502 // fd might have been deleted before we got to critical
503 if (poll_fd[i].overlapped != overlapped) {
504 LeaveCriticalSection(&_poll_fd[i].mutex);
507 memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
508 LeaveCriticalSection(&_poll_fd[i].mutex);
512 return INVALID_WINFD;
516 * POSIX poll equivalent, using Windows OVERLAPPED
517 * Currently, this function only accepts one of POLLIN or POLLOUT per fd
518 * (but you can create multiple fds from the same handle for read and write)
520 int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout)
523 int _index, object_index, triggered;
524 HANDLE *handles_to_wait_on;
525 int *handle_to_index;
526 DWORD nb_handles_to_wait_on = 0;
532 handles_to_wait_on = (HANDLE*) calloc(nfds+1, sizeof(HANDLE)); // +1 for fd_update
533 handle_to_index = (int*) calloc(nfds, sizeof(int));
534 if ((handles_to_wait_on == NULL) || (handle_to_index == NULL)) {
540 for (i = 0; i < nfds; ++i) {
543 // Only one of POLLIN or POLLOUT can be selected with this version of poll (not both)
544 if ((fds[i].events & ~POLLIN) && (!(fds[i].events & POLLOUT))) {
545 fds[i].revents |= POLLERR;
547 usbi_warn(NULL, "unsupported set of events");
552 _index = _fd_to_index_and_lock(fds[i].fd);
553 poll_dbg("fd[%d]=%d: (overlapped=%p) got events %04X", i, poll_fd[_index].fd, poll_fd[_index].overlapped, fds[i].events);
555 if ( (_index < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
556 || (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL)) {
557 fds[i].revents |= POLLNVAL | POLLERR;
560 LeaveCriticalSection(&_poll_fd[_index].mutex);
562 usbi_warn(NULL, "invalid fd");
567 // IN or OUT must match our fd direction
568 if ((fds[i].events & POLLIN) && (poll_fd[_index].rw != RW_READ)) {
569 fds[i].revents |= POLLNVAL | POLLERR;
571 usbi_warn(NULL, "attempted POLLIN on fd without READ access");
572 LeaveCriticalSection(&_poll_fd[_index].mutex);
577 if ((fds[i].events & POLLOUT) && (poll_fd[_index].rw != RW_WRITE)) {
578 fds[i].revents |= POLLNVAL | POLLERR;
580 usbi_warn(NULL, "attempted POLLOUT on fd without WRITE access");
581 LeaveCriticalSection(&_poll_fd[_index].mutex);
586 // The following macro only works if overlapped I/O was reported pending
587 if ( (HasOverlappedIoCompleted(poll_fd[_index].overlapped))
588 || (HasOverlappedIoCompletedSync(poll_fd[_index].overlapped)) ) {
589 poll_dbg(" completed");
590 // checks above should ensure this works:
591 fds[i].revents = fds[i].events;
594 handles_to_wait_on[nb_handles_to_wait_on] = poll_fd[_index].overlapped->hEvent;
595 handle_to_index[nb_handles_to_wait_on] = i;
596 nb_handles_to_wait_on++;
598 LeaveCriticalSection(&_poll_fd[_index].mutex);
601 // If nothing was triggered, wait on all fds that require it
602 if ((timeout != 0) && (triggered == 0) && (nb_handles_to_wait_on != 0)) {
604 poll_dbg("starting infinite wait for %d handles...", (int)nb_handles_to_wait_on);
606 poll_dbg("starting %d ms wait for %d handles...", timeout, (int)nb_handles_to_wait_on);
608 ret = WaitForMultipleObjects(nb_handles_to_wait_on, handles_to_wait_on,
609 FALSE, (timeout<0)?INFINITE:(DWORD)timeout);
610 object_index = ret-WAIT_OBJECT_0;
611 if ((object_index >= 0) && ((DWORD)object_index < nb_handles_to_wait_on)) {
612 poll_dbg(" completed after wait");
613 i = handle_to_index[object_index];
614 _index = _fd_to_index_and_lock(fds[i].fd);
615 fds[i].revents = fds[i].events;
618 LeaveCriticalSection(&_poll_fd[_index].mutex);
620 } else if (ret == WAIT_TIMEOUT) {
621 poll_dbg(" timed out");
622 triggered = 0; // 0 = timeout
625 triggered = -1; // error
630 if (handles_to_wait_on != NULL) {
631 free(handles_to_wait_on);
633 if (handle_to_index != NULL) {
634 free(handle_to_index);
640 * close a fake pipe fd
642 int usbi_close(int fd)
649 _index = _fd_to_index_and_lock(fd);
654 if (poll_fd[_index].overlapped != NULL) {
655 // Must be a different event for each end of the pipe
656 CloseHandle(poll_fd[_index].overlapped->hEvent);
657 free(poll_fd[_index].overlapped);
659 r = _close(poll_fd[_index].fd);
663 poll_fd[_index] = INVALID_WINFD;
664 LeaveCriticalSection(&_poll_fd[_index].mutex);
670 * synchronous write for fake "pipe" signaling
672 ssize_t usbi_write(int fd, const void *buf, size_t count)
679 if (count != sizeof(unsigned char)) {
680 usbi_err(NULL, "this function should only used for signaling");
684 _index = _fd_to_index_and_lock(fd);
686 if ( (_index < 0) || (poll_fd[_index].overlapped == NULL) ) {
689 LeaveCriticalSection(&_poll_fd[_index].mutex);
694 poll_dbg("set pipe event (fd = %d, thread = %08X)", _index, GetCurrentThreadId());
695 SetEvent(poll_fd[_index].overlapped->hEvent);
696 poll_fd[_index].overlapped->Internal = STATUS_WAIT_0;
697 // If two threads write on the pipe at the same time, we need to
698 // process two separate reads => use the overlapped as a counter
699 poll_fd[_index].overlapped->InternalHigh++;
701 LeaveCriticalSection(&_poll_fd[_index].mutex);
702 return sizeof(unsigned char);
706 * synchronous read for fake "pipe" signaling
708 ssize_t usbi_read(int fd, void *buf, size_t count)
716 if (count != sizeof(unsigned char)) {
717 usbi_err(NULL, "this function should only used for signaling");
721 _index = _fd_to_index_and_lock(fd);
728 if (WaitForSingleObject(poll_fd[_index].overlapped->hEvent, INFINITE) != WAIT_OBJECT_0) {
729 usbi_warn(NULL, "waiting for event failed: %d", (int)GetLastError());
734 poll_dbg("clr pipe event (fd = %d, thread = %08X)", _index, GetCurrentThreadId());
735 poll_fd[_index].overlapped->InternalHigh--;
736 // Don't reset unless we don't have any more events to process
737 if (poll_fd[_index].overlapped->InternalHigh <= 0) {
738 ResetEvent(poll_fd[_index].overlapped->hEvent);
739 poll_fd[_index].overlapped->Internal = STATUS_PENDING;
742 r = sizeof(unsigned char);
745 LeaveCriticalSection(&_poll_fd[_index].mutex);