diff options
-rw-r--r-- | Changes | 6 | ||||
-rw-r--r-- | ev.c | 39 | ||||
-rw-r--r-- | ev.h | 9 | ||||
-rw-r--r-- | ev.pod | 24 |
4 files changed, 53 insertions, 25 deletions
@@ -1,6 +1,6 @@ Revision history for libev, a high-performance and full-featured event loop. -3.4 +3.41 - work around an (undocumented) bug in winsocket select: if you provide only empty fd sets then select returns WSAEINVAL. how sucky. - improve timer scheduling stability and reduce use of time_epsilon. @@ -18,8 +18,8 @@ Revision history for libev, a high-performance and full-featured event loop. - add portability requirements section. - fix manpage headers etc. - normalise WSA error codes to lower range on windows. - - start some (internal only) consistency check code that - can be called frequently to catch bugs. + - add consistency check code that can be called automatically + or on demand to check for internal structures (ev_loop_verify). 3.31 Wed Apr 16 20:45:04 CEST 2008 - added last minute fix for ev_poll.c by Brandon Black. @@ -128,7 +128,7 @@ extern "C" { # define EV_USE_EVENTFD 0 # endif # endif - + #endif #include <math.h> @@ -238,11 +238,15 @@ extern "C" { #endif #if 0 /* debugging */ -# define EV_VERIFY 1 +# define EV_VERIFY 3 # define EV_USE_4HEAP 1 # define EV_HEAP_CACHE_AT 1 #endif +#ifndef EV_VERIFY +# define EV_VERIFY !EV_MINIMAL +#endif + #ifndef EV_USE_4HEAP # define EV_USE_4HEAP !EV_MINIMAL #endif @@ -296,12 +300,7 @@ int eventfd (unsigned int initval, int flags); /**/ -/* EV_VERIFY: enable internal consistency checks - * undefined or zero: no verification done or available - * 1 or higher: ev_loop_verify function available - * 2 or higher: ev_loop_verify is called frequently - */ -#if EV_VERIFY >= 1 +#if EV_VERIFY >= 3 # define EV_FREQUENT_CHECK ev_loop_verify (EV_A) #else # define EV_FREQUENT_CHECK do { } while (0) @@ -1486,6 +1485,7 @@ loop_fork (EV_P) } #if EV_MULTIPLICITY + struct ev_loop * ev_loop_new (unsigned int flags) { @@ -1521,10 +1521,12 @@ array_check (W **ws, int cnt) while (cnt--) assert (("active index mismatch", ev_active (ws [cnt]) == cnt + 1)); } +#endif -static void +void ev_loop_verify (EV_P) { +#if EV_VERIFY int i; checkheap (timers, timercnt); @@ -1539,15 +1541,15 @@ ev_loop_verify (EV_P) #if EV_FORK_ENABLE array_check ((W **)forks, forkcnt); #endif - array_check ((W **)prepares, preparecnt); - array_check ((W **)checks, checkcnt); #if EV_ASYNC_ENABLE array_check ((W **)asyncs, asynccnt); #endif -} + array_check ((W **)prepares, preparecnt); + array_check ((W **)checks, checkcnt); #endif +} -#endif +#endif /* multiplicity */ #if EV_MULTIPLICITY struct ev_loop * @@ -1622,8 +1624,6 @@ call_pending (EV_P) { int pri; - EV_FREQUENT_CHECK; - for (pri = NUMPRI; pri--; ) while (pendingcnt [pri]) { @@ -1635,10 +1635,9 @@ call_pending (EV_P) p->w->pending = 0; EV_CB_INVOKE (p->w, p->events); + EV_FREQUENT_CHECK; } } - - EV_FREQUENT_CHECK; } #if EV_IDLE_ENABLE @@ -1700,6 +1699,7 @@ void inline_size periodics_reify (EV_P) { EV_FREQUENT_CHECK; + while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now) { ev_periodic *w = (ev_periodic *)ANHE_w (periodics [HEAP0]); @@ -1715,7 +1715,6 @@ periodics_reify (EV_P) ANHE_at_cache (periodics [HEAP0]); downheap (periodics, periodiccnt, HEAP0); - EV_FREQUENT_CHECK; } else if (w->interval) { @@ -1861,6 +1860,10 @@ ev_loop (EV_P_ int flags) do { +#if EV_VERIFY >= 2 + ev_loop_verify (EV_A); +#endif + #ifndef _WIN32 if (expect_false (curpid)) /* penalise the forking check even more */ if (expect_false (getpid () != curpid)) @@ -419,7 +419,7 @@ void ev_set_allocator (void *(*cb)(void *ptr, long size)); */ void ev_set_syserr_cb (void (*cb)(const char *msg)); -# if EV_MULTIPLICITY +#if EV_MULTIPLICITY EV_INLINE struct ev_loop * ev_default_loop_uc (void) { @@ -449,10 +449,11 @@ ev_default_loop (unsigned int flags) struct ev_loop *ev_loop_new (unsigned int flags); void ev_loop_destroy (EV_P); void ev_loop_fork (EV_P); +void ev_loop_verify (EV_P); ev_tstamp ev_now (EV_P); /* time w.r.t. timers and the eventloop, updated after each poll */ -# else +#else int ev_default_loop (unsigned int flags); /* returns true when successful */ @@ -463,7 +464,7 @@ ev_now (void) return ev_rt_now; } -# endif +#endif /* multiplicity */ EV_INLINE int ev_is_default_loop (EV_P) @@ -486,7 +487,7 @@ void ev_default_fork (void); unsigned int ev_backend (EV_P); /* backend in use by loop */ unsigned int ev_loop_count (EV_P); /* number of loop iterations */ -#endif +#endif /* prototypes */ #define EVLOOP_NONBLOCK 1 /* do not block/wait */ #define EVLOOP_ONESHOT 2 /* block *once* only */ @@ -691,6 +691,17 @@ interactive servers (of course not for games), likewise for timeouts. It usually doesn't make much sense to set it to a lower value than C<0.01>, as this approsaches the timing granularity of most systems. +=item ev_loop_verify (loop) + +This function only does something when C<EV_VERIFY> support has been +compiled in. It tries to go through all internal structures and checks +them for validity. If anything is found to be inconsistent, it will print +an error message to standard error and call C<abort ()>. + +This can be used to catch bugs inside libev itself: under normal +circumstances, this function will never abort as of course libev keeps its +data structures consistent. + =back @@ -3033,6 +3044,19 @@ noticably with with many (hundreds) of watchers. The default is C<1> unless C<EV_MINIMAL> is set in which case it is C<0> (disabled). +=item EV_VERIFY + +Controls how much internal verification (see C<ev_loop_verify ()>) will +be done: If set to C<0>, no internal verification code will be compiled +in. If set to C<1>, then verification code will be compiled in, but not +called. If set to C<2>, then the internal verification code will be +called once per loop, which can slow down libev. If set to C<3>, then the +verification code will be called very frequently, which will slow down +libev considerably. + +The default is C<1>, unless C<EV_MINIMAL> is set, in which case it will be +C<0.> + =item EV_COMMON By default, all watchers have a C<void *data> member. By redefining |