From 2dff0867c6069c41ede598cd78bb2d5223fde025 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 12 Nov 2007 00:31:08 +0000 Subject: [PATCH] rewrite seletc backend, port again to msvc --- ev.c | 108 +++++++++++++++-------------- ev.h | 36 +++++----- ev_select.c | 195 +++++++++++++++++++++++++++------------------------- ev_vars.h | 8 +-- ev_win32.c | 5 +- event.c | 4 +- 6 files changed, 183 insertions(+), 173 deletions(-) diff --git a/ev.c b/ev.c index 4812c40..89c0929 100644 --- a/ev.c +++ b/ev.c @@ -77,11 +77,18 @@ extern "C" { #include -#ifndef WIN32 +#ifndef _WIN32 # include # include # include +#else +# define WIN32_LEAN_AND_MEAN +# include +# ifndef EV_SELECT_IS_WINSOCKET +# define EV_SELECT_IS_WINSOCKET 1 +# endif #endif + /**/ #ifndef EV_USE_MONOTONIC @@ -104,16 +111,6 @@ extern "C" { # define EV_USE_KQUEUE 0 #endif -#ifndef EV_USE_WIN32 -# ifdef WIN32 -# define EV_USE_WIN32 0 /* it does not exist, use select */ -# undef EV_USE_SELECT -# define EV_USE_SELECT 1 -# else -# define EV_USE_WIN32 0 -# endif -#endif - #ifndef EV_USE_REALTIME # define EV_USE_REALTIME 1 #endif @@ -130,6 +127,10 @@ extern "C" { # define EV_USE_REALTIME 0 #endif +#if EV_SELECT_IS_WINSOCKET +# include +#endif + /**/ #define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ @@ -157,13 +158,15 @@ extern "C" { #define NUMPRI (EV_MAXPRI - EV_MINPRI + 1) #define ABSPRI(w) ((w)->priority - EV_MINPRI) +#define EMPTY /* required for microsofts broken pseudo-c compiler */ + typedef struct ev_watcher *W; typedef struct ev_watcher_list *WL; typedef struct ev_watcher_time *WT; static int have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work? */ -#ifdef WIN32 +#ifdef _WIN32 # include "ev_win32.c" #endif @@ -222,6 +225,9 @@ typedef struct WL head; unsigned char events; unsigned char reify; +#if EV_SELECT_IS_WINSOCKET + SOCKET handle; +#endif } ANFD; typedef struct @@ -320,11 +326,6 @@ ev_now (EV_P) fprintf (stderr, "slimmed down " # stem " to %d\n", stem ## max);/*D*/\ } -/* microsoft's pseudo-c is quite far from C as the rest of the world and the standard knows it */ -/* bringing us everlasting joy in form of stupid extra macros that are not required in C */ -#define array_free_microshit(stem) \ - ev_free (stem ## s); stem ## cnt = stem ## max = 0; - #define array_free(stem, idx) \ ev_free (stem ## s idx); stem ## cnt idx = stem ## max idx = 0; @@ -408,6 +409,15 @@ fd_reify (EV_P) for (w = (struct ev_io *)anfd->head; w; w = (struct ev_io *)((WL)w)->next) events |= w->events; +#if EV_SELECT_IS_WINSOCKET + if (events) + { + unsigned long argp; + anfd->handle = _get_osfhandle (fd); + assert (("libev only supports socket fds in this configuration", ioctlsocket (anfd->handle, FIONREAD, &argp) == 0)); + } +#endif + anfd->reify = 0; method_modify (EV_A_ fd, anfd->events, events); @@ -445,8 +455,8 @@ fd_kill (EV_P_ int fd) static int fd_valid (int fd) { -#ifdef WIN32 - return !!win32_get_osfhandle (fd); +#ifdef _WIN32 + return _get_osfhandle (fd) != -1; #else return fcntl (fd, F_GETFD) != -1; #endif @@ -573,7 +583,7 @@ signals_init (ANSIG *base, int count) static void sighandler (int signum) { -#if WIN32 +#if _WIN32 signal (signum, sighandler); #endif @@ -583,11 +593,7 @@ sighandler (int signum) { int old_errno = errno; gotsig = 1; -#ifdef WIN32 - send (sigpipe [1], &signum, 1, MSG_DONTWAIT); -#else write (sigpipe [1], &signum, 1); -#endif errno = old_errno; } } @@ -617,11 +623,7 @@ sigcb (EV_P_ struct ev_io *iow, int revents) { int signum; -#ifdef WIN32 - recv (sigpipe [0], &revents, 1, MSG_DONTWAIT); -#else read (sigpipe [0], &revents, 1); -#endif gotsig = 0; for (signum = signalmax; signum--; ) @@ -629,17 +631,23 @@ sigcb (EV_P_ struct ev_io *iow, int revents) ev_feed_signal_event (EV_A_ signum + 1); } +inline void +fd_intern (int fd) +{ +#ifdef _WIN32 + int arg = 1; + ioctlsocket (_get_osfhandle (fd), FIONBIO, &arg); +#else + fcntl (fd, F_SETFD, FD_CLOEXEC); + fcntl (fd, F_SETFL, O_NONBLOCK); +#endif +} + static void siginit (EV_P) { -#ifndef WIN32 - fcntl (sigpipe [0], F_SETFD, FD_CLOEXEC); - fcntl (sigpipe [1], F_SETFD, FD_CLOEXEC); - - /* rather than sort out wether we really need nb, set it */ - fcntl (sigpipe [0], F_SETFL, O_NONBLOCK); - fcntl (sigpipe [1], F_SETFL, O_NONBLOCK); -#endif + fd_intern (sigpipe [0]); + fd_intern (sigpipe [1]); ev_io_set (&sigev, sigpipe [0], EV_READ); ev_io_start (EV_A_ &sigev); @@ -650,7 +658,7 @@ siginit (EV_P) static struct ev_child *childs [PID_HASHSIZE]; -#ifndef WIN32 +#ifndef _WIN32 static struct ev_signal childev; @@ -721,7 +729,7 @@ ev_version_minor (void) static int enable_secure (void) { -#ifdef WIN32 +#ifdef _WIN32 return 0; #else return getuid () != geteuid () @@ -760,9 +768,6 @@ loop_init (EV_P_ int methods) methods = EVMETHOD_ANY; method = 0; -#if EV_USE_WIN32 - if (!method && (methods & EVMETHOD_WIN32 )) method = win32_init (EV_A_ methods); -#endif #if EV_USE_KQUEUE if (!method && (methods & EVMETHOD_KQUEUE)) method = kqueue_init (EV_A_ methods); #endif @@ -786,9 +791,6 @@ loop_destroy (EV_P) { int i; -#if EV_USE_WIN32 - if (method == EVMETHOD_WIN32 ) win32_destroy (EV_A); -#endif #if EV_USE_KQUEUE if (method == EVMETHOD_KQUEUE) kqueue_destroy (EV_A); #endif @@ -806,14 +808,14 @@ loop_destroy (EV_P) array_free (pending, [i]); /* have to use the microsoft-never-gets-it-right macro */ - array_free_microshit (fdchange); - array_free_microshit (timer); + array_free (fdchange, EMPTY); + array_free (timer, EMPTY); #if EV_PERIODICS - array_free_microshit (periodic); + array_free (periodic, EMPTY); #endif - array_free_microshit (idle); - array_free_microshit (prepare); - array_free_microshit (check); + array_free (idle, EMPTY); + array_free (prepare, EMPTY); + array_free (check, EMPTY); method = 0; } @@ -902,7 +904,7 @@ ev_default_loop (int methods) { siginit (EV_A); -#ifndef WIN32 +#ifndef _WIN32 ev_signal_init (&childev, childcb, SIGCHLD); ev_set_priority (&childev, EV_MAXPRI); ev_signal_start (EV_A_ &childev); @@ -923,7 +925,7 @@ ev_default_destroy (void) struct ev_loop *loop = default_loop; #endif -#ifndef WIN32 +#ifndef _WIN32 ev_ref (EV_A); /* child watcher */ ev_signal_stop (EV_A_ &childev); #endif @@ -1513,7 +1515,7 @@ ev_signal_start (EV_P_ struct ev_signal *w) if (!((WL)w)->next) { -#if WIN32 +#if _WIN32 signal (w->signum, sighandler); #else struct sigaction sa; diff --git a/ev.h b/ev.h index 4c915a0..3f00918 100644 --- a/ev.h +++ b/ev.h @@ -86,7 +86,7 @@ struct ev_loop; /* can be used to add custom fields to all watchers, while losing binary compatibility */ #ifndef EV_COMMON -# define EV_COMMON void *data +# define EV_COMMON void *data; #endif #ifndef EV_PROTOTYPES # define EV_PROTOTYPES 1 @@ -114,40 +114,40 @@ struct ev_loop; int active; /* private */ \ int pending; /* private */ \ int priority; /* private */ \ - EV_COMMON; /* rw */ \ + EV_COMMON /* rw */ \ EV_CB_DECLARE (type) /* private */ #define EV_WATCHER_LIST(type) \ - EV_WATCHER (type); \ - struct ev_watcher_list *next /* private */ + EV_WATCHER (type) \ + struct ev_watcher_list *next; /* private */ #define EV_WATCHER_TIME(type) \ - EV_WATCHER (type); \ - ev_tstamp at /* private */ + EV_WATCHER (type) \ + ev_tstamp at; /* private */ /* base class, nothing to see here unless you subclass */ struct ev_watcher { - EV_WATCHER (ev_watcher); + EV_WATCHER (ev_watcher) }; /* base class, nothing to see here unless you subclass */ struct ev_watcher_list { - EV_WATCHER_LIST (ev_watcher_list); + EV_WATCHER_LIST (ev_watcher_list) }; /* base class, nothing to see here unless you subclass */ struct ev_watcher_time { - EV_WATCHER_TIME (ev_watcher_time); + EV_WATCHER_TIME (ev_watcher_time) }; /* invoked after a specific time, repeatable (based on monotonic clock) */ /* revent EV_TIMEOUT */ struct ev_timer { - EV_WATCHER_TIME (ev_timer); + EV_WATCHER_TIME (ev_timer) ev_tstamp repeat; /* rw */ }; @@ -156,7 +156,7 @@ struct ev_timer /* revent EV_PERIODIC */ struct ev_periodic { - EV_WATCHER_TIME (ev_periodic); + EV_WATCHER_TIME (ev_periodic) ev_tstamp interval; /* rw */ ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now); /* rw */ @@ -166,7 +166,7 @@ struct ev_periodic /* revent EV_READ, EV_WRITE */ struct ev_io { - EV_WATCHER_LIST (ev_io); + EV_WATCHER_LIST (ev_io) int fd; /* ro */ int events; /* ro */ @@ -176,7 +176,7 @@ struct ev_io /* revent EV_SIGNAL */ struct ev_signal { - EV_WATCHER_LIST (ev_signal); + EV_WATCHER_LIST (ev_signal) int signum; /* ro */ }; @@ -185,7 +185,7 @@ struct ev_signal /* revent EV_IDLE */ struct ev_idle { - EV_WATCHER (ev_idle); + EV_WATCHER (ev_idle) }; /* invoked for each run of the mainloop, just before the blocking call */ @@ -193,14 +193,14 @@ struct ev_idle /* revent EV_PREPARE */ struct ev_prepare { - EV_WATCHER (ev_prepare); + EV_WATCHER (ev_prepare) }; /* invoked for each run of the mainloop, just after the blocking call */ /* revent EV_CHECK */ struct ev_check { - EV_WATCHER (ev_check); + EV_WATCHER (ev_check) }; /* invoked when sigchld is received and waitpid indicates the givne pid */ @@ -208,7 +208,7 @@ struct ev_check /* does not support priorities */ struct ev_child { - EV_WATCHER_LIST (ev_child); + EV_WATCHER_LIST (ev_child) int pid; /* ro */ int rpid; /* rw, holds the received pid */ @@ -278,7 +278,7 @@ ev_tstamp ev_now (EV_P); /* time w.r.t. timers and the eventloop, updated after int ev_default_loop (int methods); /* returns true when successful */ static ev_tstamp -ev_now () +ev_now (void) { extern ev_tstamp ev_rt_now; diff --git a/ev_select.c b/ev_select.c index 7fe9084..2a87a07 100644 --- a/ev_select.c +++ b/ev_select.c @@ -29,20 +29,33 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef _WIN32 /* for unix systems */ -#if WIN32 -typedef unsigned int uint32_t; -# ifndef EV_SELECT_USE_FD_SET -# define EV_SELECT_USE_FD_SET 1 -# endif -#else # include # include #endif -#if EV_SELECT_USE_WIN32_HANDLES +#ifndef EV_SELECT_USE_FD_SET +# ifdef NFDBITS +# define EV_SELECT_USE_FD_SET 0 +# else +# define EV_SELECT_USE_FD_SET 1 +# endif +#endif + +#if EV_SELECT_IS_WINSOCKET # undef EV_SELECT_USE_FD_SET # define EV_SELECT_USE_FD_SET 1 +# undef EINTR +# define EINTR WSAEINTR +# undef EBADF +# define EBADF WSAENOTSOCK +# undef ENOMEM +# define ENOMEM (errno + 1) +#endif + +#if !EV_SELECT_USE_FD_SET +# define NFDBYTES (NFDBITS / 8) #endif #include @@ -53,78 +66,79 @@ select_modify (EV_P_ int fd, int oev, int nev) if (oev == nev) return; + { #if EV_SELECT_USE_FD_SET -# if EV_SELECT_USE_WIN32_HANDLES - fd = _get_osfhandle (fd); - if (fd < 0) - return; -# endif - if (nev & EV_READ) - FD_SET (fd, (struct fd_set *)vec_ri); - else - FD_CLR (fd, (struct fd_set *)vec_ri); + #if EV_SELECT_IS_WINSOCKET + SOCKET handle = anfds [fd].handle; + #else + 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); - if (nev & EV_WRITE) - FD_SET (fd, (struct fd_set *)vec_wi); - else - FD_CLR (fd, (struct fd_set *)vec_wi); #else - { - int offs = fd >> 3; - int mask = 1 << (fd & 7); - if (vec_max < (fd >> 5) + 1) + int word = fd / NFDBITS; + int mask = 1UL << (fd % NFDBITS); + + if (vec_max < word + 1) { - int new_max = (fd >> 5) + 1; + int new_max = word + 1; - vec_ri = (unsigned char *)ev_realloc (vec_ri, new_max * 4); - vec_ro = (unsigned char *)ev_realloc (vec_ro, new_max * 4); /* could free/malloc */ - vec_wi = (unsigned char *)ev_realloc (vec_wi, new_max * 4); - vec_wo = (unsigned char *)ev_realloc (vec_wo, new_max * 4); /* could free/malloc */ + vec_ri = ev_realloc (vec_ri, new_max * NFDBYTES); + vec_ro = ev_realloc (vec_ro, new_max * NFDBYTES); /* could free/malloc */ + vec_wi = ev_realloc (vec_wi, new_max * NFDBYTES); + vec_wo = ev_realloc (vec_wo, new_max * NFDBYTES); /* could free/malloc */ for (; vec_max < new_max; ++vec_max) - ((uint32_t *)vec_ri)[vec_max] = - ((uint32_t *)vec_wi)[vec_max] = 0; + ((fd_mask *)vec_ri)[vec_max] = + ((fd_mask *)vec_wi)[vec_max] = 0; } - vec_ri [offs] |= mask; + ((fd_mask *)vec_ri) [word] |= mask; if (!(nev & EV_READ)) - vec_ri [offs] &= ~mask; + ((fd_mask *)vec_ri) [word] &= ~mask; - vec_wi [offs] |= mask; + ((fd_mask *)vec_wi) [word] |= mask; if (!(nev & EV_WRITE)) - vec_wi [offs] &= ~mask; - } + ((fd_mask *)vec_wi) [word] &= ~mask; #endif + } } static void select_poll (EV_P_ ev_tstamp timeout) { - int word, offs; struct timeval tv; int res; #if EV_SELECT_USE_FD_SET - memcpy (vec_ro, vec_ri, sizeof (struct fd_set)); - memcpy (vec_wo, vec_wi, sizeof (struct fd_set)); + memcpy (vec_ro, vec_ri, sizeof (fd_set)); + memcpy (vec_wo, vec_wi, sizeof (fd_set)); #else - memcpy (vec_ro, vec_ri, vec_max * 4); - memcpy (vec_wo, vec_wi, vec_max * 4); + memcpy (vec_ro, vec_ri, vec_max * NFDBYTES); + memcpy (vec_wo, vec_wi, vec_max * NFDBYTES); #endif tv.tv_sec = (long)timeout; tv.tv_usec = (long)((timeout - (ev_tstamp)tv.tv_sec) * 1e6); - res = select (vec_max * 32, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv); + res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv); if (res < 0) { -#ifdef WIN32 - if (errno == WSAEINTR ) errno = EINTR; - if (errno == WSAENOTSOCK) errno = EBADF; -#endif + #if EV_SELECT_IS_WINSOCKET + errno = WSAGetLastError (); + #endif if (errno == EBADF) fd_ebadf (EV_A); @@ -137,59 +151,52 @@ select_poll (EV_P_ ev_tstamp timeout) } #if EV_SELECT_USE_FD_SET -# if EV_SELECT_USE_WIN32_HANDLES - for (word = 0; word < anfdmax; ++word) - { - if (!anfd [word].events) + + { + int fd; + + for (fd = 0; fd < anfdmax; ++fd) + if (anfds [fd].events) { - int fd = _get_osfhandle (word); + int events = 0; + #if EV_SELECT_IS_WINSOCKET + SOCKET handle = anfds [fd].handle; + #else + int handle = fd; + #endif + + if (FD_ISSET (handle, (fd_set *)vec_ro)) events |= EV_READ; + if (FD_ISSET (handle, (fd_set *)vec_wo)) events |= EV_WRITE; + + if (events) + fd_event (EV_A_ fd, events); + } + } - if (fd >= 0) +#else + + { + int word, bit; + for (word = vec_max; word--; ) + { + fd_mask word_r = ((fd_mask *)vec_ro) [word]; + fd_mask word_w = ((fd_mask *)vec_wo) [word]; + + if (word_r || word_w) + for (bit = NFDBITS; bit--; ) { + fd_mask mask = 1UL << bit; int events = 0; - if (FD_ISSET (fd, (struct fd_set *)vec_ro)) events |= EV_READ; - if (FD_ISSET (fd, (struct fd_set *)vec_wo)) events |= EV_WRITE; + events |= word_r & mask ? EV_READ : 0; + events |= word_w & mask ? EV_WRITE : 0; if (events) - fd_event (EV_A_ word, events); + fd_event (EV_A_ word * NFDBITS + bit, events); } - } - } -# else - for (word = 0; word < FD_SETSIZE; ++word) - { - int events = 0; - if (FD_ISSET (word, (struct fd_set *)vec_ro)) events |= EV_READ; - if (FD_ISSET (word, (struct fd_set *)vec_wo)) events |= EV_WRITE; + } + } - if (events) - fd_event (EV_A_ word, events); - } -# endif -#else - for (word = vec_max; word--; ) - { - if (((uint32_t *)vec_ro) [word] | ((uint32_t *)vec_wo) [word]) - for (offs = 4; offs--; ) - { - int idx = word * 4 + offs; - unsigned char byte_r = vec_ro [idx]; - unsigned char byte_w = vec_wo [idx]; - int bit; - - if (byte_r | byte_w) - for (bit = 8; bit--; ) - { - int events = 0; - events |= byte_r & (1 << bit) ? EV_READ : 0; - events |= byte_w & (1 << bit) ? EV_WRITE : 0; - - if (events) - fd_event (EV_A_ idx * 8 + bit, events); - } - } - } #endif } @@ -202,10 +209,10 @@ select_init (EV_P_ int flags) #if EV_SELECT_USE_FD_SET vec_max = FD_SETSIZE / 32; - vec_ri = ev_malloc (sizeof (struct fd_set)); FD_ZERO ((struct fd_set *)vec_ri); - vec_ro = ev_malloc (sizeof (struct fd_set)); - vec_wi = ev_malloc (sizeof (struct fd_set)); FD_ZERO ((struct fd_set *)vec_wi); - vec_wo = ev_malloc (sizeof (struct fd_set)); + vec_ri = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_ri); + vec_ro = ev_malloc (sizeof (fd_set)); + vec_wi = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_wi); + vec_wo = ev_malloc (sizeof (fd_set)); #else vec_max = 0; vec_ri = 0; diff --git a/ev_vars.h b/ev_vars.h index 77fa3d0..e73d37d 100644 --- a/ev_vars.h +++ b/ev_vars.h @@ -13,10 +13,10 @@ VARx(int, postfork) /* true if we need to recreate kernel state after fork */ VARx(int, activecnt) /* number of active events */ #if EV_USE_SELECT || EV_GENWRAP -VARx(unsigned char *, vec_ri) -VARx(unsigned char *, vec_ro) -VARx(unsigned char *, vec_wi) -VARx(unsigned char *, vec_wo) +VARx(void *, vec_ri) +VARx(void *, vec_ro) +VARx(void *, vec_wi) +VARx(void *, vec_wo) VARx(int, vec_max) #endif diff --git a/ev_win32.c b/ev_win32.c index 5821128..8357426 100644 --- a/ev_win32.c +++ b/ev_win32.c @@ -29,7 +29,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifdef WIN32 +#ifdef _WIN32 #include @@ -104,6 +104,7 @@ ev_gettimeofday (struct timeval *tv, struct timezone *tz) } #undef gettimeofday -#define gettimeofdy(tv,tz) ev_gettimeofday (tv, tz) +#define gettimeofday(tv,tz) ev_gettimeofday (tv, tz) #endif + diff --git a/event.c b/event.c index 8fed83d..5dc0da6 100644 --- a/event.c +++ b/event.c @@ -141,7 +141,7 @@ x_cb (struct event *ev, int revents) revents &= EV_READ | EV_WRITE | EV_TIMEOUT | EV_SIGNAL; ev->ev_res = revents; - ev->ev_callback (ev->ev_fd, revents, ev->ev_arg); + ev->ev_callback (ev->ev_fd, (short)revents, ev->ev_arg); } static void @@ -358,7 +358,7 @@ x_once_cb (int revents, void *arg) { struct x_once *once = (struct x_once *)arg; - once->cb (once->fd, revents, once->arg); + once->cb (once->fd, (short)revents, once->arg); free (once); } -- 2.43.0