summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorroot <root>2008-05-20 19:26:45 +0000
committerroot <root>2008-05-20 19:26:45 +0000
commite41363f983e45e61b9a6f6b1b2f906c7d39c5a54 (patch)
tree32715518e9c1e379fddc32b4a7aea7ae11b81824
parentd84a71bca8644e58d732c7eb2e0f321a750fb2e0 (diff)
*** empty log message ***rel-3_4
-rw-r--r--Changes5
-rw-r--r--ev_select.c25
2 files changed, 28 insertions, 2 deletions
diff --git a/Changes b/Changes
index cab1e19..5303f34 100644
--- a/Changes
+++ b/Changes
@@ -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);