diff options
| -rw-r--r-- | ev.c | 113 | ||||
| -rw-r--r-- | ev.h | 28 | ||||
| -rw-r--r-- | ev_select.c | 6 | ||||
| -rw-r--r-- | ev_vars.h | 124 | ||||
| -rw-r--r-- | ev_wrap.h | 55 | ||||
| -rw-r--r-- | event.c | 48 | ||||
| -rw-r--r-- | event.h | 4 | ||||
| -rwxr-xr-x | update_ev_wrap | 10 | 
8 files changed, 259 insertions, 129 deletions
@@ -115,6 +115,8 @@ 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? */ +  /*****************************************************************************/  typedef struct @@ -131,16 +133,22 @@ typedef struct  } ANPENDING;  #ifdef EV_MULTIPLICITY +  struct ev_loop  { -# define VAR(name,decl) decl +# define VAR(name,decl) decl;  # include "ev_vars.h"  }; +# undef VAR +# include "ev_wrap.h" +  #else -# define VAR(name,decl) static decl + +# define VAR(name,decl) static decl;  # include "ev_vars.h" +# undef VAR +  #endif -#undef VAR  /*****************************************************************************/ @@ -335,44 +343,44 @@ fd_enomem (EV_P)  /*****************************************************************************/  static void -upheap (WT *timers, int k) +upheap (WT *heap, int k)  { -  WT w = timers [k]; +  WT w = heap [k]; -  while (k && timers [k >> 1]->at > w->at) +  while (k && heap [k >> 1]->at > w->at)      { -      timers [k] = timers [k >> 1]; -      timers [k]->active = k + 1; +      heap [k] = heap [k >> 1]; +      heap [k]->active = k + 1;        k >>= 1;      } -  timers [k] = w; -  timers [k]->active = k + 1; +  heap [k] = w; +  heap [k]->active = k + 1;  }  static void -downheap (WT *timers, int N, int k) +downheap (WT *heap, int N, int k)  { -  WT w = timers [k]; +  WT w = heap [k];    while (k < (N >> 1))      {        int j = k << 1; -      if (j + 1 < N && timers [j]->at > timers [j + 1]->at) +      if (j + 1 < N && heap [j]->at > heap [j + 1]->at)          ++j; -      if (w->at <= timers [j]->at) +      if (w->at <= heap [j]->at)          break; -      timers [k] = timers [j]; -      timers [k]->active = k + 1; +      heap [k] = heap [j]; +      heap [k]->active = k + 1;        k = j;      } -  timers [k] = w; -  timers [k]->active = k + 1; +  heap [k] = w; +  heap [k]->active = k + 1;  }  /*****************************************************************************/ @@ -447,7 +455,7 @@ siginit (EV_P)  #endif    ev_io_set (&sigev, sigpipe [0], EV_READ); -  ev_io_start (&sigev); +  ev_io_start (EV_A_ &sigev);    ev_unref (EV_A); /* child watcher should not keep loop alive */  } @@ -536,13 +544,9 @@ ev_method (EV_P)    return method;  } -int -ev_init (EV_P_ int methods) +static void +loop_init (EV_P_ int methods)  { -#ifdef EV_MULTIPLICITY -  memset (loop, 0, sizeof (struct ev_loop)); -#endif -    if (!method)      {  #if EV_USE_MONOTONIC @@ -556,7 +560,7 @@ ev_init (EV_P_ int methods)        rt_now    = ev_time ();        mn_now    = get_clock ();        now_floor = mn_now; -      diff      = rt_now - mn_now; +      rtmn_diff = rt_now - mn_now;        if (pipe (sigpipe))          return 0; @@ -599,6 +603,35 @@ ev_init (EV_P_ int methods)    return method;  } +#ifdef EV_MULTIPLICITY + +struct ev_loop * +ev_loop_new (int methods) +{ +  struct ev_loop *loop = (struct ev_loop *)calloc (1, sizeof (struct ev_loop)); + +  loop_init (EV_A_ methods); + +  return loop; +} + +void +ev_loop_delete (EV_P) +{ +  /*TODO*/ +  free (loop); +} + +#else + +int +ev_init (int methods) +{ +  loop_init (); +} + +#endif +  /*****************************************************************************/  void @@ -616,16 +649,19 @@ ev_fork_parent (void)  void  ev_fork_child (void)  { +  /*TODO*/ +#if !EV_MULTIPLICITY  #if EV_USE_EPOLL    if (method == EVMETHOD_EPOLL) -    epoll_postfork_child (); +    epoll_postfork_child (EV_A);  #endif -  ev_io_stop (&sigev); +  ev_io_stop (EV_A_ &sigev);    close (sigpipe [0]);    close (sigpipe [1]);    pipe (sigpipe); -  siginit (); +  siginit (EV_A); +#endif  }  /*****************************************************************************/ @@ -665,7 +701,7 @@ timers_reify (EV_P)        else          ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */ -      event ((W)w, EV_TIMEOUT); +      event (EV_A_ (W)w, EV_TIMEOUT);      }  } @@ -691,7 +727,7 @@ periodics_reify (EV_P)  }  static void -periodics_reschedule (EV_P_ ev_tstamp diff) +periodics_reschedule (EV_P)  {    int i; @@ -722,7 +758,7 @@ time_update_monotonic (EV_P)    if (expect_true (mn_now - now_floor < MIN_TIMEJUMP * .5))      { -      rt_now = mn_now + diff; +      rt_now = rtmn_diff + mn_now;        return 0;      }    else @@ -743,13 +779,13 @@ time_update (EV_P)      {        if (time_update_monotonic (EV_A))          { -          ev_tstamp odiff = diff; +          ev_tstamp odiff = rtmn_diff;            for (i = 4; --i; ) /* loop a few times, before making important decisions */              { -              diff = rt_now - mn_now; +              rtmn_diff = rt_now - mn_now; -              if (fabs (odiff - diff) < MIN_TIMEJUMP) +              if (fabs (odiff - rtmn_diff) < MIN_TIMEJUMP)                  return; /* all is well */                rt_now    = ev_time (); @@ -757,8 +793,9 @@ time_update (EV_P)                now_floor = mn_now;              } -          periodics_reschedule (EV_A_ diff - odiff); +          periodics_reschedule (EV_A);            /* no timer adjustment, as the monotonic clock doesn't jump */ +          /* timers_reschedule (EV_A_ rtmn_diff - odiff) */          }      }    else @@ -768,11 +805,11 @@ time_update (EV_P)        if (expect_false (mn_now > rt_now || mn_now < rt_now - MAX_BLOCKTIME - MIN_TIMEJUMP))          { -          periodics_reschedule (EV_A_ rt_now - mn_now); +          periodics_reschedule (EV_A);            /* adjust timers. this is easy, as the offset is the same for all */            for (i = 0; i < timercnt; ++i) -            timers [i]->at += diff; +            timers [i]->at += rt_now - mn_now;          }        mn_now = rt_now; @@ -44,8 +44,12 @@ typedef double ev_tstamp;  # define EV_MAXPRI +2  #endif +#ifndef EV_MULTIPLICITY +# define EV_MULTIPLICITY 1 +#endif +  /* support multiple event loops? */ -#ifdef EV_MULTIPLICITY +#if EV_MULTIPLICITY  struct ev_loop;  # define EV_P struct ev_loop *loop  # define EV_P_ EV_P, @@ -56,7 +60,6 @@ struct ev_loop;  # define EV_P_  # define EV_A  # define EV_A_ -  #endif  /* eventmask, revents, events... */ @@ -155,6 +158,9 @@ struct ev_io  struct ev_signal  {    EV_WATCHER_LIST (ev_signal); +#if EV_MULTIPLICITY +  struct ev_loop *loop; +#endif    int signum; /* ro */  }; @@ -201,9 +207,8 @@ struct ev_child  #define EVMETHOD_DEVPOLL 16 /* NYI */  #define EVMETHOD_PORT    32 /* NYI */  #define EVMETHOD_ANY     ~0 /* any method, do not consult env */ +  #if EV_PROTOTYPES -int ev_method (EV_P); -int ev_init (EV_P_ int methods); /* returns ev_method */  int ev_version_major (void);  int ev_version_minor (void); @@ -213,13 +218,26 @@ void ev_fork_parent (void);  void ev_fork_child (void);  ev_tstamp ev_time (void); + +# if EV_MULTIPLICITY +struct ev_loop *ev_loop_new (int methods); +void ev_loop_delete (EV_P); +# else +int ev_init (int methods); /* returns ev_method */ +# endif + +int ev_method (EV_P); +  #endif  #define EVLOOP_NONBLOCK	1 /* do not block/wait */  #define EVLOOP_ONESHOT	2 /* block *once* only */ +#define EVUNLOOP_ONCE   1 /* unloop once */ +#define EVUNLOOP_ALL    2 /* unloop all loops */ +  #if EV_PROTOTYPES  void ev_loop (EV_P_ int flags); -void ev_unloop (EV_P_ int status); /* set to 1 to break out of event loop, set to 2 to break out of all event loops */ +void ev_unloop (EV_P_ int how); /* set to 1 to break out of event loop, set to 2 to break out of all event loops */  ev_tstamp ev_now (EV_P); /* time w.r.t. timers and the eventloop, updated after each poll */ diff --git a/ev_select.c b/ev_select.c index 05dc30a..5738fe5 100644 --- a/ev_select.c +++ b/ev_select.c @@ -107,7 +107,7 @@ select_poll (EV_P_ ev_tstamp timeout)                        events |= byte_w & (1 << bit) ? EV_WRITE : 0;                        if (events) -                        fd_event (idx * 8 + bit, events); +                        fd_event (EV_A_ idx * 8 + bit, events);                      }                }          } @@ -115,9 +115,9 @@ select_poll (EV_P_ ev_tstamp timeout)    else if (res < 0)      {        if (errno == EBADF) -        fd_ebadf (); +        fd_ebadf (EV_A);        else if (errno == ENOMEM) -        fd_enomem (); +        fd_enomem (EV_A);      }  } @@ -1,86 +1,84 @@  #define VARx(type,name) VAR(name, type name) -VARx(ev_tstamp, now_floor); /* last time we refreshed rt_time */ -VARx(ev_tstamp, mn_now);    /* monotonic clock "now" */ -VARx(ev_tstamp, rt_now); -VARx(ev_tstamp, diff);      /* difference realtime - monotonic time */ -VARx(int, method); - -VARx(int, have_monotonic); /* runtime */ - -VARx(ev_tstamp, method_fudge); /* assumed typical timer resolution */ -VAR (method_modify, void (*method_modify)(EV_P_ int fd, int oev, int nev)); -VAR (method_poll  , void (*method_poll)(EV_P_ ev_tstamp timeout)); - -VARx(int, activecnt); /* number of active events */ - -#if EV_USE_SELECT -VARx(unsigned char *, vec_ri); -VARx(unsigned char *, vec_ro); -VARx(unsigned char *, vec_wi); -VARx(unsigned char *, vec_wo); -VARx(int, vec_max); +VARx(ev_tstamp, now_floor) /* last time we refreshed rt_time */ +VARx(ev_tstamp, mn_now)    /* monotonic clock "now" */ +VARx(ev_tstamp, rt_now) +VARx(ev_tstamp, rtmn_diff)      /* difference realtime - monotonic time */ +VARx(int, method) + +VARx(ev_tstamp, method_fudge) /* assumed typical timer resolution */ +VAR (method_modify, void (*method_modify)(EV_P_ int fd, int oev, int nev)) +VAR (method_poll  , void (*method_poll)(EV_P_ ev_tstamp timeout)) + +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(int, vec_max)  #endif -#if EV_USEV_POLL -VARx(struct pollfd *, polls); -VARx(int, pollmax); -VARx(int, pollcnt); -VARx(int *, pollidxs); /* maps fds into structure indices */ -VARx(int, pollidxmax); +#if EV_USE_POLL || EV_GENWRAP +VARx(struct pollfd *, polls) +VARx(int, pollmax) +VARx(int, pollcnt) +VARx(int *, pollidxs) /* maps fds into structure indices */ +VARx(int, pollidxmax)  #endif -#if EV_USE_EPOLL -VARx(int, epoll_fd); +#if EV_USE_EPOLL || EV_GENWRAP +VARx(int, epoll_fd) -VARx(struct epoll_event *, events); -VARx(int, eventmax); +VARx(struct epoll_event *, epoll_events) +VARx(int, epoll_eventmax)  #endif -#if EV_USE_KQUEUE -VARx(int, kqueue_fd); -VARx(struct kevent *, kqueue_changes); -VARx(int, kqueue_changemax); -VARx(int, kqueue_changecnt); -VARx(struct kevent *, kqueue_events); -VARx(int, kqueue_eventmax); +#if EV_USE_KQUEUE || EV_GENWRAP +VARx(int, kqueue_fd) +VARx(struct kevent *, kqueue_changes) +VARx(int, kqueue_changemax) +VARx(int, kqueue_changecnt) +VARx(struct kevent *, kqueue_events) +VARx(int, kqueue_eventmax)  #endif -VARx(ANFD *, anfds); -VARx(int, anfdmax); +VARx(ANFD *, anfds) +VARx(int, anfdmax) -VAR (pendings, ANPENDING *pendings [NUMPRI]); -VAR (pendingmax, int pendingmax [NUMPRI]); -VAR (pendingcnt, int pendingcnt [NUMPRI]); +VAR (pendings, ANPENDING *pendings [NUMPRI]) +VAR (pendingmax, int pendingmax [NUMPRI]) +VAR (pendingcnt, int pendingcnt [NUMPRI]) -VARx(int *, fdchanges); -VARx(int, fdchangemax); -VARx(int, fdchangecnt); +VARx(int *, fdchanges) +VARx(int, fdchangemax) +VARx(int, fdchangecnt) -VARx(struct ev_timer **, timers); -VARx(int, timermax); -VARx(int, timercnt); +VARx(struct ev_timer **, timers) +VARx(int, timermax) +VARx(int, timercnt) -VARx(struct ev_periodic **, periodics); -VARx(int, periodicmax); -VARx(int, periodiccnt); +VARx(struct ev_periodic **, periodics) +VARx(int, periodicmax) +VARx(int, periodiccnt) -VARx(struct ev_idle **, idles); -VARx(int, idlemax); -VARx(int, idlecnt); +VARx(struct ev_idle **, idles) +VARx(int, idlemax) +VARx(int, idlecnt) -VARx(struct ev_prepare **, prepares); -VARx(int, preparemax); -VARx(int, preparecnt); +VARx(struct ev_prepare **, prepares) +VARx(int, preparemax) +VARx(int, preparecnt) -VARx(struct ev_check **, checks); -VARx(int, checkmax); -VARx(int, checkcnt); +VARx(struct ev_check **, checks) +VARx(int, checkmax) +VARx(int, checkcnt) -VAR (childs, struct ev_child *childs [PID_HASHSIZE]); -VARx(struct ev_signal, childev); +VAR (childs, struct ev_child *childs [PID_HASHSIZE]) +VARx(struct ev_signal, childev) -VARx(struct ev_io, sigev); +VARx(struct ev_io, sigev)  #undef VARx diff --git a/ev_wrap.h b/ev_wrap.h new file mode 100644 index 0000000..379ed74 --- /dev/null +++ b/ev_wrap.h @@ -0,0 +1,55 @@ +/* DO NOT EDIT, automaticlaly generated by update_ev_wrap */ +#define now_floor ((loop)->now_floor) +#define mn_now ((loop)->mn_now) +#define rt_now ((loop)->rt_now) +#define rtmn_diff ((loop)->rtmn_diff) +#define method ((loop)->method) +#define method_fudge ((loop)->method_fudge) +#define method_modify ((loop)->method_modify) +#define method_poll ((loop)->method_poll) +#define activecnt ((loop)->activecnt) +#define vec_ri ((loop)->vec_ri) +#define vec_ro ((loop)->vec_ro) +#define vec_wi ((loop)->vec_wi) +#define vec_wo ((loop)->vec_wo) +#define vec_max ((loop)->vec_max) +#define polls ((loop)->polls) +#define pollmax ((loop)->pollmax) +#define pollcnt ((loop)->pollcnt) +#define pollidxs ((loop)->pollidxs) +#define pollidxmax ((loop)->pollidxmax) +#define epoll_fd ((loop)->epoll_fd) +#define epoll_events ((loop)->epoll_events) +#define epoll_eventmax ((loop)->epoll_eventmax) +#define kqueue_fd ((loop)->kqueue_fd) +#define kqueue_changes ((loop)->kqueue_changes) +#define kqueue_changemax ((loop)->kqueue_changemax) +#define kqueue_changecnt ((loop)->kqueue_changecnt) +#define kqueue_events ((loop)->kqueue_events) +#define kqueue_eventmax ((loop)->kqueue_eventmax) +#define anfds ((loop)->anfds) +#define anfdmax ((loop)->anfdmax) +#define pendings ((loop)->pendings) +#define pendingmax ((loop)->pendingmax) +#define pendingcnt ((loop)->pendingcnt) +#define fdchanges ((loop)->fdchanges) +#define fdchangemax ((loop)->fdchangemax) +#define fdchangecnt ((loop)->fdchangecnt) +#define timers ((loop)->timers) +#define timermax ((loop)->timermax) +#define timercnt ((loop)->timercnt) +#define periodics ((loop)->periodics) +#define periodicmax ((loop)->periodicmax) +#define periodiccnt ((loop)->periodiccnt) +#define idles ((loop)->idles) +#define idlemax ((loop)->idlemax) +#define idlecnt ((loop)->idlecnt) +#define prepares ((loop)->prepares) +#define preparemax ((loop)->preparemax) +#define preparecnt ((loop)->preparecnt) +#define checks ((loop)->checks) +#define checkmax ((loop)->checkmax) +#define checkcnt ((loop)->checkcnt) +#define childs ((loop)->childs) +#define childev ((loop)->childev) +#define sigev ((loop)->sigev) @@ -35,19 +35,17 @@  #include "event.h" -#ifdef EV_MULTIPLICITY -# define dLOOPev struct ev_loop *loop = ev->ev_base->loop -# define dLOOPbase struct ev_loop *loop = base->loop +#if EV_MULTIPLICITY +# define dLOOPev struct ev_loop *loop = (struct ev_loop *)ev->ev_base +# define dLOOPbase struct ev_loop *loop = (struct ev_loop *)base  #else  # define dLOOPev  # define dLOOPbase  #endif +/* never accessed, will always be cast from/to ev_loop */  struct event_base  { -#ifdef EV_MULTIPLICITY -  struct ev_loop *loop; -#endif    int dummy;  }; @@ -83,17 +81,22 @@ const char *event_get_method (void)  void *event_init (void)  { -  if (!x_cur && ev_init (0)) -    return x_cur = &x_base; +#if EV_MULTIPLICITY +  x_cur = (struct event_base *)ev_loop_new (EVMETHOD_AUTO); +#else +  x_cur = &x_base; +#endif -  return 0; +  return x_cur;  }  void event_base_free (struct event_base *base)  {    dLOOPbase; -  /* nop */ +#if EV_MULTIPLICITY +  ev_loop_delete (loop); +#endif  }  int event_dispatch (void) @@ -139,7 +142,7 @@ x_cb_io (EV_P_ struct ev_io *w, int revents)    struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, iosig.io));    if (!(ev->ev_events & EV_PERSIST) && ev_is_active (w)) -    ev_io_stop (w); +    ev_io_stop (EV_A_ w);    x_cb (ev, revents);  } @@ -152,14 +155,19 @@ x_cb_to (EV_P_ struct ev_timer *w, int revents)  void event_set (struct event *ev, int fd, short events, void (*cb)(int, short, void *), void *arg)  { -  if (events & EV_SIGNAL) -    ev_watcher_init (&ev->iosig.sig, x_cb_sig); -  else -    ev_watcher_init (&ev->iosig.io, x_cb_io); +  if (!ev->initialised) +    { +      ev->initialised = 1; + +      if (events & EV_SIGNAL) +        ev_watcher_init (&ev->iosig.sig, x_cb_sig); +      else +        ev_watcher_init (&ev->iosig.io, x_cb_io); -  ev_watcher_init (&ev->to, x_cb_to); +      ev_watcher_init (&ev->to, x_cb_to); +    } -  ev->ev_base     = x_cur; +  ev->ev_base     = x_cur; /* not threadsafe, but its like libevent works */    ev->ev_fd       = fd;    ev->ev_events   = events;    ev->ev_pri      = 0; @@ -287,9 +295,11 @@ int event_base_dispatch (struct event_base *base)  }  static void -x_loopexit_cb (EV_P_ int revents, void *arg) +x_loopexit_cb (int revents, void *base)  { -  ev_unloop (EV_A_ 2); +  dLOOPbase; + +  ev_unloop (EV_A_ EVUNLOOP_ONCE);  }  int event_base_loopexit (struct event_base *base, struct timeval *tv) @@ -54,6 +54,8 @@ struct event    int ev_pri;    int ev_res;    short ev_events; + +  char initialised; /* flag to work around some idiosynchrasies in the API */  };  #define EV_PERSIST                 0x10 @@ -61,7 +63,7 @@ struct event  #define EVENT_SIGNAL(ev)           ((int) (ev)->ev_fd)  #define EVENT_FD(ev)               ((int) (ev)->ev_fd) -#define event_initialized(ev)      1 +#define event_initialized(ev)      ((ev)->initialised)  #define evtimer_add(ev,tv)         event_add (ev, tv)  #define evtimer_set(ev,cb,data)    event_set (ev, -1, 0, cb, data) diff --git a/update_ev_wrap b/update_ev_wrap new file mode 100755 index 0000000..32ab625 --- /dev/null +++ b/update_ev_wrap @@ -0,0 +1,10 @@ +#!/bin/sh + +( +   echo '#define VAR(name,decl) define name ((loop)->name)' +   echo '#define EV_GENWRAP 1' +   cat ev_vars.h +) | cc -E -o - - | sed -e 's/define/#define/' | grep '#define' | ( +   echo "/* DO NOT EDIT, automaticlaly generated by update_ev_wrap */" +   cat +) | tee ev_wrap.h  | 
