diff options
| author | root <root> | 2009-07-10 19:10:19 +0000 | 
|---|---|---|
| committer | root <root> | 2009-07-10 19:10:19 +0000 | 
| commit | 9a4bdcd75ef07d4a9fee91d2dd3f9d4ac1c57580 (patch) | |
| tree | 0aadce32eacc79b88ac6226d3333c3b4aea10228 | |
| parent | fe7f056cfc2dc30ab33a1e36b0005fa1e39b0e50 (diff) | |
*** empty log message ***
| -rw-r--r-- | Changes | 3 | ||||
| -rw-r--r-- | ev.c | 47 | ||||
| -rw-r--r-- | ev.h | 12 | ||||
| -rw-r--r-- | ev.pod | 5 | ||||
| -rw-r--r-- | ev_epoll.c | 4 | ||||
| -rw-r--r-- | ev_kqueue.c | 4 | ||||
| -rw-r--r-- | ev_poll.c | 4 | ||||
| -rw-r--r-- | ev_port.c | 4 | ||||
| -rw-r--r-- | ev_select.c | 4 | ||||
| -rw-r--r-- | ev_vars.h | 11 | ||||
| -rw-r--r-- | ev_wrap.h | 16 | 
11 files changed, 65 insertions, 49 deletions
| @@ -3,8 +3,11 @@ Revision history for libev, a high-performance and full-featured event loop.  TODO: ev_walk  TODO: remain  TODO: on_call_pending, on_suspend_resume ev_invoke_pending (EV_P) +TODO: EV_MINIMAL  	- ev_unloop and ev_loop wrongly used a global variable to exit loops,            instead of using a per-loop variable (bug caught by accident...). +        - calling ev_unloop in fork/prepare watchers will no longer poll +          for new events.  	- Denis F. Latypoff corrected many typos in example code snippets.  	- the ev_set_io_collect_interval interpretation has changed.          - honor autoconf detection of EV_USE_CLOCK_SYSCALL, also double- @@ -492,12 +492,15 @@ ev_realloc (void *ptr, long size)  /*****************************************************************************/ +/* set in reify when reification needed */ +#define EV_ANFD_REIFY 1 +  /* file descriptor info structure */  typedef struct  {    WL head;    unsigned char events; /* the events watched for */ -  unsigned char reify;  /* flag set when this ANFD needs reification */ +  unsigned char reify;  /* flag set when this ANFD needs reification (EV_ANFD_REIFY, EV__IOFDSET) */    unsigned char emask;  /* the epoll backend stores the actual kernel mask in here */    unsigned char unused;  #if EV_USE_EPOLL @@ -570,15 +573,17 @@ typedef struct  #endif  #if EV_MINIMAL < 2 -# define EV_SUSPEND_CB if (expect_false (suspend_cb)) suspend_cb (EV_A) -# define EV_RESUME_CB  if (expect_false (resume_cb )) resume_cb  (EV_A) +# define EV_RELEASE_CB if (expect_false (release_cb)) release_cb (EV_A) +# define EV_ACQUIRE_CB if (expect_false (acquire_cb)) acquire_cb (EV_A)  # define EV_INVOKE_PENDING invoke_cb (EV_A)  #else -# define EV_SUSPEND_CB (void)0 -# define EV_RESUME_CB  (void)0 +# define EV_RELEASE_CB (void)0 +# define EV_ACQUIRE_CB (void)0  # define EV_INVOKE_PENDING ev_invoke_pending (EV_A)  #endif +#define EVUNLOOP_RECURSE 0x80 +  /*****************************************************************************/  #ifndef EV_HAVE_EV_TIME @@ -762,7 +767,7 @@ queue_events (EV_P_ W *events, int eventcnt, int type)  /*****************************************************************************/  inline_speed void -fd_event (EV_P_ int fd, int revents) +fd_event_nc (EV_P_ int fd, int revents)  {    ANFD *anfd = anfds + fd;    ev_io *w; @@ -776,11 +781,22 @@ fd_event (EV_P_ int fd, int revents)      }  } +/* do not submit kernel events for fds that have reify set */ +/* because that means they changed while we were polling for new events */ +inline_speed void +fd_event (EV_P_ int fd, int revents) +{ +  ANFD *anfd = anfds + fd; + +  if (expect_true (!anfd->reify)) +    fd_event_nc (EV_A_ fd, revents); +} +  void  ev_feed_fd_event (EV_P_ int fd, int revents)  {    if (fd >= 0 && fd < anfdmax) -    fd_event (EV_A_ fd, revents); +    fd_event_nc (EV_A_ fd, revents);  }  /* make sure the external fd watch events are in-sync */ @@ -905,7 +921,7 @@ fd_rearm_all (EV_P)        {          anfds [fd].events = 0;          anfds [fd].emask  = 0; -        fd_change (EV_A_ fd, EV__IOFDSET | 1); +        fd_change (EV_A_ fd, EV__IOFDSET | EV_ANFD_REIFY);        }  } @@ -1411,10 +1427,10 @@ void ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P))    invoke_cb = invoke_pending_cb;  } -void ev_set_blocking_cb (EV_P_ void (*suspend_cb_)(EV_P), void (*resume_cb_)(EV_P)) +void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P))  { -  suspend_cb = suspend_cb_; -  resume_cb  = resume_cb_; +  release_cb = release; +  acquire_cb = acquire;  }  #endif @@ -2079,6 +2095,8 @@ ev_loop (EV_P_ int flags)    ++loop_depth;  #endif +  assert (("libev: ev_loop recursion during release detected", loop_done != EVUNLOOP_RECURSE)); +    loop_done = EVUNLOOP_CANCEL;    EV_INVOKE_PENDING; /* in case we recurse, ensure ordering stays nice and clean */ @@ -2115,6 +2133,9 @@ ev_loop (EV_P_ int flags)            EV_INVOKE_PENDING;          } +      if (expect_false (loop_done)) +        break; +        /* we might have forked, so reify kernel state if necessary */        if (expect_false (postfork))          loop_fork (EV_A); @@ -2174,7 +2195,9 @@ ev_loop (EV_P_ int flags)  #if EV_MINIMAL < 2          ++loop_count;  #endif +        assert ((loop_done = EVUNLOOP_RECURSE, 1)); /* assert for side effect */          backend_poll (EV_A_ waittime); +        assert ((loop_done = EVUNLOOP_CANCEL, 1)); /* assert for side effect */          /* update ev_rt_now, do magic */          time_update (EV_A_ waittime + sleeptime); @@ -2350,7 +2373,7 @@ ev_io_start (EV_P_ ev_io *w)    array_needsize (ANFD, anfds, anfdmax, fd + 1, array_init_zero);    wlist_add (&anfds[fd].head, (WL)w); -  fd_change (EV_A_ fd, w->events & EV__IOFDSET | 1); +  fd_change (EV_A_ fd, w->events & EV__IOFDSET | EV_ANFD_REIFY);    w->events &= ~EV__IOFDSET;    EV_FREQUENT_CHECK; @@ -547,19 +547,11 @@ void         ev_loop_verify (EV_P); /* abort if loop data corrupted */  void ev_set_io_collect_interval (EV_P_ ev_tstamp interval); /* sleep at least this time, default 0 */  void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval); /* sleep at least this time, default 0 */ -/* - * a single void * can be attached to each loop. this is intended - * to aid the invoke_pending/blocking callbacks. - */ +/* advanced stuff for threading etc. support, see docs */  void ev_set_userdata (EV_P_ void *data);  void *ev_userdata (EV_P); - -/* - * hooks to overide how and when libev invokes callbacks, - * and hooks that wrap the actual eventloop blocking call. - */  void ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P)); -void ev_set_blocking_cb (EV_P_ void (*suspend_cb_)(EV_P), void (*resume_cb_)(EV_P)); +void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P));  void ev_invoke_pending (EV_P); /* invoke all pending watchers */ @@ -3678,8 +3678,9 @@ is used to override some inlining decisions, saves roughly 30% code size  on amd64. It also selects a much smaller 2-heap for timer management over  the default 4-heap. -You can save even more by disabling watcher types you do not need and -setting C<EV_MAXPRI> == C<EV_MINPRI>. +You can save even more by disabling watcher types you do not need +and setting C<EV_MAXPRI> == C<EV_MINPRI>. Also, disabling C<assert> +(C<-DNDEBUG>) will usually reduce code size a lot.  Defining C<EV_MINIMAL> to C<2> will additionally reduce the core API to  provide a bare-bones event library. See C<ev.h> for details on what parts @@ -121,9 +121,9 @@ epoll_poll (EV_P_ ev_tstamp timeout)    int i;    int eventcnt; -  EV_SUSPEND_CB; +  EV_RELEASE_CB;    eventcnt = epoll_wait (backend_fd, epoll_events, epoll_eventmax, (int)ceil (timeout * 1000.)); -  EV_RESUME_CB; +  EV_ACQUIRE_CB;    if (expect_false (eventcnt < 0))      { diff --git a/ev_kqueue.c b/ev_kqueue.c index 2a9832f..ac73f7c 100644 --- a/ev_kqueue.c +++ b/ev_kqueue.c @@ -85,7 +85,7 @@ kqueue_poll (EV_P_ ev_tstamp timeout)    int res, i;    struct timespec ts; -  EV_SUSPEND_CB; +  EV_RELEASE_CB;    /* need to resize so there is enough space for errors */    if (kqueue_changecnt > kqueue_eventmax) @@ -100,7 +100,7 @@ kqueue_poll (EV_P_ ev_tstamp timeout)    res = kevent (backend_fd, kqueue_changes, kqueue_changecnt, kqueue_events, kqueue_eventmax, &ts);    kqueue_changecnt = 0; -  EV_RESUME_CB; +  EV_ACQUIRE_CB;    if (expect_false (res < 0))      {  @@ -91,9 +91,9 @@ poll_poll (EV_P_ ev_tstamp timeout)    struct pollfd *p;    int res; -  EV_SUSPEND_CB; +  EV_RELEASE_CB;    res = poll (polls, pollcnt, (int)ceil (timeout * 1000.)); -  EV_RESUME_CB; +  EV_ACQUIRE_CB;    if (expect_false (res < 0))      { @@ -85,11 +85,11 @@ port_poll (EV_P_ ev_tstamp timeout)    struct timespec ts;    uint_t nget = 1; -  EV_SUSPEND_CB; +  EV_RELEASE_CB;    ts.tv_sec  = (time_t)timeout;    ts.tv_nsec = (long)(timeout - (ev_tstamp)ts.tv_sec) * 1e9;    res = port_getn (backend_fd, port_events, port_eventmax, &nget, &ts); -  EV_RESUME_CB; +  EV_ACQUIRE_CB;    if (res == -1)      {  diff --git a/ev_select.c b/ev_select.c index b7bb69d..e57c1e2 100644 --- a/ev_select.c +++ b/ev_select.c @@ -140,7 +140,7 @@ select_poll (EV_P_ ev_tstamp timeout)    int res;    int fd_setsize; -  EV_SUSPEND_CB; +  EV_RELEASE_CB;    tv.tv_sec  = (long)timeout;    tv.tv_usec = (long)((timeout - (ev_tstamp)tv.tv_sec) * 1e6); @@ -167,7 +167,7 @@ select_poll (EV_P_ ev_tstamp timeout)  #else    res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);  #endif -  EV_RESUME_CB; +  EV_ACQUIRE_CB;    if (expect_false (res < 0))      { @@ -48,7 +48,7 @@ VARx(ev_tstamp, timeout_blocktime)  VARx(int, backend)  VARx(int, activecnt) /* total number of active events ("refcount") */ -VARx(char, loop_done)  /* signal by ev_unloop */ +VARx(unsigned char, loop_done)  /* signal by ev_unloop */  VARx(int, backend_fd)  VARx(ev_tstamp, backend_fudge) /* assumed typical timer resolution */ @@ -166,16 +166,13 @@ VARx(char, fs_2625) /* whether we are running in linux 2.6.25 or newer */  VAR (fs_hash, ANFS fs_hash [EV_INOTIFY_HASHSIZE])  #endif -#if EV_MINIMAL < 2 +#if EV_MINIMAL < 2 || EV_GENWRAP  VARx(unsigned int, loop_count) /* total number of loop iterations/blocks */  VARx(unsigned int, loop_depth) /* #ev_loop enters - #ev_loop leaves */  VARx(void *, userdata) -#endif - -#if EV_MINIMAL < 2 -VAR (suspend_cb, void (*suspend_cb)(EV_P)) -VAR (resume_cb , void (*resume_cb) (EV_P)) +VAR (release_cb, void (*release_cb)(EV_P)) +VAR (acquire_cb, void (*acquire_cb)(EV_P))  VAR (invoke_cb , void (*invoke_cb) (EV_P))  #endif @@ -8,8 +8,6 @@  #define timeout_blocktime ((loop)->timeout_blocktime)  #define backend ((loop)->backend)  #define activecnt ((loop)->activecnt) -#define loop_count ((loop)->loop_count) -#define loop_depth ((loop)->loop_depth)  #define loop_done ((loop)->loop_done)  #define backend_fd ((loop)->backend_fd)  #define backend_fudge ((loop)->backend_fudge) @@ -79,9 +77,11 @@  #define fs_w ((loop)->fs_w)  #define fs_2625 ((loop)->fs_2625)  #define fs_hash ((loop)->fs_hash) +#define loop_count ((loop)->loop_count) +#define loop_depth ((loop)->loop_depth)  #define userdata ((loop)->userdata) -#define suspend_cb ((loop)->suspend_cb) -#define resume_cb ((loop)->resume_cb) +#define release_cb ((loop)->release_cb) +#define acquire_cb ((loop)->acquire_cb)  #define invoke_cb ((loop)->invoke_cb)  #else  #undef EV_WRAP_H @@ -92,8 +92,6 @@  #undef timeout_blocktime  #undef backend  #undef activecnt -#undef loop_count -#undef loop_depth  #undef loop_done  #undef backend_fd  #undef backend_fudge @@ -163,8 +161,10 @@  #undef fs_w  #undef fs_2625  #undef fs_hash +#undef loop_count +#undef loop_depth  #undef userdata -#undef suspend_cb -#undef resume_cb +#undef release_cb +#undef acquire_cb  #undef invoke_cb  #endif | 
