diff options
-rw-r--r-- | Changes | 5 | ||||
-rw-r--r-- | ev_select.c | 25 |
2 files changed, 28 insertions, 2 deletions
@@ -1,6 +1,8 @@ Revision history for libev, a high-performance and full-featured event loop. -3.33 +3.4 + - work around an (undocumented) bug in winsocket select: if you + provide only empty fd sets then select returns WSAEINVAL. how sucky. - use 1-based 2-heap for EV_MINIMAL, simplifies code, reduces codesize and makes for better cache-efficiency. - use 3-based 4-heap for !EV_MINIMAL. this makes better use @@ -14,6 +16,7 @@ Revision history for libev, a high-performance and full-featured event loop. - improve ev_stat docs. - add portability requirements section. - fix manpage headers etc. + - normalise WSA error codes to lower range on windows. 3.31 Wed Apr 16 20:45:04 CEST 2008 - added last minute fix for ev_poll.c by Brandon Black. 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); |