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); | 
