diff options
| -rw-r--r-- | ev.c | 108 | ||||
| -rw-r--r-- | ev.h | 36 | ||||
| -rw-r--r-- | ev_select.c | 195 | ||||
| -rw-r--r-- | ev_vars.h | 8 | ||||
| -rw-r--r-- | ev_win32.c | 5 | ||||
| -rw-r--r-- | event.c | 4 | 
6 files changed, 183 insertions, 173 deletions
| @@ -77,11 +77,18 @@ extern "C" {  #include <signal.h> -#ifndef WIN32 +#ifndef _WIN32  # include <unistd.h>  # include <sys/time.h>  # include <sys/wait.h> +#else +# define WIN32_LEAN_AND_MEAN +# include <windows.h> +# 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 <winsock.h> +#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; @@ -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 <sys/select.h>  # include <inttypes.h>  #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 <string.h> @@ -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;  @@ -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 @@ -29,7 +29,7 @@   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   */ -#ifdef WIN32 +#ifdef _WIN32  #include <sys/timeb.h> @@ -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 + @@ -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);  } | 
