diff options
-rw-r--r-- | Changes | 4 | ||||
-rw-r--r-- | ev.c | 6 | ||||
-rw-r--r-- | ev.pod | 19 | ||||
-rw-r--r-- | ev_select.c | 27 |
4 files changed, 46 insertions, 10 deletions
@@ -1,5 +1,8 @@ Revision history for libev, a high-performance and full-featured event loop. + - work around yet another windows bug: FD_SET actually adds fd's + multiple times to the fd_*SET*, despite official MSN docs claiming + otherwise. Reported and wel-analysed by Matt Tolton. - define NFSBITS to 0 when EV_SELECT_IS_WINSOCKET to make it compile (reported any analysed by Chris Hulbert). - fix a bug in ev_ebadf (this function is only used to catch @@ -7,6 +10,7 @@ Revision history for libev, a high-performance and full-featured event loop. - fix a bug in fd_intern on win32 (could lead to compile errors under some circumstances, but would work correctly if it compiles). reported by Matt Tolton. + - (try to) work around missing lstat on windows. - pass in the write fd set as except fd set under windows. windows is so uncontrollably lame that it requires this. this means that switching off oobinline is not supported (but tcp/ip doesn't @@ -2571,6 +2571,12 @@ infy_fork (EV_P) #endif +#ifdef _WIN32 +# define EV_LSTAT(p,b) _stati64 (p, b) +#else +# define EV_LSTAT(p,b) lstat (p, b) +#endif + void ev_stat_stat (EV_P_ ev_stat *w) { @@ -3328,6 +3328,22 @@ different implementation for windows, as libev offers the POSIX readiness notification model, which cannot be implemented efficiently on windows (Microsoft monopoly games). +A typical way to use libev under windows is to embed it (see the embedding +section for details) and use the following F<evwrap.h> header file instead +of F<ev.h>: + + #define EV_STANDALONE /* keeps ev from requiring config.h */ + #define EV_SELECT_IS_WINSOCKET 1 /* configure libev for windows select */ + #define EV_STAT_ENABLE 0 /* no stat() availble */ + + #include "ev.h" + +And compile the following F<evwrap.c> file into your project (make sure +you do I<not> compile the F<ev.c> or any other embedded soruce files!): + + #include "evwrap.h" + #include "ev.c" + =over 4 =item The winsocket select function @@ -3335,7 +3351,8 @@ notification model, which cannot be implemented efficiently on windows The winsocket C<select> function doesn't follow POSIX in that it requires socket I<handles> and not socket I<file descriptors> (it is also extremely buggy). This makes select very inefficient, and also -requires a mapping from file descriptors to socket handles. See the +requires a mapping from file descriptors to socket handles (the Microsoft +C runtime provides the function C<_open_osfhandle> for this). See the discussion of the C<EV_SELECT_USE_FD_SET>, C<EV_SELECT_IS_WINSOCKET> and C<EV_FD_TO_WIN32_HANDLE> preprocessor symbols for more info. diff --git a/ev_select.c b/ev_select.c index 1303a56..93d84cf 100644 --- a/ev_select.c +++ b/ev_select.c @@ -79,15 +79,24 @@ select_modify (EV_P_ int fd, int oev, int nev) int handle = fd; #endif - if (nev & EV_READ) - FD_SET (handle, (fd_set *)vec_ri); - else - FD_CLR (handle, (fd_set *)vec_ri); - - if (nev & EV_WRITE) - FD_SET (handle, (fd_set *)vec_wi); - else - FD_CLR (handle, (fd_set *)vec_wi); + /* FD_SET is broken on windows (it adds the fd to a set twice or more, + * which eventually leads to overflows). Need to call it only on changes. + */ + #if EV_SELECT_IS_WINSOCKET + if ((oev ^ nev) & EV_READ) + #endif + if (nev & EV_READ) + FD_SET (handle, (fd_set *)vec_ri); + else + FD_CLR (handle, (fd_set *)vec_ri); + + #if EV_SELECT_IS_WINSOCKET + if ((oev ^ nev) & EV_WRITE) + #endif + if (nev & EV_WRITE) + FD_SET (handle, (fd_set *)vec_wi); + else + FD_CLR (handle, (fd_set *)vec_wi); #else |