poll_windows.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  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. * poll() and pipe() Windows compatibility layer for libusb 1.0
  24. *
  25. * The way this layer works is by using OVERLAPPED with async I/O transfers, as
  26. * OVERLAPPED have an associated event which is flagged for I/O completion.
  27. *
  28. * For USB pollable async I/O, you would typically:
  29. * - obtain a Windows HANDLE to a file or device that has been opened in
  30. * OVERLAPPED mode
  31. * - call usbi_create_fd with this handle to obtain a custom fd.
  32. * Note that if you need simultaneous R/W access, you need to call create_fd
  33. * twice, once in _O_RDONLY and once in _O_WRONLY mode to obtain 2 separate
  34. * pollable fds
  35. * - leave the core functions call the poll routine and flag POLLIN/POLLOUT
  36. *
  37. * The pipe pollable synchronous I/O works using the overlapped event associated
  38. * with a fake pipe. The read/write functions are only meant to be used in that
  39. * context.
  40. */
  41. #include <errno.h>
  42. #include <fcntl.h>
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <io.h>
  46. #include <libusbi.h>
  47. // Uncomment to debug the polling layer
  48. //#define DEBUG_POLL_WINDOWS
  49. #if defined(DEBUG_POLL_WINDOWS)
  50. #define poll_dbg usbi_dbg
  51. #else
  52. // MSVC++ < 2005 cannot use a variadic argument and non MSVC
  53. // compilers produce warnings if parenthesis are omitted.
  54. #if defined(_MSC_VER) && _MSC_VER < 1400
  55. #define poll_dbg
  56. #else
  57. #define poll_dbg(...)
  58. #endif
  59. #endif
  60. #if defined(_PREFAST_)
  61. #pragma warning(disable:28719)
  62. #endif
  63. #if defined(__CYGWIN__)
  64. // cygwin produces a warning unless these prototypes are defined
  65. extern int _open(char* name, int flags);
  66. extern int _close(int fd);
  67. extern int _snprintf(char *buffer, size_t count, const char *format, ...);
  68. #define NUL_DEVICE "/dev/null"
  69. #else
  70. #define NUL_DEVICE "NUL"
  71. #endif
  72. #define CHECK_INIT_POLLING do {if(!is_polling_set) init_polling();} while(0)
  73. // public fd data
  74. const struct winfd INVALID_WINFD = {-1, INVALID_HANDLE_VALUE, NULL, RW_NONE};
  75. struct winfd poll_fd[MAX_FDS];
  76. // internal fd data
  77. struct {
  78. CRITICAL_SECTION mutex; // lock for fds
  79. // Additional variables for XP CancelIoEx partial emulation
  80. HANDLE original_handle;
  81. DWORD thread_id;
  82. } _poll_fd[MAX_FDS];
  83. // globals
  84. BOOLEAN is_polling_set = FALSE;
  85. LONG pipe_number = 0;
  86. static volatile LONG compat_spinlock = 0;
  87. // CancelIoEx, available on Vista and later only, provides the ability to cancel
  88. // a single transfer (OVERLAPPED) when used. As it may not be part of any of the
  89. // platform headers, we hook into the Kernel32 system DLL directly to seek it.
  90. static BOOL (__stdcall *pCancelIoEx)(HANDLE, LPOVERLAPPED) = NULL;
  91. #define CancelIoEx_Available (pCancelIoEx != NULL)
  92. static __inline BOOL cancel_io(int _index)
  93. {
  94. if ((_index < 0) || (_index >= MAX_FDS)) {
  95. return FALSE;
  96. }
  97. if ( (poll_fd[_index].fd < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
  98. || (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL) ) {
  99. return TRUE;
  100. }
  101. if (CancelIoEx_Available) {
  102. return (*pCancelIoEx)(poll_fd[_index].handle, poll_fd[_index].overlapped);
  103. }
  104. if (_poll_fd[_index].thread_id == GetCurrentThreadId()) {
  105. return CancelIo(poll_fd[_index].handle);
  106. }
  107. usbi_warn(NULL, "Unable to cancel I/O that was started from another thread");
  108. return FALSE;
  109. }
  110. // Init
  111. void init_polling(void)
  112. {
  113. int i;
  114. while (InterlockedExchange((LONG *)&compat_spinlock, 1) == 1) {
  115. SleepEx(0, TRUE);
  116. }
  117. if (!is_polling_set) {
  118. pCancelIoEx = (BOOL (__stdcall *)(HANDLE,LPOVERLAPPED))
  119. GetProcAddress(GetModuleHandleA("KERNEL32"), "CancelIoEx");
  120. usbi_dbg("Will use CancelIo%s for I/O cancellation",
  121. CancelIoEx_Available?"Ex":"");
  122. for (i=0; i<MAX_FDS; i++) {
  123. poll_fd[i] = INVALID_WINFD;
  124. _poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
  125. _poll_fd[i].thread_id = 0;
  126. InitializeCriticalSection(&_poll_fd[i].mutex);
  127. }
  128. is_polling_set = TRUE;
  129. }
  130. compat_spinlock = 0;
  131. }
  132. // Internal function to retrieve the table index (and lock the fd mutex)
  133. int _fd_to_index_and_lock(int fd)
  134. {
  135. int i;
  136. if (fd <= 0)
  137. return -1;
  138. for (i=0; i<MAX_FDS; i++) {
  139. if (poll_fd[i].fd == fd) {
  140. EnterCriticalSection(&_poll_fd[i].mutex);
  141. // fd might have changed before we got to critical
  142. if (poll_fd[i].fd != fd) {
  143. LeaveCriticalSection(&_poll_fd[i].mutex);
  144. continue;
  145. }
  146. return i;
  147. }
  148. }
  149. return -1;
  150. }
  151. OVERLAPPED *create_overlapped(void)
  152. {
  153. OVERLAPPED *overlapped = (OVERLAPPED*) calloc(1, sizeof(OVERLAPPED));
  154. if (overlapped == NULL) {
  155. return NULL;
  156. }
  157. overlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  158. if(overlapped->hEvent == NULL) {
  159. free (overlapped);
  160. return NULL;
  161. }
  162. return overlapped;
  163. }
  164. void free_overlapped(OVERLAPPED *overlapped)
  165. {
  166. if (overlapped == NULL)
  167. return;
  168. if ( (overlapped->hEvent != 0)
  169. && (overlapped->hEvent != INVALID_HANDLE_VALUE) ) {
  170. CloseHandle(overlapped->hEvent);
  171. }
  172. free(overlapped);
  173. }
  174. void reset_overlapped(OVERLAPPED *overlapped)
  175. {
  176. HANDLE event_handle;
  177. if (overlapped == NULL)
  178. return;
  179. event_handle = overlapped->hEvent;
  180. if (event_handle != NULL) {
  181. ResetEvent(event_handle);
  182. }
  183. memset(overlapped, 0, sizeof(OVERLAPPED));
  184. overlapped->hEvent = event_handle;
  185. }
  186. void exit_polling(void)
  187. {
  188. int i;
  189. while (InterlockedExchange((LONG *)&compat_spinlock, 1) == 1) {
  190. SleepEx(0, TRUE);
  191. }
  192. if (is_polling_set) {
  193. is_polling_set = FALSE;
  194. for (i=0; i<MAX_FDS; i++) {
  195. // Cancel any async I/O (handle can be invalid)
  196. cancel_io(i);
  197. // If anything was pending on that I/O, it should be
  198. // terminating, and we should be able to access the fd
  199. // mutex lock before too long
  200. EnterCriticalSection(&_poll_fd[i].mutex);
  201. if ( (poll_fd[i].fd > 0) && (poll_fd[i].handle != INVALID_HANDLE_VALUE) && (poll_fd[i].handle != 0)
  202. && (GetFileType(poll_fd[i].handle) == FILE_TYPE_UNKNOWN) ) {
  203. _close(poll_fd[i].fd);
  204. }
  205. free_overlapped(poll_fd[i].overlapped);
  206. if (!CancelIoEx_Available) {
  207. // Close duplicate handle
  208. if (_poll_fd[i].original_handle != INVALID_HANDLE_VALUE) {
  209. CloseHandle(poll_fd[i].handle);
  210. }
  211. }
  212. poll_fd[i] = INVALID_WINFD;
  213. LeaveCriticalSection(&_poll_fd[i].mutex);
  214. DeleteCriticalSection(&_poll_fd[i].mutex);
  215. }
  216. }
  217. compat_spinlock = 0;
  218. }
  219. /*
  220. * Create a fake pipe.
  221. * As libusb only uses pipes for signaling, all we need from a pipe is an
  222. * event. To that extent, we create a single wfd and overlapped as a means
  223. * to access that event.
  224. */
  225. int usbi_pipe(int filedes[2])
  226. {
  227. int i;
  228. OVERLAPPED* overlapped;
  229. CHECK_INIT_POLLING;
  230. overlapped = (OVERLAPPED*) calloc(1, sizeof(OVERLAPPED));
  231. if (overlapped == NULL) {
  232. return -1;
  233. }
  234. // The overlapped must have status pending for signaling to work in poll
  235. overlapped->Internal = STATUS_PENDING;
  236. overlapped->InternalHigh = 0;
  237. // Read end of the "pipe"
  238. filedes[0] = _open(NUL_DEVICE, _O_WRONLY);
  239. if (filedes[0] < 0) {
  240. usbi_err(NULL, "could not create pipe: errno %d", errno);
  241. goto out1;
  242. }
  243. // We can use the same handle for both ends
  244. filedes[1] = filedes[0];
  245. poll_dbg("pipe filedes = %d", filedes[0]);
  246. // Note: manual reset must be true (second param) as the reset occurs in read
  247. overlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  248. if(!overlapped->hEvent) {
  249. goto out2;
  250. }
  251. for (i=0; i<MAX_FDS; i++) {
  252. if (poll_fd[i].fd < 0) {
  253. EnterCriticalSection(&_poll_fd[i].mutex);
  254. // fd might have been allocated before we got to critical
  255. if (poll_fd[i].fd >= 0) {
  256. LeaveCriticalSection(&_poll_fd[i].mutex);
  257. continue;
  258. }
  259. poll_fd[i].fd = filedes[0];
  260. poll_fd[i].handle = DUMMY_HANDLE;
  261. poll_fd[i].overlapped = overlapped;
  262. // There's no polling on the write end, so we just use READ for our needs
  263. poll_fd[i].rw = RW_READ;
  264. _poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
  265. LeaveCriticalSection(&_poll_fd[i].mutex);
  266. return 0;
  267. }
  268. }
  269. CloseHandle(overlapped->hEvent);
  270. out2:
  271. _close(filedes[0]);
  272. out1:
  273. free(overlapped);
  274. return -1;
  275. }
  276. /*
  277. * Create both an fd and an OVERLAPPED from an open Windows handle, so that
  278. * it can be used with our polling function
  279. * The handle MUST support overlapped transfers (usually requires CreateFile
  280. * with FILE_FLAG_OVERLAPPED)
  281. * Return a pollable file descriptor struct, or INVALID_WINFD on error
  282. *
  283. * Note that the fd returned by this function is a per-transfer fd, rather
  284. * than a per-session fd and cannot be used for anything else but our
  285. * custom functions (the fd itself points to the NUL: device)
  286. * if you plan to do R/W on the same handle, you MUST create 2 fds: one for
  287. * read and one for write. Using a single R/W fd is unsupported and will
  288. * produce unexpected results
  289. */
  290. struct winfd usbi_create_fd(HANDLE handle, int access_mode)
  291. {
  292. int i, fd;
  293. struct winfd wfd = INVALID_WINFD;
  294. OVERLAPPED* overlapped = NULL;
  295. CHECK_INIT_POLLING;
  296. if ((handle == 0) || (handle == INVALID_HANDLE_VALUE)) {
  297. return INVALID_WINFD;
  298. }
  299. if ((access_mode != _O_RDONLY) && (access_mode != _O_WRONLY)) {
  300. usbi_warn(NULL, "only one of _O_RDONLY or _O_WRONLY are supported.\n"
  301. "If you want to poll for R/W simultaneously, create multiple fds from the same handle.");
  302. return INVALID_WINFD;
  303. }
  304. if (access_mode == _O_RDONLY) {
  305. wfd.rw = RW_READ;
  306. } else {
  307. wfd.rw = RW_WRITE;
  308. }
  309. // Ensure that we get a non system conflicting unique fd, using
  310. // the same fd attribution system as the pipe ends
  311. fd = _open(NUL_DEVICE, _O_WRONLY);
  312. if (fd < 0) {
  313. return INVALID_WINFD;
  314. }
  315. overlapped = create_overlapped();
  316. if(overlapped == NULL) {
  317. _close(fd);
  318. return INVALID_WINFD;
  319. }
  320. for (i=0; i<MAX_FDS; i++) {
  321. if (poll_fd[i].fd < 0) {
  322. EnterCriticalSection(&_poll_fd[i].mutex);
  323. // fd might have been removed before we got to critical
  324. if (poll_fd[i].fd >= 0) {
  325. LeaveCriticalSection(&_poll_fd[i].mutex);
  326. continue;
  327. }
  328. wfd.fd = fd;
  329. // Attempt to emulate some of the CancelIoEx behaviour on platforms
  330. // that don't have it
  331. if (!CancelIoEx_Available) {
  332. _poll_fd[i].thread_id = GetCurrentThreadId();
  333. if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(),
  334. &wfd.handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
  335. usbi_dbg("could not duplicate handle for CancelIo - using original one");
  336. wfd.handle = handle;
  337. // Make sure we won't close the original handle on fd deletion then
  338. _poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
  339. } else {
  340. _poll_fd[i].original_handle = handle;
  341. }
  342. } else {
  343. wfd.handle = handle;
  344. }
  345. wfd.overlapped = overlapped;
  346. memcpy(&poll_fd[i], &wfd, sizeof(struct winfd));
  347. LeaveCriticalSection(&_poll_fd[i].mutex);
  348. return wfd;
  349. }
  350. }
  351. free_overlapped(overlapped);
  352. _close(fd);
  353. return INVALID_WINFD;
  354. }
  355. void _free_index(int _index)
  356. {
  357. // Cancel any async IO (Don't care about the validity of our handles for this)
  358. cancel_io(_index);
  359. // close fake handle for devices
  360. if ( (poll_fd[_index].handle != INVALID_HANDLE_VALUE) && (poll_fd[_index].handle != 0)
  361. && (GetFileType(poll_fd[_index].handle) == FILE_TYPE_UNKNOWN) ) {
  362. _close(poll_fd[_index].fd);
  363. }
  364. // close the duplicate handle (if we have an actual duplicate)
  365. if (!CancelIoEx_Available) {
  366. if (_poll_fd[_index].original_handle != INVALID_HANDLE_VALUE) {
  367. CloseHandle(poll_fd[_index].handle);
  368. }
  369. _poll_fd[_index].original_handle = INVALID_HANDLE_VALUE;
  370. _poll_fd[_index].thread_id = 0;
  371. }
  372. free_overlapped(poll_fd[_index].overlapped);
  373. poll_fd[_index] = INVALID_WINFD;
  374. }
  375. /*
  376. * Release a pollable file descriptor.
  377. *
  378. * Note that the associated Windows handle is not closed by this call
  379. */
  380. void usbi_free_fd(int fd)
  381. {
  382. int _index;
  383. CHECK_INIT_POLLING;
  384. _index = _fd_to_index_and_lock(fd);
  385. if (_index < 0) {
  386. return;
  387. }
  388. _free_index(_index);
  389. LeaveCriticalSection(&_poll_fd[_index].mutex);
  390. }
  391. /*
  392. * The functions below perform various conversions between fd, handle and OVERLAPPED
  393. */
  394. struct winfd fd_to_winfd(int fd)
  395. {
  396. int i;
  397. struct winfd wfd;
  398. CHECK_INIT_POLLING;
  399. if (fd <= 0)
  400. return INVALID_WINFD;
  401. for (i=0; i<MAX_FDS; i++) {
  402. if (poll_fd[i].fd == fd) {
  403. EnterCriticalSection(&_poll_fd[i].mutex);
  404. // fd might have been deleted before we got to critical
  405. if (poll_fd[i].fd != fd) {
  406. LeaveCriticalSection(&_poll_fd[i].mutex);
  407. continue;
  408. }
  409. memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
  410. LeaveCriticalSection(&_poll_fd[i].mutex);
  411. return wfd;
  412. }
  413. }
  414. return INVALID_WINFD;
  415. }
  416. struct winfd handle_to_winfd(HANDLE handle)
  417. {
  418. int i;
  419. struct winfd wfd;
  420. CHECK_INIT_POLLING;
  421. if ((handle == 0) || (handle == INVALID_HANDLE_VALUE))
  422. return INVALID_WINFD;
  423. for (i=0; i<MAX_FDS; i++) {
  424. if (poll_fd[i].handle == handle) {
  425. EnterCriticalSection(&_poll_fd[i].mutex);
  426. // fd might have been deleted before we got to critical
  427. if (poll_fd[i].handle != handle) {
  428. LeaveCriticalSection(&_poll_fd[i].mutex);
  429. continue;
  430. }
  431. memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
  432. LeaveCriticalSection(&_poll_fd[i].mutex);
  433. return wfd;
  434. }
  435. }
  436. return INVALID_WINFD;
  437. }
  438. struct winfd overlapped_to_winfd(OVERLAPPED* overlapped)
  439. {
  440. int i;
  441. struct winfd wfd;
  442. CHECK_INIT_POLLING;
  443. if (overlapped == NULL)
  444. return INVALID_WINFD;
  445. for (i=0; i<MAX_FDS; i++) {
  446. if (poll_fd[i].overlapped == overlapped) {
  447. EnterCriticalSection(&_poll_fd[i].mutex);
  448. // fd might have been deleted before we got to critical
  449. if (poll_fd[i].overlapped != overlapped) {
  450. LeaveCriticalSection(&_poll_fd[i].mutex);
  451. continue;
  452. }
  453. memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
  454. LeaveCriticalSection(&_poll_fd[i].mutex);
  455. return wfd;
  456. }
  457. }
  458. return INVALID_WINFD;
  459. }
  460. /*
  461. * POSIX poll equivalent, using Windows OVERLAPPED
  462. * Currently, this function only accepts one of POLLIN or POLLOUT per fd
  463. * (but you can create multiple fds from the same handle for read and write)
  464. */
  465. int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout)
  466. {
  467. unsigned i;
  468. int _index, object_index, triggered;
  469. HANDLE *handles_to_wait_on;
  470. int *handle_to_index;
  471. DWORD nb_handles_to_wait_on = 0;
  472. DWORD ret;
  473. CHECK_INIT_POLLING;
  474. triggered = 0;
  475. handles_to_wait_on = (HANDLE*) calloc(nfds+1, sizeof(HANDLE)); // +1 for fd_update
  476. handle_to_index = (int*) calloc(nfds, sizeof(int));
  477. if ((handles_to_wait_on == NULL) || (handle_to_index == NULL)) {
  478. errno = ENOMEM;
  479. triggered = -1;
  480. goto poll_exit;
  481. }
  482. for (i = 0; i < nfds; ++i) {
  483. fds[i].revents = 0;
  484. // Only one of POLLIN or POLLOUT can be selected with this version of poll (not both)
  485. if ((fds[i].events & ~POLLIN) && (!(fds[i].events & POLLOUT))) {
  486. fds[i].revents |= POLLERR;
  487. errno = EACCES;
  488. usbi_warn(NULL, "unsupported set of events");
  489. triggered = -1;
  490. goto poll_exit;
  491. }
  492. _index = _fd_to_index_and_lock(fds[i].fd);
  493. poll_dbg("fd[%d]=%d: (overlapped=%p) got events %04X", i, poll_fd[_index].fd, poll_fd[_index].overlapped, fds[i].events);
  494. if ( (_index < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
  495. || (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL)) {
  496. fds[i].revents |= POLLNVAL | POLLERR;
  497. errno = EBADF;
  498. if (_index >= 0) {
  499. LeaveCriticalSection(&_poll_fd[_index].mutex);
  500. }
  501. usbi_warn(NULL, "invalid fd");
  502. triggered = -1;
  503. goto poll_exit;
  504. }
  505. // IN or OUT must match our fd direction
  506. if ((fds[i].events & POLLIN) && (poll_fd[_index].rw != RW_READ)) {
  507. fds[i].revents |= POLLNVAL | POLLERR;
  508. errno = EBADF;
  509. usbi_warn(NULL, "attempted POLLIN on fd without READ access");
  510. LeaveCriticalSection(&_poll_fd[_index].mutex);
  511. triggered = -1;
  512. goto poll_exit;
  513. }
  514. if ((fds[i].events & POLLOUT) && (poll_fd[_index].rw != RW_WRITE)) {
  515. fds[i].revents |= POLLNVAL | POLLERR;
  516. errno = EBADF;
  517. usbi_warn(NULL, "attempted POLLOUT on fd without WRITE access");
  518. LeaveCriticalSection(&_poll_fd[_index].mutex);
  519. triggered = -1;
  520. goto poll_exit;
  521. }
  522. // The following macro only works if overlapped I/O was reported pending
  523. if ( (HasOverlappedIoCompleted(poll_fd[_index].overlapped))
  524. || (HasOverlappedIoCompletedSync(poll_fd[_index].overlapped)) ) {
  525. poll_dbg(" completed");
  526. // checks above should ensure this works:
  527. fds[i].revents = fds[i].events;
  528. triggered++;
  529. } else {
  530. handles_to_wait_on[nb_handles_to_wait_on] = poll_fd[_index].overlapped->hEvent;
  531. handle_to_index[nb_handles_to_wait_on] = i;
  532. nb_handles_to_wait_on++;
  533. }
  534. LeaveCriticalSection(&_poll_fd[_index].mutex);
  535. }
  536. // If nothing was triggered, wait on all fds that require it
  537. if ((timeout != 0) && (triggered == 0) && (nb_handles_to_wait_on != 0)) {
  538. if (timeout < 0) {
  539. poll_dbg("starting infinite wait for %d handles...", (int)nb_handles_to_wait_on);
  540. } else {
  541. poll_dbg("starting %d ms wait for %d handles...", timeout, (int)nb_handles_to_wait_on);
  542. }
  543. ret = WaitForMultipleObjects(nb_handles_to_wait_on, handles_to_wait_on,
  544. FALSE, (timeout<0)?INFINITE:(DWORD)timeout);
  545. object_index = ret-WAIT_OBJECT_0;
  546. if ((object_index >= 0) && ((DWORD)object_index < nb_handles_to_wait_on)) {
  547. poll_dbg(" completed after wait");
  548. i = handle_to_index[object_index];
  549. _index = _fd_to_index_and_lock(fds[i].fd);
  550. fds[i].revents = fds[i].events;
  551. triggered++;
  552. if (_index >= 0) {
  553. LeaveCriticalSection(&_poll_fd[_index].mutex);
  554. }
  555. } else if (ret == WAIT_TIMEOUT) {
  556. poll_dbg(" timed out");
  557. triggered = 0; // 0 = timeout
  558. } else {
  559. errno = EIO;
  560. triggered = -1; // error
  561. }
  562. }
  563. poll_exit:
  564. if (handles_to_wait_on != NULL) {
  565. free(handles_to_wait_on);
  566. }
  567. if (handle_to_index != NULL) {
  568. free(handle_to_index);
  569. }
  570. return triggered;
  571. }
  572. /*
  573. * close a fake pipe fd
  574. */
  575. int usbi_close(int fd)
  576. {
  577. int _index;
  578. int r = -1;
  579. CHECK_INIT_POLLING;
  580. _index = _fd_to_index_and_lock(fd);
  581. if (_index < 0) {
  582. errno = EBADF;
  583. } else {
  584. if (poll_fd[_index].overlapped != NULL) {
  585. // Must be a different event for each end of the pipe
  586. CloseHandle(poll_fd[_index].overlapped->hEvent);
  587. free(poll_fd[_index].overlapped);
  588. }
  589. r = _close(poll_fd[_index].fd);
  590. if (r != 0) {
  591. errno = EIO;
  592. }
  593. poll_fd[_index] = INVALID_WINFD;
  594. LeaveCriticalSection(&_poll_fd[_index].mutex);
  595. }
  596. return r;
  597. }
  598. /*
  599. * synchronous write for fake "pipe" signaling
  600. */
  601. ssize_t usbi_write(int fd, const void *buf, size_t count)
  602. {
  603. int _index;
  604. CHECK_INIT_POLLING;
  605. if (count != sizeof(unsigned char)) {
  606. usbi_err(NULL, "this function should only used for signaling");
  607. return -1;
  608. }
  609. _index = _fd_to_index_and_lock(fd);
  610. if ( (_index < 0) || (poll_fd[_index].overlapped == NULL) ) {
  611. errno = EBADF;
  612. if (_index >= 0) {
  613. LeaveCriticalSection(&_poll_fd[_index].mutex);
  614. }
  615. return -1;
  616. }
  617. poll_dbg("set pipe event (fd = %d, thread = %08X)", _index, GetCurrentThreadId());
  618. SetEvent(poll_fd[_index].overlapped->hEvent);
  619. poll_fd[_index].overlapped->Internal = STATUS_WAIT_0;
  620. // If two threads write on the pipe at the same time, we need to
  621. // process two separate reads => use the overlapped as a counter
  622. poll_fd[_index].overlapped->InternalHigh++;
  623. LeaveCriticalSection(&_poll_fd[_index].mutex);
  624. return sizeof(unsigned char);
  625. }
  626. /*
  627. * synchronous read for fake "pipe" signaling
  628. */
  629. ssize_t usbi_read(int fd, void *buf, size_t count)
  630. {
  631. int _index;
  632. ssize_t r = -1;
  633. CHECK_INIT_POLLING;
  634. if (count != sizeof(unsigned char)) {
  635. usbi_err(NULL, "this function should only used for signaling");
  636. return -1;
  637. }
  638. _index = _fd_to_index_and_lock(fd);
  639. if (_index < 0) {
  640. errno = EBADF;
  641. return -1;
  642. }
  643. if (WaitForSingleObject(poll_fd[_index].overlapped->hEvent, INFINITE) != WAIT_OBJECT_0) {
  644. usbi_warn(NULL, "waiting for event failed: %d", (int)GetLastError());
  645. errno = EIO;
  646. goto out;
  647. }
  648. poll_dbg("clr pipe event (fd = %d, thread = %08X)", _index, GetCurrentThreadId());
  649. poll_fd[_index].overlapped->InternalHigh--;
  650. // Don't reset unless we don't have any more events to process
  651. if (poll_fd[_index].overlapped->InternalHigh <= 0) {
  652. ResetEvent(poll_fd[_index].overlapped->hEvent);
  653. poll_fd[_index].overlapped->Internal = STATUS_PENDING;
  654. }
  655. r = sizeof(unsigned char);
  656. out:
  657. LeaveCriticalSection(&_poll_fd[_index].mutex);
  658. return r;
  659. }