diff options
Diffstat (limited to 'ev_select.c')
-rw-r--r-- | ev_select.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/ev_select.c b/ev_select.c index 3b06654..5844b8b 100644 --- a/ev_select.c +++ b/ev_select.c @@ -98,7 +98,7 @@ select_modify (EV_P_ int fd, int oev, int nev) int word = fd / NFDBITS; fd_mask mask = 1UL << (fd % NFDBITS); - if (expect_false (vec_max < word + 1)) + if (expect_false (vec_max <= word)) { int new_max = word + 1; @@ -147,6 +147,29 @@ select_poll (EV_P_ ev_tstamp timeout) #if EV_SELECT_IS_WINSOCKET errno = WSAGetLastError (); #endif + #ifdef WSABASEERR + /* on windows, select returns incompatible error codes, fix this */ + if (errno >= WSABASEERR && errno < WSABASEERR + 1000) + if (errno == WSAENOTSOCK) + errno = EBADF; + else + errno -= WSABASEERR; + #endif + + #ifdef _WIN32 + /* select on windows errornously returns EINVAL when no fd sets have been + * provided (this is documented). what microsoft doesn't tell you that this bug + * exists even when the fd sets are provided, so we have to check for this bug + * here and emulate by sleeping manually. + * we also get EINVAL when the timeout is invalid, but we ignore this case here + * and assume that EINVAL always means: you have to wait manually. + */ + if (errno == EINVAL) + { + ev_sleep (timeout); + return; + } + #endif if (errno == EBADF) fd_ebadf (EV_A); |