Windows: Rename various variables named "index" to avoid shadow warnings
[platform/upstream/libusb.git] / libusb / os / poll_windows.c
1 /*
2  * poll_windows: poll compatibility wrapper for Windows
3  * Copyright (C) 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.
6  *
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.
11  *
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.
16  *
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
20  *
21  */
22
23 /*
24  * poll() and pipe() Windows compatibility layer for libusb 1.0
25  *
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.
28  *
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
31  *   OVERLAPPED mode
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
35  *   pollable fds
36  * - leave the core functions call the poll routine and flag POLLIN/POLLOUT
37  *
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
40  * context.
41  */
42 #include <errno.h>
43 #include <fcntl.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <io.h>
47
48 #include <libusbi.h>
49
50 // Uncomment to debug the polling layer
51 //#define DEBUG_POLL_WINDOWS
52 #if defined(DEBUG_POLL_WINDOWS)
53 #define poll_dbg usbi_dbg
54 #else
55 // MSVC6 cannot use a variadic argument and non MSVC
56 // compilers produce warnings if parenthesis are ommitted.
57 #if defined(_MSC_VER)
58 #define poll_dbg
59 #else
60 #define poll_dbg(...)
61 #endif
62 #endif
63
64 #if defined(_PREFAST_)
65 #pragma warning(disable:28719)
66 #endif
67
68 #if defined(__CYGWIN__)
69 // cygwin produces a warning unless these prototypes are defined
70 extern int _close(int fd);
71 extern int _snprintf(char *buffer, size_t count, const char *format, ...);
72 extern int cygwin_attach_handle_to_fd(char *name, int fd, HANDLE handle, int bin, int access_mode);
73 // _open_osfhandle() is not available on cygwin, but we can emulate
74 // it for our needs with cygwin_attach_handle_to_fd()
75 static inline int _open_osfhandle(intptr_t osfhandle, int flags)
76 {
77         int access_mode;
78         switch (flags) {
79         case _O_RDONLY:
80                 access_mode = GENERIC_READ;
81                 break;
82         case _O_WRONLY:
83                 access_mode = GENERIC_WRITE;
84                 break;
85         case _O_RDWR:
86                 access_mode = GENERIC_READ|GENERIC_WRITE;
87                 break;
88         default:
89                 usbi_err(NULL, "unsupported access mode");
90                 return -1;
91         }
92         return cygwin_attach_handle_to_fd("/dev/null", -1, (HANDLE)osfhandle, -1, access_mode);
93 }
94 #endif
95
96 #define CHECK_INIT_POLLING do {if(!is_polling_set) init_polling();} while(0)
97
98 // public fd data
99 const struct winfd INVALID_WINFD = {-1, INVALID_HANDLE_VALUE, NULL, RW_NONE};
100 struct winfd poll_fd[MAX_FDS];
101 // internal fd data
102 struct {
103         CRITICAL_SECTION mutex; // lock for fds
104         // Additional variables for XP CancelIoEx partial emulation
105         HANDLE original_handle;
106         DWORD thread_id;
107 } _poll_fd[MAX_FDS];
108
109 // globals
110 BOOLEAN is_polling_set = FALSE;
111 #if defined(DYNAMIC_FDS)
112 HANDLE fd_update = INVALID_HANDLE_VALUE;        // event to notify poll of fd update
113 HANDLE new_fd[MAX_FDS];         // overlapped event handles for fds created since last poll
114 unsigned nb_new_fds = 0;        // nb new fds created since last poll
115 usbi_mutex_t new_fd_mutex;      // mutex required for the above
116 #endif
117 LONG pipe_number = 0;
118 static volatile LONG compat_spinlock = 0;
119
120 // CancelIoEx, available on Vista and later only, provides the ability to cancel
121 // a single transfer (OVERLAPPED) when used. As it may not be part of any of the
122 // platform headers, we hook into the Kernel32 system DLL directly to seek it.
123 static BOOL (__stdcall *pCancelIoEx)(HANDLE, LPOVERLAPPED) = NULL;
124 #define CancelIoEx_Available (pCancelIoEx != NULL)
125 __inline BOOL cancel_io(int _index)
126 {
127         if ((_index < 0) || (_index >= MAX_FDS)) {
128                 return FALSE;
129         }
130
131         if ( (poll_fd[_index].fd < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
132           || (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL) ) {
133                 return TRUE;
134         }
135         if (CancelIoEx_Available) {
136                 return (*pCancelIoEx)(poll_fd[_index].handle, poll_fd[_index].overlapped);
137         }
138         if (_poll_fd[_index].thread_id == GetCurrentThreadId()) {
139                 return CancelIo(poll_fd[_index].handle);
140         }
141         usbi_warn(NULL, "Unable to cancel I/O that was started from another thread");
142         return FALSE;
143 }
144
145 // Init
146 void init_polling(void)
147 {
148         int i;
149
150         while (InterlockedExchange((LONG *)&compat_spinlock, 1) == 1) {
151                 SleepEx(0, TRUE);
152         }
153         if (!is_polling_set) {
154                 pCancelIoEx = (BOOL (__stdcall *)(HANDLE,LPOVERLAPPED))
155                         GetProcAddress(GetModuleHandle("KERNEL32"), "CancelIoEx");
156                 usbi_dbg("Will use CancelIo%s for I/O cancellation",
157                         CancelIoEx_Available?"Ex":"");
158                 for (i=0; i<MAX_FDS; i++) {
159                         poll_fd[i] = INVALID_WINFD;
160                         _poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
161                         _poll_fd[i].thread_id = 0;
162                         InitializeCriticalSection(&_poll_fd[i].mutex);
163                 }
164 #if defined(DYNAMIC_FDS)
165                 // We need to create an update event so that poll is warned when there
166                 // are new/deleted fds during a timeout wait operation
167                 fd_update = CreateEvent(NULL, TRUE, FALSE, NULL);
168                 if (fd_update == NULL) {
169                         usbi_err(NULL, "unable to create update event");
170                 }
171                 usbi_mutex_init(&new_fd_mutex, NULL);
172                 nb_new_fds = 0;
173 #endif
174                 is_polling_set = TRUE;
175         }
176         compat_spinlock = 0;
177 }
178
179 // Internal function to retrieve the table index (and lock the fd mutex)
180 int _fd_to_index_and_lock(int fd)
181 {
182         int i;
183
184         if (fd <= 0)
185                 return -1;
186
187         for (i=0; i<MAX_FDS; i++) {
188                 if (poll_fd[i].fd == fd) {
189                         EnterCriticalSection(&_poll_fd[i].mutex);
190                         // fd might have changed before we got to critical
191                         if (poll_fd[i].fd != fd) {
192                                 LeaveCriticalSection(&_poll_fd[i].mutex);
193                                 continue;
194                         }
195                         return i;
196                 }
197         }
198         return -1;
199 }
200
201 OVERLAPPED *create_overlapped(void)
202 {
203         OVERLAPPED *overlapped = calloc(1, sizeof(OVERLAPPED));
204         if (overlapped == NULL) {
205                 return NULL;
206         }
207         overlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
208         if(overlapped->hEvent == NULL) {
209                 free (overlapped);
210                 return NULL;
211         }
212         return overlapped;
213 }
214
215 void free_overlapped(OVERLAPPED *overlapped)
216 {
217         if (overlapped == NULL)
218                 return;
219
220         if ( (overlapped->hEvent != 0)
221           && (overlapped->hEvent != INVALID_HANDLE_VALUE) ) {
222                 CloseHandle(overlapped->hEvent);
223         }
224         free(overlapped);
225 }
226
227 void reset_overlapped(OVERLAPPED *overlapped)
228 {
229         HANDLE event_handle;
230         if (overlapped == NULL)
231                 return;
232
233         event_handle = overlapped->hEvent;
234         if (event_handle != NULL) {
235                 ResetEvent(event_handle);
236         }
237         memset(overlapped, 0, sizeof(OVERLAPPED));
238         overlapped->hEvent = event_handle;
239 }
240
241 void exit_polling(void)
242 {
243         int i;
244
245         while (InterlockedExchange((LONG *)&compat_spinlock, 1) == 1) {
246                 SleepEx(0, TRUE);
247         }
248         if (is_polling_set) {
249                 is_polling_set = FALSE;
250
251                 for (i=0; i<MAX_FDS; i++) {
252                         // Cancel any async I/O (handle can be invalid)
253                         cancel_io(i);
254                         // If anything was pending on that I/O, it should be
255                         // terminating, and we should be able to access the fd
256                         // mutex lock before too long
257                         EnterCriticalSection(&_poll_fd[i].mutex);
258                         if ( (poll_fd[i].fd > 0) && (poll_fd[i].handle != INVALID_HANDLE_VALUE) && (poll_fd[i].handle != 0)
259                           && (GetFileType(poll_fd[i].handle) == FILE_TYPE_UNKNOWN) ) {
260                                 _close(poll_fd[i].fd);
261                         }
262                         free_overlapped(poll_fd[i].overlapped);
263                         if (!CancelIoEx_Available) {
264                                 // Close duplicate handle
265                                 if (_poll_fd[i].original_handle != INVALID_HANDLE_VALUE) {
266                                         CloseHandle(poll_fd[i].handle);
267                                 }
268                         }
269                         poll_fd[i] = INVALID_WINFD;
270 #if defined(DYNAMIC_FDS)
271                         usbi_mutex_destroy(&new_fd_mutex);
272                         CloseHandle(fd_update);
273                         fd_update = INVALID_HANDLE_VALUE;
274 #endif
275                         LeaveCriticalSection(&_poll_fd[i].mutex);
276                         DeleteCriticalSection(&_poll_fd[i].mutex);
277                 }
278         }
279         compat_spinlock = 0;
280 }
281
282 /*
283  * Create a fake pipe.
284  * As libusb only uses pipes for signaling, all we need from a pipe is an
285  * event. To that extent, we create a single wfd and overlapped as a means
286  * to access that event.
287  */
288 int usbi_pipe(int filedes[2])
289 {
290         int i;
291         HANDLE handle;
292         OVERLAPPED* overlapped;
293
294         CHECK_INIT_POLLING;
295
296         overlapped = calloc(1, sizeof(OVERLAPPED));
297         if (overlapped == NULL) {
298                 return -1;
299         }
300         // The overlapped must have status pending for signaling to work in poll
301         overlapped->Internal = STATUS_PENDING;
302         overlapped->InternalHigh = 0;
303
304         // Read end of the "pipe"
305         handle = CreateFileA("NUL", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
306         if (handle == INVALID_HANDLE_VALUE) {
307                 usbi_err(NULL, "could not create pipe: errcode %d", (int)GetLastError());
308                 goto out1;
309         }
310         filedes[0] = _open_osfhandle((intptr_t)handle, _O_RDONLY);
311         // We can use the same handle for both ends
312         filedes[1] = filedes[0];
313         poll_dbg("pipe filedes = %d", filedes[0]);
314
315         // Note: manual reset must be true (second param) as the reset occurs in read
316         overlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
317         if(!overlapped->hEvent) {
318                 goto out2;
319         }
320
321         for (i=0; i<MAX_FDS; i++) {
322                 if (poll_fd[i].fd < 0) {
323                         EnterCriticalSection(&_poll_fd[i].mutex);
324                         // fd might have been allocated before we got to critical
325                         if (poll_fd[i].fd >= 0) {
326                                 LeaveCriticalSection(&_poll_fd[i].mutex);
327                                 continue;
328                         }
329
330                         poll_fd[i].fd = filedes[0];
331                         poll_fd[i].handle = handle;
332                         poll_fd[i].overlapped = overlapped;
333                         // There's no polling on the write end, so we just use READ for our needs
334                         poll_fd[i].rw = RW_READ;
335                         _poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
336                         LeaveCriticalSection(&_poll_fd[i].mutex);
337                         return 0;
338                 }
339         }
340
341         CloseHandle(overlapped->hEvent);
342 out2:
343         CloseHandle(handle);
344 out1:
345         free(overlapped);
346         return -1;
347 }
348
349 /*
350  * Create both an fd and an OVERLAPPED from an open Windows handle, so that
351  * it can be used with our polling function
352  * The handle MUST support overlapped transfers (usually requires CreateFile
353  * with FILE_FLAG_OVERLAPPED)
354  * Return a pollable file descriptor struct, or INVALID_WINFD on error
355  *
356  * Note that the fd returned by this function is a per-transfer fd, rather
357  * than a per-session fd and cannot be used for anything else but our
358  * custom functions (the fd itself points to the NUL: device)
359  * if you plan to do R/W on the same handle, you MUST create 2 fds: one for
360  * read and one for write. Using a single R/W fd is unsupported and will
361  * produce unexpected results
362  */
363 struct winfd usbi_create_fd(HANDLE handle, int access_mode)
364 {
365         int i, fd;
366         struct winfd wfd = INVALID_WINFD;
367         OVERLAPPED* overlapped = NULL;
368
369         CHECK_INIT_POLLING;
370
371         if ((handle == 0) || (handle == INVALID_HANDLE_VALUE)) {
372                 return INVALID_WINFD;
373         }
374
375         if ((access_mode != _O_RDONLY) && (access_mode != _O_WRONLY)) {
376                 usbi_warn(NULL, "only one of _O_RDONLY or _O_WRONLY are supported.\n"
377                         "If you want to poll for R/W simultaneously, create multiple fds from the same handle.");
378                 return INVALID_WINFD;
379         }
380         if (access_mode == _O_RDONLY) {
381                 wfd.rw = RW_READ;
382         } else {
383                 wfd.rw = RW_WRITE;
384         }
385
386         // Ensure that we get a non system conflicting unique fd
387         fd = _open_osfhandle((intptr_t)CreateFileA("NUL", 0, 0,
388                 NULL, OPEN_EXISTING, 0, NULL), _O_RDWR);
389         if (fd < 0) {
390                 return INVALID_WINFD;
391         }
392
393         overlapped = create_overlapped();
394         if(overlapped == NULL) {
395                 _close(fd);
396                 return INVALID_WINFD;
397         }
398
399         for (i=0; i<MAX_FDS; i++) {
400                 if (poll_fd[i].fd < 0) {
401                         EnterCriticalSection(&_poll_fd[i].mutex);
402                         // fd might have been removed before we got to critical
403                         if (poll_fd[i].fd >= 0) {
404                                 LeaveCriticalSection(&_poll_fd[i].mutex);
405                                 continue;
406                         }
407                         wfd.fd = fd;
408                         // Attempt to emulate some of the CancelIoEx behaviour on platforms
409                         // that don't have it
410                         if (!CancelIoEx_Available) {
411                                 _poll_fd[i].thread_id = GetCurrentThreadId();
412                                 if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(),
413                                         &wfd.handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
414                                         usbi_dbg("could not duplicate handle for CancelIo - using original one");
415                                         wfd.handle = handle;
416                                         // Make sure we won't close the original handle on fd deletion then
417                                         _poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
418                                 } else {
419                                         _poll_fd[i].original_handle = handle;
420                                 }
421                         } else {
422                                 wfd.handle = handle;
423                         }
424                         wfd.overlapped = overlapped;
425                         memcpy(&poll_fd[i], &wfd, sizeof(struct winfd));
426                         LeaveCriticalSection(&_poll_fd[i].mutex);
427 #if defined(DYNAMIC_FDS)
428                         usbi_mutex_lock(&new_fd_mutex);
429                         new_fd[nb_new_fds++] = overlapped->hEvent;
430                         usbi_mutex_unlock(&new_fd_mutex);
431                         // Notify poll that fds have been updated
432                         SetEvent(fd_update);
433 #endif
434                         return wfd;
435                 }
436         }
437         free_overlapped(overlapped);
438         _close(fd);
439         return INVALID_WINFD;
440 }
441
442 void _free_index(int _index)
443 {
444         // Cancel any async IO (Don't care about the validity of our handles for this)
445         cancel_io(_index);
446         // close fake handle for devices
447         if ( (poll_fd[_index].handle != INVALID_HANDLE_VALUE) && (poll_fd[_index].handle != 0)
448           && (GetFileType(poll_fd[_index].handle) == FILE_TYPE_UNKNOWN) ) {
449                 _close(poll_fd[_index].fd);
450         }
451         // close the duplicate handle (if we have an actual duplicate)
452         if (!CancelIoEx_Available) {
453                 if (_poll_fd[_index].original_handle != INVALID_HANDLE_VALUE) {
454                         CloseHandle(poll_fd[_index].handle);
455                 }
456                 _poll_fd[_index].original_handle = INVALID_HANDLE_VALUE;
457                 _poll_fd[_index].thread_id = 0;
458         }
459         free_overlapped(poll_fd[_index].overlapped);
460         poll_fd[_index] = INVALID_WINFD;
461 }
462
463 /*
464  * Release a pollable file descriptor.
465  *
466  * Note that the associated Windows handle is not closed by this call
467  */
468 void usbi_free_fd(int fd)
469 {
470         int _index;
471
472         CHECK_INIT_POLLING;
473
474         _index = _fd_to_index_and_lock(fd);
475         if (_index < 0) {
476                 return;
477         }
478         _free_index(_index);
479         LeaveCriticalSection(&_poll_fd[_index].mutex);
480 }
481
482 /*
483  * The functions below perform various conversions between fd, handle and OVERLAPPED
484  */
485 struct winfd fd_to_winfd(int fd)
486 {
487         int i;
488         struct winfd wfd;
489
490         CHECK_INIT_POLLING;
491
492         if (fd <= 0)
493                 return INVALID_WINFD;
494
495         for (i=0; i<MAX_FDS; i++) {
496                 if (poll_fd[i].fd == fd) {
497                         EnterCriticalSection(&_poll_fd[i].mutex);
498                         // fd might have been deleted before we got to critical
499                         if (poll_fd[i].fd != fd) {
500                                 LeaveCriticalSection(&_poll_fd[i].mutex);
501                                 continue;
502                         }
503                         memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
504                         LeaveCriticalSection(&_poll_fd[i].mutex);
505                         return wfd;
506                 }
507         }
508         return INVALID_WINFD;
509 }
510
511 struct winfd handle_to_winfd(HANDLE handle)
512 {
513         int i;
514         struct winfd wfd;
515
516         CHECK_INIT_POLLING;
517
518         if ((handle == 0) || (handle == INVALID_HANDLE_VALUE))
519                 return INVALID_WINFD;
520
521         for (i=0; i<MAX_FDS; i++) {
522                 if (poll_fd[i].handle == handle) {
523                         EnterCriticalSection(&_poll_fd[i].mutex);
524                         // fd might have been deleted before we got to critical
525                         if (poll_fd[i].handle != handle) {
526                                 LeaveCriticalSection(&_poll_fd[i].mutex);
527                                 continue;
528                         }
529                         memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
530                         LeaveCriticalSection(&_poll_fd[i].mutex);
531                         return wfd;
532                 }
533         }
534         return INVALID_WINFD;
535 }
536
537 struct winfd overlapped_to_winfd(OVERLAPPED* overlapped)
538 {
539         int i;
540         struct winfd wfd;
541
542         CHECK_INIT_POLLING;
543
544         if (overlapped == NULL)
545                 return INVALID_WINFD;
546
547         for (i=0; i<MAX_FDS; i++) {
548                 if (poll_fd[i].overlapped == overlapped) {
549                         EnterCriticalSection(&_poll_fd[i].mutex);
550                         // fd might have been deleted before we got to critical
551                         if (poll_fd[i].overlapped != overlapped) {
552                                 LeaveCriticalSection(&_poll_fd[i].mutex);
553                                 continue;
554                         }
555                         memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
556                         LeaveCriticalSection(&_poll_fd[i].mutex);
557                         return wfd;
558                 }
559         }
560         return INVALID_WINFD;
561 }
562
563 /*
564  * POSIX poll equivalent, using Windows OVERLAPPED
565  * Currently, this function only accepts one of POLLIN or POLLOUT per fd
566  * (but you can create multiple fds from the same handle for read and write)
567  */
568 int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout)
569 {
570         unsigned i;
571         int _index, object_index, triggered;
572         HANDLE *handles_to_wait_on;
573         int *handle_to_index;
574         DWORD nb_handles_to_wait_on = 0;
575         DWORD ret;
576
577 #if defined(DYNAMIC_FDS)
578         DWORD nb_extra_handles = 0;
579         unsigned j;
580
581         // To address the possibility of missing new fds between the time the new
582         // pollable fd set is assembled, and the ResetEvent() call below, an
583         // additional new_fd[] HANDLE table is used for any new fd that was created
584         // since the last call to poll (see below)
585         ResetEvent(fd_update);
586
587         // At this stage, any new fd creation will be detected through the fd_update
588         // event notification, and any previous creation that we may have missed
589         // will be picked up through the existing new_fd[] table.
590 #endif
591
592         CHECK_INIT_POLLING;
593
594         triggered = 0;
595         handles_to_wait_on = malloc((nfds+1)*sizeof(HANDLE));   // +1 for fd_update
596         handle_to_index = malloc(nfds*sizeof(int));
597         if ((handles_to_wait_on == NULL) || (handle_to_index == NULL)) {
598                 errno = ENOMEM;
599                 triggered = -1;
600                 goto poll_exit;
601         }
602
603         for (i = 0; i < nfds; ++i) {
604                 fds[i].revents = 0;
605
606                 // Only one of POLLIN or POLLOUT can be selected with this version of poll (not both)
607                 if ((fds[i].events & ~POLLIN) && (!(fds[i].events & POLLOUT))) {
608                         fds[i].revents |= POLLERR;
609                         errno = EACCES;
610                         usbi_warn(NULL, "unsupported set of events");
611                         triggered = -1;
612                         goto poll_exit;
613                 }
614
615                 _index = _fd_to_index_and_lock(fds[i].fd);
616                 poll_dbg("fd[%d]=%d: (overlapped=%p) got events %04X", i, poll_fd[_index].fd, poll_fd[_index].overlapped, fds[i].events);
617
618                 if ( (_index < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
619                   || (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL)) {
620                         fds[i].revents |= POLLNVAL | POLLERR;
621                         errno = EBADF;
622                         if (_index >= 0) {
623                                 LeaveCriticalSection(&_poll_fd[_index].mutex);
624                         }
625                         usbi_warn(NULL, "invalid fd");
626                         triggered = -1;
627                         goto poll_exit;
628                 }
629
630                 // IN or OUT must match our fd direction
631                 if ((fds[i].events & POLLIN) && (poll_fd[_index].rw != RW_READ)) {
632                         fds[i].revents |= POLLNVAL | POLLERR;
633                         errno = EBADF;
634                         usbi_warn(NULL, "attempted POLLIN on fd without READ access");
635                         LeaveCriticalSection(&_poll_fd[_index].mutex);
636                         triggered = -1;
637                         goto poll_exit;
638                 }
639
640                 if ((fds[i].events & POLLOUT) && (poll_fd[_index].rw != RW_WRITE)) {
641                         fds[i].revents |= POLLNVAL | POLLERR;
642                         errno = EBADF;
643                         usbi_warn(NULL, "attempted POLLOUT on fd without WRITE access");
644                         LeaveCriticalSection(&_poll_fd[_index].mutex);
645                         triggered = -1;
646                         goto poll_exit;
647                 }
648
649                 // The following macro only works if overlapped I/O was reported pending
650                 if ( (HasOverlappedIoCompleted(poll_fd[_index].overlapped))
651                   || (HasOverlappedIoCompletedSync(poll_fd[_index].overlapped)) ) {
652                         poll_dbg("  completed");
653                         // checks above should ensure this works:
654                         fds[i].revents = fds[i].events;
655                         triggered++;
656                 } else {
657                         handles_to_wait_on[nb_handles_to_wait_on] = poll_fd[_index].overlapped->hEvent;
658                         handle_to_index[nb_handles_to_wait_on] = i;
659 #if defined(DYNAMIC_FDS)
660                         // If this fd from the poll set is also part of the new_fd event handle table, remove it
661                         usbi_mutex_lock(&new_fd_mutex);
662                         for (j=0; j<nb_new_fds; j++) {
663                                 if (handles_to_wait_on[nb_handles_to_wait_on] == new_fd[j]) {
664                                         new_fd[j] = INVALID_HANDLE_VALUE;
665                                         break;
666                                 }
667                         }
668                         usbi_mutex_unlock(&new_fd_mutex);
669 #endif
670                         nb_handles_to_wait_on++;
671                 }
672                 LeaveCriticalSection(&_poll_fd[_index].mutex);
673         }
674 #if defined(DYNAMIC_FDS)
675         // At this stage, new_fd[] should only contain events from fds that
676         // have been added since the last call to poll, but are not (yet) part
677         // of the pollable fd set. Typically, these would be from fds that have
678         // been created between the construction of the fd set and the calling
679         // of poll.
680         // Event if we won't be able to return usable poll data on these events,
681         // make sure we monitor them to return an EINTR code
682         usbi_mutex_lock(&new_fd_mutex); // We could probably do without
683         for (i=0; i<nb_new_fds; i++) {
684                 if (new_fd[i] != INVALID_HANDLE_VALUE) {
685                         handles_to_wait_on[nb_handles_to_wait_on++] = new_fd[i];
686                         nb_extra_handles++;
687                 }
688         }
689         usbi_mutex_unlock(&new_fd_mutex);
690         poll_dbg("dynamic_fds: added %d extra handles", nb_extra_handles);
691 #endif
692
693         // If nothing was triggered, wait on all fds that require it
694         if ((timeout != 0) && (triggered == 0) && (nb_handles_to_wait_on != 0)) {
695 #if defined(DYNAMIC_FDS)
696                 // Register for fd update notifications
697                 handles_to_wait_on[nb_handles_to_wait_on++] = fd_update;
698                 nb_extra_handles++;
699 #endif
700                 if (timeout < 0) {
701                         poll_dbg("starting infinite wait for %d handles...", (int)nb_handles_to_wait_on);
702                 } else {
703                         poll_dbg("starting %d ms wait for %d handles...", timeout, (int)nb_handles_to_wait_on);
704                 }
705                 ret = WaitForMultipleObjects(nb_handles_to_wait_on, handles_to_wait_on,
706                         FALSE, (timeout<0)?INFINITE:(DWORD)timeout);
707                 object_index = ret-WAIT_OBJECT_0;
708                 if ((object_index >= 0) && ((DWORD)object_index < nb_handles_to_wait_on)) {
709 #if defined(DYNAMIC_FDS)
710                         if ((DWORD)object_index >= (nb_handles_to_wait_on-nb_extra_handles)) {
711                                 // Detected fd update => flag a poll interruption
712                                 if ((DWORD)object_index == (nb_handles_to_wait_on-1))
713                                         poll_dbg("  dynamic_fds: fd_update event");
714                                 else
715                                         poll_dbg("  dynamic_fds: new fd I/O event");
716                                 errno = EINTR;
717                                 triggered = -1;
718                                 goto poll_exit;
719                         }
720 #endif
721                         poll_dbg("  completed after wait");
722                         i = handle_to_index[object_index];
723                         _index = _fd_to_index_and_lock(fds[i].fd);
724                         fds[i].revents = fds[i].events;
725                         triggered++;
726                         if (_index >= 0) {
727                                 LeaveCriticalSection(&_poll_fd[_index].mutex);
728                         }
729                 } else if (ret == WAIT_TIMEOUT) {
730                         poll_dbg("  timed out");
731                         triggered = 0;  // 0 = timeout
732                 } else {
733                         errno = EIO;
734                         triggered = -1; // error
735                 }
736         }
737
738 poll_exit:
739         if (handles_to_wait_on != NULL) {
740                 free(handles_to_wait_on);
741         }
742         if (handle_to_index != NULL) {
743                 free(handle_to_index);
744         }
745 #if defined(DYNAMIC_FDS)
746         usbi_mutex_lock(&new_fd_mutex);
747         nb_new_fds = 0;
748         usbi_mutex_unlock(&new_fd_mutex);
749 #endif
750         return triggered;
751 }
752
753 /*
754  * close a fake pipe fd
755  */
756 int usbi_close(int fd)
757 {
758         int _index;
759         int r = -1;
760
761         CHECK_INIT_POLLING;
762
763         _index = _fd_to_index_and_lock(fd);
764
765         if (_index < 0) {
766                 errno = EBADF;
767         } else {
768                 if (poll_fd[_index].overlapped != NULL) {
769                         // Must be a different event for each end of the pipe
770                         CloseHandle(poll_fd[_index].overlapped->hEvent);
771                         free(poll_fd[_index].overlapped);
772                 }
773                 if (CloseHandle(poll_fd[_index].handle) == 0) {
774                         errno = EIO;
775                 } else {
776                         r = 0;
777                 }
778                 poll_fd[_index] = INVALID_WINFD;
779                 LeaveCriticalSection(&_poll_fd[_index].mutex);
780         }
781         return r;
782 }
783
784 /*
785  * synchronous write for fake "pipe" signaling
786  */
787 ssize_t usbi_write(int fd, const void *buf, size_t count)
788 {
789         int _index;
790
791         CHECK_INIT_POLLING;
792
793         if (count != sizeof(unsigned char)) {
794                 usbi_err(NULL, "this function should only used for signaling");
795                 return -1;
796         }
797
798         _index = _fd_to_index_and_lock(fd);
799
800         if ( (_index < 0) || (poll_fd[_index].overlapped == NULL) ) {
801                 errno = EBADF;
802                 if (_index >= 0) {
803                         LeaveCriticalSection(&_poll_fd[_index].mutex);
804                 }
805                 return -1;
806         }
807
808         poll_dbg("set pipe event (fd = %d, thread = %08X)", _index, GetCurrentThreadId());
809         SetEvent(poll_fd[_index].overlapped->hEvent);
810         poll_fd[_index].overlapped->Internal = STATUS_WAIT_0;
811         // If two threads write on the pipe at the same time, we need to
812         // process two separate reads => use the overlapped as a counter
813         poll_fd[_index].overlapped->InternalHigh++;
814
815         LeaveCriticalSection(&_poll_fd[_index].mutex);
816         return sizeof(unsigned char);
817 }
818
819 /*
820  * synchronous read for fake "pipe" signaling
821  */
822 ssize_t usbi_read(int fd, void *buf, size_t count)
823 {
824         int _index;
825         ssize_t r = -1;
826
827         CHECK_INIT_POLLING;
828
829         if (count != sizeof(unsigned char)) {
830                 usbi_err(NULL, "this function should only used for signaling");
831                 return -1;
832         }
833
834         _index = _fd_to_index_and_lock(fd);
835
836         if (_index < 0) {
837                 errno = EBADF;
838                 return -1;
839         }
840
841         if (WaitForSingleObject(poll_fd[_index].overlapped->hEvent, INFINITE) != WAIT_OBJECT_0) {
842                 usbi_warn(NULL, "waiting for event failed: %d", (int)GetLastError());
843                 errno = EIO;
844                 goto out;
845         }
846
847         poll_dbg("clr pipe event (fd = %d, thread = %08X)", _index, GetCurrentThreadId());
848         poll_fd[_index].overlapped->InternalHigh--;
849         // Don't reset unless we don't have any more events to process
850         if (poll_fd[_index].overlapped->InternalHigh <= 0) {
851                 ResetEvent(poll_fd[_index].overlapped->hEvent);
852                 poll_fd[_index].overlapped->Internal = STATUS_PENDING;
853         }
854
855         r = sizeof(unsigned char);
856
857 out:
858         LeaveCriticalSection(&_poll_fd[_index].mutex);
859         return r;
860 }