--- libev/ev.pod 2008/06/09 14:31:36 1.168 +++ libev/ev.pod 2008/09/08 17:27:42 1.177 @@ -575,6 +575,18 @@ time used for relative timers. You can treat it as the timestamp of the event occurring (or more correctly, libev finding out about it). +=item ev_now_update (loop) + +Establishes the current time by querying the kernel, updating the time +returned by C in the progress. This is a costly operation and +is usually done automatically within C. + +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 +the current time is a good idea. + +See also "The special problem of time updates" in the C section. + =item ev_loop (loop, int flags) Finally, this is it, the event handler. This function usually is called @@ -606,21 +618,22 @@ - Before the first iteration, call any pending watchers. * If EVFLAG_FORKCHECK was used, check for a fork. - - If a fork was detected, queue and call all fork watchers. + - If a fork was detected (by any means), queue and call all fork watchers. - Queue and call all prepare watchers. - - If we have been forked, recreate the kernel state. + - 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". + - 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 any active watchers at all will result in not sleeping). - Sleep if the I/O and timer collect interval say so. - Block the process, waiting for any events. - Queue all outstanding I/O (fd) events. - - Update the "event loop time" and do time jump handling. + - Update the "event loop time" (ev_now ()), and do time jump adjustments. - Queue all outstanding timers. - Queue all outstanding periodics. - - If no events are pending now, queue all idle watchers. + - Unless any events are pending now, queue all idle watchers. - 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 @@ -635,7 +648,7 @@ ... 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); - ... jobs done. yeah! + ... jobs done or somebody called unloop. yeah! =item ev_unloop (loop, how) @@ -681,12 +694,14 @@ =item ev_set_timeout_collect_interval (loop, ev_tstamp interval) These advanced functions influence the time that libev will spend waiting -for events. Both are by default C<0>, meaning that libev will try to -invoke timer/periodic callbacks and I/O callbacks with minimum latency. +for events. Both time intervals are by default C<0>, meaning that libev +will try to invoke timer/periodic callbacks and I/O callbacks with minimum +latency. Setting these to a higher value (the C I be >= C<0>) -allows libev to delay invocation of I/O and timer/periodic callbacks to -increase efficiency of loop iterations. +allows libev to delay invocation of I/O and timer/periodic callbacks +to increase efficiency of loop iterations (or to increase power-saving +opportunities). The background is that sometimes your program runs just fast enough to handle one (or very few) event(s) per loop iteration. While this makes @@ -712,6 +727,13 @@ usually doesn't make much sense to set it to a lower value than C<0.01>, as this approaches the timing granularity of most systems. +Setting the I can improve the opportunity for +saving power, as the program will "bundle" timer callback invocations that +are "near" in time together, by delaying some, thus reducing the number of +times the process sleeps and wakes up again. Another useful technique to +reduce iterations/wake-ups is to use C watchers and make sure +they fire on, say, one-second boundaries only. + =item ev_loop_verify (loop) This function only does something when C support has been @@ -1126,10 +1148,9 @@ =head3 The special problem of SIGPIPE While not really specific to libev, it is easy to forget about SIGPIPE: -when reading from a pipe whose other end has been closed, your program -gets send a SIGPIPE, which, by default, aborts your program. For most -programs this is sensible behaviour, for daemons, this is usually -undesirable. +when writing to a pipe whose other end has been closed, your program gets +send a SIGPIPE, which, by default, aborts your program. For most programs +this is sensible behaviour, for daemons, this is usually undesirable. So when you encounter spurious, unexplained daemon exits, make sure you ignore SIGPIPE (and maybe make sure you log the exit status of your daemon @@ -1190,17 +1211,29 @@ detecting time jumps is hard, and some inaccuracies are unavoidable (the monotonic clock option helps a lot here). +The callback is guaranteed to be invoked only after its timeout has passed, +but if multiple timers become ready during the same loop iteration then +order of execution is undefined. + +=head3 The special problem of time updates + +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 polls for new events, which causes +a growing difference between C and C when handling +lots of events. + The relative timeouts are calculated relative to the C time. This is usually the right thing as this timestamp refers to the time of the event triggering whatever timeout you are modifying/starting. If -you suspect event processing to be delayed and you I to base the timeout -on the current time, use something like this to adjust for this: +you suspect event processing to be delayed and you I to base the +timeout on the current time, use something like this to adjust for this: ev_timer_set (&timer, after + ev_now () - ev_time (), 0.); -The callback is guaranteed to be invoked only after its timeout has passed, -but if multiple timers become ready during the same loop iteration then -order of execution is undefined. +If the event loop is suspended for a long time, you can also force an +update of the time returned by C by calling C. =head3 Watcher-Specific Functions and Data Members @@ -1562,6 +1595,13 @@ event-based approach to child reaping and thus use libev's support for that, so other libev users can use C watchers freely. +=head3 Stopping the Child Watcher + +Currently, the child watcher never gets stopped, even when the +child terminates, so normally one needs to stop the watcher in the +callback. Future versions of libev might stop the watcher automatically +when a child exit is detected. + =head3 Watcher-Specific Functions and Data Members =over 4 @@ -1664,13 +1704,19 @@ =head3 ABI Issues (Largefile Support) Libev by default (unless the user overrides this) uses the default -compilation environment, which means that on systems with optionally -disabled large file support, you get the 32 bit version of the stat +compilation environment, which means that on systems with large file +support disabled by default, you get the 32 bit version of the stat structure. When using the library from programs that change the ABI to use 64 bit file offsets the programs will fail. In that case you have to compile libev with the same flags to get binary compatibility. This is obviously the case with any flags that change the ABI, but the problem is -most noticeably with ev_stat and large file support. +most noticeably disabled with ev_stat and large file support. + +The solution for this is to lobby your distribution maker to make large +file interfaces available by default (as e.g. FreeBSD does) and not +optional. Libev cannot simply switch on large file support because it has +to exchange stat structures with application programs compiled using the +default compilation environment. =head3 Inotify @@ -2650,7 +2696,7 @@ =item D Leandro Lucarella has written a D language binding (F) for libev, to -be found at L. +be found at L. =back @@ -3184,8 +3230,9 @@ thread ever is inside a call at any point in time, e.g. by using a mutex per loop). -If you want to know which design is best for your problem, then I cannot -help you but by giving some generic advice: +If you want to know which design (one loop, locking, or multiple loops +without or something else still) is best for your problem, then I cannot +help you. I can give some generic advice however: =over 4