diff options
author | root <root> | 2010-10-21 12:32:47 +0000 |
---|---|---|
committer | root <root> | 2010-10-21 12:32:47 +0000 |
commit | 6f0d3cb475e52576be15d46194e09d01c54c7de4 (patch) | |
tree | 11882d1e81802b83f9f15af48a227ccc5dcd91dd | |
parent | 0aa781a3bca6d71933d42a757e501b376fa73c29 (diff) |
*** empty log message ***
-rw-r--r-- | Changes | 5 | ||||
-rw-r--r-- | ev.c | 40 | ||||
-rw-r--r-- | ev.h | 50 | ||||
-rw-r--r-- | ev.pod | 240 | ||||
-rw-r--r-- | event.c | 6 | ||||
-rw-r--r-- | event.h | 6 |
6 files changed, 210 insertions, 137 deletions
@@ -1,12 +1,13 @@ Revision history for libev, a high-performance and full-featured event loop. -TODO: ABI??? API????? Changes??? TODO: include ev_xyz_start in each example? TODO: section watcher states/lifetime -TODO: ALL ev_xxx_set funtions must be called from ev++ set methods, somehow. +TODO: use enums //TODO: enum? - "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). + - ev_run will now always update the current loop time - it errornously + didn't when idle watchers were active, causing timers not to fire. - fix a bug where a timeout of zero caused the timer not to fire in the libevent emulation (testcase by Péter Szabó). - applied win32 fixes by Michael Lenaghan (also James Mansion). @@ -719,7 +719,7 @@ typedef struct # define EV_INVOKE_PENDING ev_invoke_pending (EV_A) #endif -#define EVUNLOOP_RECURSE 0x80 +#define EVBREAK_RECURSE 0x80 /*****************************************************************************/ @@ -2294,15 +2294,15 @@ time_update (EV_P_ ev_tstamp max_block) } void -ev_loop (EV_P_ int flags) +ev_run (EV_P_ int flags) { #if EV_FEATURE_API ++loop_depth; #endif - assert (("libev: ev_loop recursion during release detected", loop_done != EVUNLOOP_RECURSE)); + assert (("libev: ev_loop recursion during release detected", loop_done != EVBREAK_RECURSE)); - loop_done = EVUNLOOP_CANCEL; + loop_done = EVBREAK_CANCEL; EV_INVOKE_PENDING; /* in case we recurse, ensure ordering stays nice and clean */ @@ -2355,14 +2355,14 @@ ev_loop (EV_P_ int flags) ev_tstamp waittime = 0.; ev_tstamp sleeptime = 0.; - if (expect_true (!(flags & EVLOOP_NONBLOCK || idleall || !activecnt))) - { - /* remember old timestamp for io_blocktime calculation */ - ev_tstamp prev_mn_now = mn_now; + /* remember old timestamp for io_blocktime calculation */ + ev_tstamp prev_mn_now = mn_now; - /* update time to cancel out callback processing overhead */ - time_update (EV_A_ 1e100); + /* update time to cancel out callback processing overhead */ + time_update (EV_A_ 1e100); + if (expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt))) + { waittime = MAX_BLOCKTIME; if (timercnt) @@ -2402,9 +2402,9 @@ ev_loop (EV_P_ int flags) #if EV_FEATURE_API ++loop_count; #endif - assert ((loop_done = EVUNLOOP_RECURSE, 1)); /* assert for side effect */ + assert ((loop_done = EVBREAK_RECURSE, 1)); /* assert for side effect */ backend_poll (EV_A_ waittime); - assert ((loop_done = EVUNLOOP_CANCEL, 1)); /* assert for side effect */ + assert ((loop_done = EVBREAK_CANCEL, 1)); /* assert for side effect */ /* update ev_rt_now, do magic */ time_update (EV_A_ waittime + sleeptime); @@ -2432,11 +2432,11 @@ ev_loop (EV_P_ int flags) while (expect_true ( activecnt && !loop_done - && !(flags & (EVLOOP_ONESHOT | EVLOOP_NONBLOCK)) + && !(flags & (EVRUN_ONCE | EVRUN_NOWAIT)) )); - if (loop_done == EVUNLOOP_ONE) - loop_done = EVUNLOOP_CANCEL; + if (loop_done == EVBREAK_ONE) + loop_done = EVBREAK_CANCEL; #if EV_FEATURE_API --loop_depth; @@ -2444,7 +2444,7 @@ ev_loop (EV_P_ int flags) } void -ev_unloop (EV_P_ int how) +ev_break (EV_P_ int how) { loop_done = how; } @@ -3429,7 +3429,7 @@ ev_check_stop (EV_P_ ev_check *w) void noinline ev_embed_sweep (EV_P_ ev_embed *w) { - ev_loop (w->other, EVLOOP_NONBLOCK); + ev_run (w->other, EVRUN_NOWAIT); } static void @@ -3440,7 +3440,7 @@ embed_io_cb (EV_P_ ev_io *io, int revents) if (ev_cb (w)) ev_feed_event (EV_A_ (W)w, EV_EMBED); else - ev_loop (w->other, EVLOOP_NONBLOCK); + ev_run (w->other, EVRUN_NOWAIT); } static void @@ -3454,7 +3454,7 @@ embed_prepare_cb (EV_P_ ev_prepare *prepare, int revents) while (fdchangecnt) { fd_reify (EV_A); - ev_loop (EV_A_ EVLOOP_NONBLOCK); + ev_run (EV_A_ EVRUN_NOWAIT); } } } @@ -3470,7 +3470,7 @@ embed_fork_cb (EV_P_ ev_fork *fork_w, int revents) EV_P = w->other; ev_loop_fork (EV_A); - ev_loop (EV_A_ EVLOOP_NONBLOCK); + ev_run (EV_A_ EVRUN_NOWAIT); } ev_embed_start (EV_A_ w); @@ -181,6 +181,7 @@ struct ev_loop; #define EV_VERSION_MINOR 0 /* eventmask, revents, events... */ +//TODO: enum? #define EV_UNDEF -1 /* guaranteed to be invalid */ #define EV_NONE 0x00 /* no events */ #define EV_READ 0x01 /* ev_io detected read will not block */ @@ -443,6 +444,7 @@ union ev_any_watcher #endif }; +//TODO: enum? /* bits for ev_default_loop and ev_loop_new */ /* the default */ #define EVFLAG_AUTO 0x00000000U /* not quite a mask */ @@ -453,6 +455,7 @@ union ev_any_watcher #define EVFLAG_NOINOTIFY 0x00100000U /* do not attempt to use inotify */ #define EVFLAG_NOSIGFD 0 /* compatibility to pre-3.9 */ #define EVFLAG_SIGNALFD 0x00200000U /* attempt to use signalfd */ +//TODO: enum? /* method bits to be ored together */ #define EVBACKEND_SELECT 0x00000001U /* about anywhere */ #define EVBACKEND_POLL 0x00000002U /* !win */ @@ -565,15 +568,17 @@ void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)); #endif /* prototypes */ -#define EVLOOP_NONBLOCK 1 /* do not block/wait */ -#define EVLOOP_ONESHOT 2 /* block *once* only */ -#define EVUNLOOP_CANCEL 0 /* undo unloop */ -#define EVUNLOOP_ONE 1 /* unloop once */ -#define EVUNLOOP_ALL 2 /* unloop all loops */ +//TODO: enum? +#define EVRUN_NOWAIT 1 /* do not block/wait */ +#define EVRUN_ONCE 2 /* block *once* only */ + +#define EVBREAK_CANCEL 0 /* undo unloop */ +#define EVBREAK_ONE 1 /* unloop once */ +#define EVBREAK_ALL 2 /* unloop all loops */ #if EV_PROTOTYPES -void ev_loop (EV_P_ int flags); -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 */ +void ev_run (EV_P_ int flags); +void ev_break (EV_P_ int how); /* set to 1 to break out of event loop, set to 2 to break out of all event loops */ /* * ref/unref can be used to add or remove a refcount on the mainloop. every watcher @@ -594,13 +599,6 @@ unsigned int ev_iteration (EV_P); /* number of loop iterations */ unsigned int ev_depth (EV_P); /* #ev_loop enters - #ev_loop leaves */ void ev_verify (EV_P); /* abort if loop data corrupted */ -/* pre 4.0 API compatibility */ -# if EV_MULTIPLICITY -# define ev_loop_count(l) ev_iteration (l) -# define ev_loop_depth(l) ev_depth (l) -# define ev_loop_verify(l) ev_verify (l) -# endif - 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 */ @@ -757,6 +755,30 @@ void ev_async_stop (EV_P_ ev_async *w); void ev_async_send (EV_P_ ev_async *w); # endif +/* pre-4.0 compatibility */ +#ifndef EV_COMPAT3 +# define EV_COMPAT3 1 +#endif + +#if EV_COMPAT3 + #define EVLOOP_NONBLOCK EVRUN_NOWAIT + #define EVLOOP_ONESHOT EVRUN_ONCE + #define EVUNLOOP_CANCEL EVBREAK_CANCEL + #define EVUNLOOP_ONE EVBREAK_ONE + #define EVUNLOOP_ALL EVBREAK_ALL + #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 ); } + #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); } + EV_INLINE void ev_loop_verify (EV_P) { ev_verify (EV_A); } + #endif + #endif +#else + typedef struct ev_loop ev_loop; +#endif + #endif #ifdef __cplusplus @@ -28,8 +28,8 @@ libev - a high performance full-featured event loop written in C // with its corresponding stop function. ev_io_stop (EV_A_ w); - // this causes all nested ev_loop's to stop iterating - ev_unloop (EV_A_ EVUNLOOP_ALL); + // this causes all nested ev_run's to stop iterating + ev_break (EV_A_ EVBREAK_ALL); } // another callback, this time for a time-out @@ -37,8 +37,8 @@ libev - a high performance full-featured event loop written in C timeout_cb (EV_P_ ev_timer *w, int revents) { puts ("timeout"); - // this causes the innermost ev_loop to stop iterating - ev_unloop (EV_A_ EVUNLOOP_ONE); + // this causes the innermost ev_run to stop iterating + ev_break (EV_A_ EVBREAK_ONE); } int @@ -58,7 +58,7 @@ libev - a high performance full-featured event loop written in C ev_timer_start (loop, &timeout_watcher); // now wait for events to arrive - ev_loop (loop, 0); + ev_run (loop, 0); // unloop was called, so exit return 0; @@ -294,13 +294,13 @@ Example: This is basically the same thing that libev does internally, too. =head1 FUNCTIONS CONTROLLING THE EVENT LOOP -An event loop is described by a C<struct ev_loop *> (the C<struct> -is I<not> optional in this case, as there is also an C<ev_loop> -I<function>). +An event loop is described by a C<struct ev_loop *> (the C<struct> is +I<not> optional in case unless libev 3 compatibility is disabled, as libev +3 had an C<ev_loop> function colliding with the struct name). The library knows two types of such loops, the I<default> loop, which -supports signals and child events, and dynamically created loops which do -not. +supports signals and child events, and dynamically created event loops +which do not. =over 4 @@ -608,12 +608,12 @@ earlier call to C<ev_loop_new>. =item ev_default_fork () -This function sets a flag that causes subsequent C<ev_loop> iterations +This function sets a flag that causes subsequent C<ev_run> iterations to reinitialise the kernel state for backends that have one. Despite the name, you can call it anytime, but it makes most sense after forking, in the child process (or both child and parent, but that again makes little sense). You I<must> call it in the child before using any of the libev -functions, and it will only take effect at the next C<ev_loop> iteration. +functions, and it will only take effect at the next C<ev_run> iteration. Again, you I<have> to call it on I<any> loop that you want to re-use after a fork, I<even if you do not plan to use the loop in the parent>. This is @@ -621,9 +621,11 @@ because some kernel interfaces *cough* I<kqueue> *cough* do funny things during fork. On the other hand, you only need to call this function in the child -process if and only if you want to use the event loop in the child. If you -just fork+exec or create a new loop in the child, you don't have to call -it at all. +process if and only if you want to use the event loop in the child. If +you just fork+exec or create a new loop in the child, you don't have to +call it at all (in fact, C<epoll> is so badly broken that it makes a +difference, but libev will usually detect this case on its own and do a +costly reset of the backend). The function itself is quite fast and it's usually not a problem to call it just in case after a fork. To make this easy, the function will fit in @@ -645,9 +647,9 @@ otherwise. =item unsigned int ev_iteration (loop) -Returns the current iteration count for the loop, which is identical to -the number of times libev did poll for new events. It starts at C<0> and -happily wraps around with enough iterations. +Returns the current iteration count for the event loop, which is identical +to the number of times libev did poll for new events. It starts at C<0> +and happily wraps around with enough iterations. This value can sometimes be useful as a generation counter of sorts (it "ticks" the number of loop iterations), as it roughly corresponds with @@ -656,16 +658,16 @@ prepare and check phases. =item unsigned int ev_depth (loop) -Returns the number of times C<ev_loop> was entered minus the number of -times C<ev_loop> was exited, in other words, the recursion depth. +Returns the number of times C<ev_run> was entered minus the number of +times C<ev_run> was exited, in other words, the recursion depth. -Outside C<ev_loop>, this number is zero. In a callback, this number is -C<1>, unless C<ev_loop> was invoked recursively (or from another thread), +Outside C<ev_run>, this number is zero. In a callback, this number is +C<1>, unless C<ev_run> was invoked recursively (or from another thread), in which case it is higher. -Leaving C<ev_loop> abnormally (setjmp/longjmp, cancelling the thread +Leaving C<ev_run> abnormally (setjmp/longjmp, cancelling the thread etc.), doesn't count as "exit" - consider this as a hint to avoid such -ungentleman behaviour unless it's really convenient. +ungentleman-like behaviour unless it's really convenient. =item unsigned int ev_backend (loop) @@ -684,7 +686,7 @@ event occurring (or more correctly, libev finding out about it). Establishes the current time by querying the kernel, updating the time returned by C<ev_now ()> in the progress. This is a costly operation and -is usually done automatically within C<ev_loop ()>. +is usually done automatically within C<ev_run ()>. This function is rarely useful, but when some event callback runs for a very long time without entering the event loop, updating libev's idea of @@ -696,8 +698,8 @@ See also L<The special problem of time updates> in the C<ev_timer> section. =item ev_resume (loop) -These two functions suspend and resume a loop, for use when the loop is -not used for a while and timeouts should not be processed. +These two functions suspend and resume an event loop, for use when the +loop is not used for a while and timeouts should not be processed. A typical use case would be an interactive program such as a game: When the user presses C<^Z> to suspend the game and resumes it an hour later it @@ -718,28 +720,32 @@ without a previous call to C<ev_suspend>. Calling C<ev_suspend>/C<ev_resume> has the side effect of updating the event loop time (see C<ev_now_update>). -=item ev_loop (loop, int flags) +=item ev_run (loop, int flags) Finally, this is it, the event handler. This function usually is called after you have initialised all your watchers and you want to start -handling events. +handling events. It will ask the operating system for any new events, call +the watcher callbacks, an then repeat the whole process indefinitely: This +is why event loops are called I<loops>. -If the flags argument is specified as C<0>, it will not return until -either no event watchers are active anymore or C<ev_unloop> was called. +If the flags argument is specified as C<0>, it will keep handling events +until either no event watchers are active anymore or C<ev_break> was +called. -Please note that an explicit C<ev_unloop> is usually better than +Please note that an explicit C<ev_break> is usually better than relying on all watchers to be stopped when deciding when a program has finished (especially in interactive programs), but having a program that automatically loops as long as it has to and no longer by virtue of relying on its watchers stopping correctly, that is truly a thing of beauty. -A flags value of C<EVLOOP_NONBLOCK> will look for new events, will handle -those events and any already outstanding ones, but will not block your -process in case there are no events and will return after one iteration of -the loop. +A flags value of C<EVRUN_NOWAIT> will look for new events, will handle +those events and any already outstanding ones, but will not wait and +block your process in case there are no events and will return after one +iteration of the loop. This is sometimes useful to poll and handle new +events while doing lengthy calculations, to keep the program responsive. -A flags value of C<EVLOOP_ONESHOT> will look for new events (waiting if +A flags value of C<EVRUN_ONCE> will look for new events (waiting if necessary) and will handle those and any already outstanding ones. It will block your process until at least one new event arrives (which could be an event internal to libev itself, so there is no guarantee that a @@ -748,55 +754,64 @@ iteration of the loop. This is useful if you are waiting for some external event in conjunction with something not expressible using other libev watchers (i.e. "roll your -own C<ev_loop>"). However, a pair of C<ev_prepare>/C<ev_check> watchers is +own C<ev_run>"). However, a pair of C<ev_prepare>/C<ev_check> watchers is usually a better approach for this kind of thing. -Here are the gory details of what C<ev_loop> does: +Here are the gory details of what C<ev_run> does: + - Increment loop depth. + - Reset the ev_break status. - Before the first iteration, call any pending watchers. - * If EVFLAG_FORKCHECK was used, check for a fork. + LOOP: + - If EVFLAG_FORKCHECK was used, check for a fork. - If a fork was detected (by any means), queue and call all fork watchers. - Queue and call all prepare watchers. + - If ev_break was called, goto FINISH. - If we have been forked, detach and recreate the kernel state as to not disturb the other process. - Update the kernel state with all outstanding changes. - Update the "event loop time" (ev_now ()). - Calculate for how long to sleep or block, if at all - (active idle watchers, EVLOOP_NONBLOCK or not having + (active idle watchers, EVRUN_NOWAIT or not having any active watchers at all will result in not sleeping). - Sleep if the I/O and timer collect interval say so. + - Increment loop iteration counter. - Block the process, waiting for any events. - Queue all outstanding I/O (fd) events. - Update the "event loop time" (ev_now ()), and do time jump adjustments. - Queue all expired timers. - Queue all expired periodics. - - Unless any events are pending now, queue all idle watchers. + - Queue all idle watchers with priority higher than that of pending events. - Queue all check watchers. - Call all queued watchers in reverse order (i.e. check watchers first). Signals and child watchers are implemented as I/O watchers, and will be handled here by queueing them when their watcher gets executed. - - If ev_unloop has been called, or EVLOOP_ONESHOT or EVLOOP_NONBLOCK - were used, or there are no active watchers, return, otherwise - continue with step *. + - If ev_break has been called, or EVRUN_ONCE or EVRUN_NOWAIT + were used, or there are no active watchers, goto FINISH, otherwise + continue with step LOOP. + FINISH: + - Reset the ev_break status iff it was EVBREAK_ONE. + - Decrement the loop depth. + - Return. Example: Queue some jobs and then loop until no events are outstanding anymore. ... queue jobs here, make sure they register event watchers as long ... as they still have work to do (even an idle watcher will do..) - ev_loop (my_loop, 0); + ev_run (my_loop, 0); ... jobs done or somebody called unloop. yeah! -=item ev_unloop (loop, how) +=item ev_break (loop, how) -Can be used to make a call to C<ev_loop> return early (but only after it +Can be used to make a call to C<ev_run> return early (but only after it has processed all outstanding events). The C<how> argument must be either -C<EVUNLOOP_ONE>, which will make the innermost C<ev_loop> call return, or -C<EVUNLOOP_ALL>, which will make all nested C<ev_loop> calls return. +C<EVBREAK_ONE>, which will make the innermost C<ev_run> call return, or +C<EVBREAK_ALL>, which will make all nested C<ev_run> calls return. -This "unloop state" will be cleared when entering C<ev_loop> again. +This "unloop state" will be cleared when entering C<ev_run> again. -It is safe to call C<ev_unloop> from outside any C<ev_loop> calls. +It is safe to call C<ev_break> from outside any C<ev_run> calls. ##TODO## =item ev_ref (loop) @@ -804,15 +819,15 @@ It is safe to call C<ev_unloop> from outside any C<ev_loop> calls. Ref/unref can be used to add or remove a reference count on the event loop: Every watcher keeps one reference, and as long as the reference -count is nonzero, C<ev_loop> will not return on its own. +count is nonzero, C<ev_run> will not return on its own. This is useful when you have a watcher that you never intend to -unregister, but that nevertheless should not keep C<ev_loop> from +unregister, but that nevertheless should not keep C<ev_run> from returning. In such a case, call C<ev_unref> after starting, and C<ev_ref> before stopping it. As an example, libev itself uses this for its internal signal pipe: It -is not visible to the libev user and should not keep C<ev_loop> from +is not visible to the libev user and should not keep C<ev_run> from exiting if no event watchers registered by it are active. It is also an excellent way to do this for generic recurring timers or from within third-party libraries. Just remember to I<unref after start> and I<ref @@ -821,7 +836,7 @@ before, respectively. Note also that libev might stop watchers itself (e.g. non-repeating timers) in which case you have to C<ev_ref> in the callback). -Example: Create a signal watcher, but keep it from keeping C<ev_loop> +Example: Create a signal watcher, but keep it from keeping C<ev_run> running when nothing else is active. ev_signal exitsig; @@ -894,7 +909,7 @@ more often than 100 times per second: =item ev_invoke_pending (loop) This call will simply invoke all pending watchers while resetting their -pending state. Normally, C<ev_loop> does this automatically when required, +pending state. Normally, C<ev_run> does this automatically when required, but when overriding the invoke callback this call comes handy. =item int ev_pending_count (loop) @@ -905,7 +920,7 @@ are pending. =item ev_set_invoke_pending_cb (loop, void (*invoke_pending_cb)(EV_P)) This overrides the invoke pending functionality of the loop: Instead of -invoking all pending watchers when there are any, C<ev_loop> will call +invoking all pending watchers when there are any, C<ev_run> will call this callback instead. This is useful, for example, when you want to invoke the actual watchers inside another context (another thread etc.). @@ -918,10 +933,10 @@ Sometimes you want to share the same loop between multiple threads. This can be done relatively simply by putting mutex_lock/unlock calls around each call to a libev function. -However, C<ev_loop> can run an indefinite time, so it is not feasible to -wait for it to return. One way around this is to wake up the loop via -C<ev_unloop> and C<av_async_send>, another way is to set these I<release> -and I<acquire> callbacks on the loop. +However, C<ev_run> can run an indefinite time, so it is not feasible +to wait for it to return. One way around this is to wake up the event +loop via C<ev_break> and C<av_async_send>, another way is to set these +I<release> and I<acquire> callbacks on the loop. When set, then C<release> will be called just before the thread is suspended waiting for new events, and C<acquire> is called just @@ -934,10 +949,10 @@ While event loop modifications are allowed between invocations of C<release> and C<acquire> (that's their only purpose after all), no modifications done will affect the event loop, i.e. adding watchers will have no effect on the set of file descriptors being watched, or the time -waited. Use an C<ev_async> watcher to wake up C<ev_loop> when you want it +waited. Use an C<ev_async> watcher to wake up C<ev_run> when you want it to take note of any changes you made. -In theory, threads executing C<ev_loop> will be async-cancel safe between +In theory, threads executing C<ev_run> will be async-cancel safe between invocations of C<release> and C<acquire>. See also the locking example in the C<THREADS> section later in this @@ -984,7 +999,7 @@ become readable, you would create an C<ev_io> watcher for that: static void my_cb (struct ev_loop *loop, ev_io *w, int revents) { ev_io_stop (w); - ev_unloop (loop, EVUNLOOP_ALL); + ev_break (loop, EVBREAK_ALL); } struct ev_loop *loop = ev_default_loop (0); @@ -995,7 +1010,7 @@ become readable, you would create an C<ev_io> watcher for that: ev_io_set (&stdin_watcher, STDIN_FILENO, EV_READ); ev_io_start (loop, &stdin_watcher); - ev_loop (loop, 0); + ev_run (loop, 0); As you can see, you are responsible for allocating the memory for your watcher structures (and it is I<usually> a bad idea to do this on the @@ -1069,13 +1084,13 @@ The C<ev_idle> watcher has determined that you have nothing better to do. =item C<EV_CHECK> -All C<ev_prepare> watchers are invoked just I<before> C<ev_loop> starts +All C<ev_prepare> watchers are invoked just I<before> C<ev_run> starts to gather new events, and all C<ev_check> watchers are invoked just after -C<ev_loop> has gathered them, but before it invokes any callbacks for any +C<ev_run> has gathered them, but before it invokes any callbacks for any received events. Callbacks of both watcher types can start and stop as many watchers as they want, and all of them will be taken into account (for example, a C<ev_prepare> watcher might start an idle watcher to keep -C<ev_loop> from blocking). +C<ev_run> from blocking). =item C<EV_EMBED> @@ -1626,7 +1641,7 @@ attempt to read a whole line in the callback. ev_io stdin_readable; ev_io_init (&stdin_readable, stdin_readable_cb, STDIN_FILENO, EV_READ); ev_io_start (loop, &stdin_readable); - ev_loop (loop, 0); + ev_run (loop, 0); =head2 C<ev_timer> - relative and optionally repeating timeouts @@ -1645,7 +1660,7 @@ passed (not I<at>, so on systems with very low-resolution clocks this might introduce a small delay). If multiple timers become ready during the same loop iteration then the ones with earlier time-out values are invoked before ones of the same priority with later time-out values (but this is -no longer true when a callback calls C<ev_loop> recursively). +no longer true when a callback calls C<ev_run> recursively). =head3 Be smart about timeouts @@ -1826,7 +1841,7 @@ overkill :) Establishing the current time is a costly operation (it usually takes at least two system calls): EV therefore updates its idea of the current -time only before and after C<ev_loop> collects new events, which causes a +time only before and after C<ev_run> collects new events, which causes a growing difference between C<ev_now ()> and C<ev_time ()> when handling lots of events in one iteration. @@ -1953,7 +1968,7 @@ inactivity. ev_timer mytimer; ev_timer_init (&mytimer, timeout_cb, 0., 10.); /* note, only repeat used */ ev_timer_again (&mytimer); /* start timer */ - ev_loop (loop, 0); + ev_run (loop, 0); // and in some piece of code that gets executed on any "activity": // reset the timeout to start ticking again at 10 seconds @@ -1989,7 +2004,7 @@ As with timers, the callback is guaranteed to be invoked only when the point in time where it is supposed to trigger has passed. If multiple timers become ready during the same loop iteration then the ones with earlier time-out values are invoked before ones with later time-out values -(but this is no longer true when a callback calls C<ev_loop> recursively). +(but this is no longer true when a callback calls C<ev_run> recursively). =head3 Watcher-Specific Functions and Data Members @@ -2237,7 +2252,7 @@ Example: Try to exit cleanly on SIGINT. static void sigint_cb (struct ev_loop *loop, ev_signal *w, int revents) { - ev_unloop (loop, EVUNLOOP_ALL); + ev_break (loop, EVBREAK_ALL); } ev_signal signal_watcher; @@ -2633,7 +2648,7 @@ Prepare and check watchers are usually (but not always) used in pairs: prepare watchers get invoked before the process blocks and check watchers afterwards. -You I<must not> call C<ev_loop> or similar functions that enter +You I<must not> call C<ev_run> or similar functions that enter the current event loop from either C<ev_prepare> or C<ev_check> watchers. Other loops than the current one are fine, however. The rationale behind this is that you do not need to check for recursion in @@ -2811,7 +2826,7 @@ libglib event loop. // create/start timer // poll - ev_loop (EV_A_ 0); + ev_run (EV_A_ 0); // stop timer again if (timeout >= 0) @@ -2899,7 +2914,7 @@ if you do not want that, you need to temporarily stop the embed watcher). =item ev_embed_sweep (loop, ev_embed *) Make a single, non-blocking sweep over the embedded loop. This works -similarly to C<ev_loop (embedded_loop, EVLOOP_NONBLOCK)>, but in the most +similarly to C<ev_run (embedded_loop, EVRUN_NOWAIT)>, but in the most appropriate way for embedded loops. =item struct ev_loop *other [read-only] @@ -3015,7 +3030,7 @@ believe me. =head2 C<ev_async> - how to wake up an event loop -In general, you cannot use an C<ev_loop> from multiple threads or other +In general, you cannot use an C<ev_run> from multiple threads or other asynchronous sources such as signal handlers (as opposed to multiple event loops - those are of course safe to use in different threads). @@ -3532,7 +3547,7 @@ C<EV_A_> is used when other arguments are following. Example: ev_unref (EV_A); ev_timer_add (EV_A_ watcher); - ev_loop (EV_A_ 0); + ev_run (EV_A_ 0); It assumes the variable C<loop> of type C<struct ev_loop *> is in scope, which is often provided by the following macro. @@ -3582,7 +3597,7 @@ or not. ev_check check; ev_check_init (&check, check_cb); ev_check_start (EV_DEFAULT_ &check); - ev_loop (EV_DEFAULT_ 0); + ev_run (EV_DEFAULT_ 0); =head1 EMBEDDING @@ -3684,6 +3699,22 @@ settings. =over 4 +=item EV_COMPAT3 (h) + +Backwards compatibility is a major concern for libev. This is why this +release of libev comes with wrappers for the functions and symbols that +have been renamed between libev version 3 and 4. + +You can disable these wrappers (to test compatibility with future +versions) by defining C<EV_COMPAT3> to C<0> when compiling your +sources. This has the additional advantage that you can drop the C<struct> +from C<struct ev_loop> declarations, as libev will provide an C<ev_loop> +typedef in that case. + +In some future version, the default for C<EV_COMPAT3> will become C<0>, +and in some even more future version the compatibility code will be +removed completely. + =item EV_STANDALONE (h) Must always be C<1> if you do not use autoconf configuration, which @@ -4267,7 +4298,7 @@ protecting the loop data, respectively. } The event loop thread first acquires the mutex, and then jumps straight -into C<ev_loop>: +into C<ev_run>: void * l_run (void *thr_arg) @@ -4276,7 +4307,7 @@ into C<ev_loop>: l_acquire (EV_A); pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0); - ev_loop (EV_A_ 0); + ev_run (EV_A_ 0); l_release (EV_A); return 0; @@ -4338,13 +4369,13 @@ watchers in the next event loop iteration. Libev is very accommodating to coroutines ("cooperative threads"): libev fully supports nesting calls to its functions from different -coroutines (e.g. you can call C<ev_loop> on the same loop from two +coroutines (e.g. you can call C<ev_run> on the same loop from two different coroutines, and switch freely between both coroutines running the loop, as long as you don't confuse yourself). The only exception is that you must not do this from C<ev_periodic> reschedule callbacks. Care has been taken to ensure that libev does not keep local state inside -C<ev_loop>, and other calls do not usually allow for coroutine switches as +C<ev_run>, and other calls do not usually allow for coroutine switches as they do not call any callbacks. =head2 COMPILER WARNINGS @@ -4731,25 +4762,38 @@ removed in later versions of libev, so better update early than late. =over 4 -=item C<ev_loop_count> renamed to C<ev_iteration> +=item function/symbol renames -=item C<ev_loop_depth> renamed to C<ev_depth> +A number of functions and symbols have been renamed: -=item C<ev_loop_verify> renamed to C<ev_verify> + ev_loop => ev_run + EVLOOP_NONBLOCK => EVRUN_NOWAIT + EVLOOP_ONESHOT => EVRUN_ONCE -Most functions working on C<struct ev_loop> objects don't have an -C<ev_loop_> prefix, so it was removed. Note that C<ev_loop_fork> is -still called C<ev_loop_fork> because it would otherwise clash with the -C<ev_fork> typedef. + ev_unloop => ev_break + EVUNLOOP_CANCEL => EVBREAK_CANCEL + EVUNLOOP_ONE => EVBREAK_ONE + EVUNLOOP_ALL => EVBREAK_ALL -=item C<EV_TIMEOUT> renamed to C<EV_TIMER> in C<revents> + EV_TIMEOUT => EV_TIMER -This is a simple rename - all other watcher types use their name -as revents flag, and now C<ev_timer> does, too. + ev_loop_count => ev_iteration + ev_loop_depth => ev_depth + ev_loop_verify => ev_verify -Both C<EV_TIMER> and C<EV_TIMEOUT> symbols were present in 3.x versions -and continue to be present for the foreseeable future, so this is mostly a -documentation change. +Most functions working on C<struct ev_loop> objects don't have an +C<ev_loop_> prefix, so it was removed; C<ev_loop>, C<ev_unloop> and +associated constants have been renamed to not collide with the C<struct +ev_loop> anymore and C<EV_TIMER> now follows the same naming scheme +as all other watcher types. Note that C<ev_loop_fork> is still called +C<ev_loop_fork> because it would otherwise clash with the C<ev_fork> +typedef. + +=item C<EV_COMPAT3> backwards compatibility mechanism + +The backward compatibility mechanism can be controlled by +C<EV_COMPAT3>. See L<PREPROCESSOR SYMBOLS/MACROS> in the L<EMBEDDING> +section. =item C<EV_MINIMAL> mechanism replaced by C<EV_FEATURES> @@ -140,7 +140,7 @@ int event_loopexit (struct timeval *tv) static void ev_x_cb (struct event *ev, int revents) { - revents &= EV_READ | EV_WRITE | EV_TIMEOUT | EV_SIGNAL; + revents &= EV_READ | EV_WRITE | EV_TIMER | EV_SIGNAL; ev->ev_res = revents; ev->ev_callback (ev->ev_fd, (short)revents, ev->ev_arg); @@ -327,7 +327,7 @@ int event_base_loop (struct event_base *base, int flags) { dLOOPbase; - ev_loop (EV_A_ flags); + ev_run (EV_A_ flags); return 0; } @@ -342,7 +342,7 @@ ev_x_loopexit_cb (int revents, void *base) { dLOOPbase; - ev_unloop (EV_A_ EVUNLOOP_ONE); + ev_break (EV_A_ EVBREAK_ONE); } int event_base_loopexit (struct event_base *base, struct timeval *tv) @@ -46,6 +46,12 @@ # include "ev.h" #endif +#ifndef EVLOOP_NONBLOCK +# define EVLOOP_NONBLOCK EVRUN_NOWAIT +#endif +#ifndef EVLOOP_ONESHOT +# define EVLOOP_ONESHOT EVRUN_ONCE +#endif #ifndef EV_TIMEOUT # define EV_TIMEOUT EV_TIMER #endif |