summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorroot <root>2008-06-09 14:11:30 +0000
committerroot <root>2008-06-09 14:11:30 +0000
commitdfe85dfd86119bfeed3e3b9e0b56f0e01e796de4 (patch)
tree45f45b80915e07d8ee19e5e94384b089c5646bc0
parentdf745b4f0e6329cf025a819384736eee93115072 (diff)
*** empty log message ***
-rw-r--r--Changes4
-rw-r--r--ev.c6
-rw-r--r--ev.pod19
-rw-r--r--ev_select.c27
4 files changed, 46 insertions, 10 deletions
diff --git a/Changes b/Changes
index cc4c5ac..73fc30e 100644
--- a/Changes
+++ b/Changes
@@ -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
diff --git a/ev.c b/ev.c
index 18dd2f5..f495041 100644
--- a/ev.c
+++ b/ev.c
@@ -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)
{
diff --git a/ev.pod b/ev.pod
index 8d286df..e11c551 100644
--- a/ev.pod
+++ b/ev.pod
@@ -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