diff options
-rw-r--r-- | Changes | 9 | ||||
-rw-r--r-- | ev++.h | 9 | ||||
-rw-r--r-- | ev.c | 61 | ||||
-rw-r--r-- | ev.h | 17 | ||||
-rw-r--r-- | ev.pod | 12 |
5 files changed, 44 insertions, 64 deletions
@@ -1,8 +1,9 @@ Revision history for libev, a high-performance and full-featured event loop. TODO: include ev_xyz_start in each example? -TODO: ev_pdef stupid idea? -TODO: EVRUN_XXX? +TODO: which supports signals and child events +TODO: pointer races +TODO: ev_default_destroy, ev_default_fork - "PORTING FROM LIBEV 3.X TO 4.X" (in ev.pod) is recommended reading. - ev_embed_stop did not correctly stop the watcher (very good testcase by Vladimir Timofeev). @@ -14,6 +15,8 @@ TODO: EVRUN_XXX? - replace EV_MINIMAL by EV_FEATURES. - prefer EPOLL_CTL_ADD over EPOLL_CTL_MOD in some more cases, as it seems the former is *much* faster than the latter. + - linux kernel version detection (for inotify bug workarounds) + did not work properly. - reduce the number of spurious wake-ups with the ports backend. - remove dependency on sys/queue.h on freebsd (patch by Vanilla Hsu). - do async init within ev_async_start, not ev_async_set, which avoids @@ -42,6 +45,7 @@ TODO: EVRUN_XXX? - add section on accept() problems to the manpage. - rename EV_TIMEOUT to EV_TIMER. - rename ev_loop_count/depth/verify/loop/unloop. + - remove ev_default_destroy and ev_default_fork. - switch to two-digit minor version. - work around an apparent gentoo compiler bug. - define _DARWIN_UNLIMITED_SELECT. just so. @@ -50,6 +54,7 @@ TODO: EVRUN_XXX? - (experimental) ev_run/ev_default_loop/ev_break/ev_loop_new have now default arguments when compiled as C++. - enable automake dependency tracking. + - ev_loop_new no longer leaks memory when loop creation failed. 3.9 Thu Dec 31 07:59:59 CET 2009 - signalfd is no longer used by default and has to be requested @@ -219,11 +219,7 @@ namespace ev { void post_fork () throw () { -#if EV_MULTIPLICITY ev_loop_fork (EV_AX); -#else - ev_default_fork (); -#endif } unsigned int backend () const throw () @@ -396,11 +392,6 @@ namespace ev { throw bad_loop (); } - ~default_loop () throw () - { - ev_default_destroy (); - } - private: default_loop (const default_loop &); default_loop &operator = (const default_loop &); @@ -532,8 +532,8 @@ static unsigned int noinline ev_linux_version (void) { #ifdef __linux + unsigned int v = 0; struct utsname buf; - unsigned int v; int i; char *p = buf.release; @@ -1733,11 +1733,19 @@ loop_init (EV_P_ unsigned int flags) } /* free up a loop structure */ -static void noinline -loop_destroy (EV_P) +void +ev_loop_destroy (EV_P) { int i; +#if EV_CHILD_ENABLE + if (ev_is_active (&childev)) + { + ev_ref (EV_A); /* child watcher */ + ev_signal_stop (EV_A_ &childev); + } +#endif + if (ev_is_active (&pipe_w)) { /*ev_ref (EV_A);*/ @@ -1814,6 +1822,15 @@ loop_destroy (EV_P) #endif backend = 0; + +#if EV_MULTIPLICITY + if (ev_is_default_loop (EV_A)) +#endif + ev_default_loop_ptr = 0; +#if EV_MULTIPLICITY + else + ev_free (EV_A); +#endif } #if EV_USE_INOTIFY @@ -1882,21 +1899,10 @@ ev_loop_new (unsigned int flags) if (ev_backend (EV_A)) return EV_A; + ev_free (EV_A); return 0; } -void -ev_loop_destroy (EV_P) -{ - loop_destroy (EV_A); - ev_free (loop); -} - -void -ev_loop_fork (EV_P) -{ - postfork = 1; /* must be in line with ev_default_fork */ -} #endif /* multiplicity */ #if EV_VERIFY @@ -2040,30 +2046,9 @@ ev_default_loop (unsigned int flags) } void -ev_default_destroy (void) -{ -#if EV_MULTIPLICITY - EV_P = ev_default_loop_ptr; -#endif - - ev_default_loop_ptr = 0; - -#if EV_CHILD_ENABLE - ev_ref (EV_A); /* child watcher */ - ev_signal_stop (EV_A_ &childev); -#endif - - loop_destroy (EV_A); -} - -void -ev_default_fork (void) +ev_loop_fork (EV_P) { -#if EV_MULTIPLICITY - EV_P = ev_default_loop_ptr; -#endif - - postfork = 1; /* must be in line with ev_loop_fork */ + postfork = 1; /* must be in line with ev_default_fork */ } /*****************************************************************************/ @@ -158,7 +158,7 @@ struct ev_loop; # define EV_P_ EV_P, /* a loop as first of multiple parameters */ # define EV_A loop /* a loop as sole argument to a function call */ # define EV_A_ EV_A, /* a loop as first of multiple arguments */ -# define EV_DEFAULT_UC ev_default_loop_uc () /* the default loop, if initialised, as sole arg */ +# define EV_DEFAULT_UC ev_default_loop_uc_ () /* the default loop, if initialised, as sole arg */ # define EV_DEFAULT_UC_ EV_DEFAULT_UC, /* the default loop as first of multiple arguments */ # define EV_DEFAULT ev_default_loop (0) /* the default loop as sole arg */ # define EV_DEFAULT_ EV_DEFAULT, /* the default loop as first of multiple arguments */ @@ -516,7 +516,7 @@ void ev_set_syserr_cb (void (*cb)(const char *msg)); struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0)); EV_INLINE struct ev_loop * -ev_default_loop_uc (void) +ev_default_loop_uc_ (void) { extern struct ev_loop *ev_default_loop_ptr; @@ -526,13 +526,13 @@ ev_default_loop_uc (void) EV_INLINE int ev_is_default_loop (EV_P) { - return EV_A == ev_default_loop_uc (); + return EV_A == EV_DEFAULT_UC; } /* create and destroy alternative loops that don't handle signals */ struct ev_loop *ev_loop_new (unsigned int flags EV_CPP (= 0)); +/* destroy event loops, also works for the default loop */ void ev_loop_destroy (EV_P); -void ev_loop_fork (EV_P); ev_tstamp ev_now (EV_P); /* time w.r.t. timers and the eventloop, updated after each poll */ @@ -557,12 +557,11 @@ ev_is_default_loop (void) #endif /* multiplicity */ -void ev_default_destroy (void); /* destroy the default loop */ -/* this needs to be called after fork, to duplicate the default loop */ -/* if you create alternative loops you have to call ev_loop_fork on them */ +/* this needs to be called after fork, to duplicate the loop */ +/* when you want to re-use it in the child */ /* you can call it in either the parent or the child */ /* you can actually call it at any time, anywhere :) */ -void ev_default_fork (void); +void ev_loop_fork (EV_P); unsigned int ev_backend (EV_P); /* backend in use by loop */ @@ -778,6 +777,8 @@ void ev_async_send (EV_P_ ev_async *w); #if EV_PROTOTYPES EV_INLINE void ev_loop (EV_P_ int flags) { ev_run (EV_A_ flags); } EV_INLINE void ev_unloop (EV_P_ int how ) { ev_break (EV_A_ how ); } + EV_INLINE void ev_default_destroy (void) { ev_loop_destroy (EV_DEFAULT); } + EV_INLINE void ev_default_fork (void) { ev_loop_fork (EV_DEFAULT); } #if EV_FEATURE_API EV_INLINE void ev_loop_count (EV_P) { ev_iteration (EV_A); } EV_INLINE void ev_loop_depth (EV_P) { ev_depth (EV_A); } @@ -344,13 +344,6 @@ environment settings to be taken into account: ev_default_loop (EVBACKEND_POLL | EVBACKEND_SELECT | EVFLAG_NOENV); -Example: Use whatever libev has to offer, but make sure that kqueue is -used if available (warning, breaks stuff, best use only with your own -private event loop and only if you know the OS supports your types of -fds): - - ev_default_loop (ev_recommended_backends () | EVBACKEND_KQUEUE); - =item struct ev_loop *ev_loop_new (unsigned int flags) This will create and initialise a new event loop object. If the loop @@ -592,6 +585,11 @@ Example: Try to create a event loop that uses epoll and nothing else. if (!epoller) fatal ("no epoll found here, maybe it hides under your chair"); +Example: Use whatever libev has to offer, but make sure that kqueue is +used if available. + + struct ev_loop *loop = ev_loop_new (ev_recommended_backends () | EVBACKEND_KQUEUE); + =item ev_loop_destroy (loop) Destroys an event loop object (frees all memory and kernel state |