--- libev/ev.pod 2007/12/09 19:42:57 1.78 +++ libev/ev.pod 2008/10/23 06:30:48 1.198 @@ -4,58 +4,72 @@ =head1 SYNOPSIS - #include + #include -=head1 EXAMPLE PROGRAM +=head2 EXAMPLE PROGRAM - #include + // a single header file is required + #include - ev_io stdin_watcher; - ev_timer timeout_watcher; + // every watcher type has its own typedef'd struct + // with the name ev_ + ev_io stdin_watcher; + ev_timer timeout_watcher; - /* called when data readable on stdin */ - static void - stdin_cb (EV_P_ struct ev_io *w, int revents) - { - /* puts ("stdin ready"); */ - ev_io_stop (EV_A_ w); /* just a syntax example */ - ev_unloop (EV_A_ EVUNLOOP_ALL); /* leave all loop calls */ - } - - static void - timeout_cb (EV_P_ struct ev_timer *w, int revents) - { - /* puts ("timeout"); */ - ev_unloop (EV_A_ EVUNLOOP_ONE); /* leave one loop call */ - } - - int - main (void) - { - struct ev_loop *loop = ev_default_loop (0); - - /* initialise an io watcher, then start it */ - ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ); - ev_io_start (loop, &stdin_watcher); - - /* simple non-repeating 5.5 second timeout */ - ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.); - ev_timer_start (loop, &timeout_watcher); + // all watcher callbacks have a similar signature + // this callback is called when data is readable on stdin + static void + stdin_cb (EV_P_ ev_io *w, int revents) + { + puts ("stdin ready"); + // for one-shot events, one must manually stop the watcher + // 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); + } - /* loop till timeout or data ready */ - ev_loop (loop, 0); + // another callback, this time for a time-out + static void + 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); + } - return 0; - } + int + main (void) + { + // use the default event loop unless you have special needs + ev_loop *loop = ev_default_loop (0); + + // initialise an io watcher, then start it + // this one will watch for stdin to become readable + ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ); + ev_io_start (loop, &stdin_watcher); + + // initialise a timer watcher, then start it + // simple non-repeating 5.5 second timeout + ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.); + ev_timer_start (loop, &timeout_watcher); + + // now wait for events to arrive + ev_loop (loop, 0); + + // unloop was called, so exit + return 0; + } =head1 DESCRIPTION -The newest version of this document is also available as a html-formatted +The newest version of this document is also available as an html-formatted web page you might find easier to navigate when reading it for the first -time: L. +time: L. Libev is an event loop: you register interest in certain events (such as a -file descriptor being readable or a timeout occuring), and it will manage +file descriptor being readable or a timeout occurring), and it will manage these event sources and provide your program with events. To do this, it must take more or less complete control over your process @@ -67,7 +81,7 @@ details of the event, and then hand it over to libev by I the watcher. -=head1 FEATURES +=head2 FEATURES Libev supports C which have a high +overhead for the actual polling but can deliver many events at once. + +By setting a higher I you allow libev to spend more +time collecting I/O events, so you can handle more events per iteration, +at the cost of increasing latency. Timeouts (both C and +C) will be not affected. Setting this to a non-null value will +introduce an additional C call into most loop iterations. + +Likewise, by setting a higher I you allow libev +to spend more time collecting timeouts, at the expense of increased +latency/jitter/inexactness (the watcher callback will be called +later). C watchers will not be affected. Setting this to a non-null +value will not introduce any overhead in libev. + +Many (busy) programs can usually benefit by setting the I/O collect +interval to a value near C<0.1> or so, which is often enough for +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 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 +compiled in. which is the default for non-minimal builds. 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. + +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 @@ -560,18 +788,18 @@ interest in some event. For instance, if you want to wait for STDIN to become readable, you would create an C watcher for that: - static void my_cb (struct ev_loop *loop, struct ev_io *w, int revents) - { - ev_io_stop (w); - ev_unloop (loop, EVUNLOOP_ALL); - } - - struct ev_loop *loop = ev_default_loop (0); - struct ev_io stdin_watcher; - ev_init (&stdin_watcher, my_cb); - ev_io_set (&stdin_watcher, STDIN_FILENO, EV_READ); - ev_io_start (loop, &stdin_watcher); - ev_loop (loop, 0); + static void my_cb (struct ev_loop *loop, ev_io *w, int revents) + { + ev_io_stop (w); + ev_unloop (loop, EVUNLOOP_ALL); + } + + struct ev_loop *loop = ev_default_loop (0); + ev_io stdin_watcher; + ev_init (&stdin_watcher, my_cb); + ev_io_set (&stdin_watcher, STDIN_FILENO, EV_READ); + ev_io_start (loop, &stdin_watcher); + ev_loop (loop, 0); As you can see, you are responsible for allocating the memory for your watcher structures (and it is usually a bad idea to do this on the stack, @@ -579,7 +807,7 @@ Each watcher structure must be initialised by a call to C, which expects a callback to be provided. This -callback gets invoked each time the event occurs (or, in the case of io +callback gets invoked each time the event occurs (or, in the case of I/O watchers, each time the event loop detects that the file descriptor given is readable and/or writable). @@ -659,19 +887,28 @@ The event loop has been resumed in the child process after fork (see C). +=item C + +The given async watcher has been asynchronously notified (see C). + =item C -An unspecified error has occured, the watcher has been stopped. This might +An unspecified error has occurred, the watcher has been stopped. This might happen because the watcher could not be properly started because libev ran out of memory, a file descriptor was found to be closed or any other -problem. You best act on it by reporting the problem and somehow coping -with the watcher being stopped. +problem. Libev considers these application bugs. -Libev will usually signal a few "dummy" events together with an error, -for example it might indicate that a fd is readable or writable, and if -your callbacks is well-written it can just attempt the operation and cope -with the error from read() or write(). This will not work in multithreaded -programs, though, so beware. +You best act on it by reporting the problem and somehow coping with the +watcher being stopped. Note that well-written programs should not receive +an error ever, so when your watcher receives it, this usually indicates a +bug in your program. + +Libev will usually signal a few "dummy" events together with an error, for +example it might indicate that a fd is readable or writable, and if your +callbacks is well-written it can just attempt the operation and cope with +the error from read() or write(). This will not work in multi-threaded +programs, though, as the fd could already be closed and reused for another +thing, so beware. =back @@ -694,9 +931,15 @@ You can reinitialise a watcher at any time as long as it has been stopped (or never started) and there are no pending events outstanding. -The callback is always of type C. +Example: Initialise an C watcher in two steps. + + ev_io w; + ev_init (&w, my_cb); + ev_io_set (&w, STDIN_FILENO, EV_READ); + =item C (ev_TYPE *, [args]) This macro initialises the type-specific parts of a watcher. You need to @@ -708,25 +951,38 @@ Although some watcher types do not have type-specific arguments (e.g. C) you still need to call its C macro. +See C, above, for an example. + =item C (ev_TYPE *watcher, callback, [args]) -This convinience macro rolls both C and C macro -calls into a single call. This is the most convinient method to initialise +This convenience macro rolls both C and C macro +calls into a single call. This is the most convenient method to initialise a watcher. The same limitations apply, of course. +Example: Initialise and set an C watcher in one step. + + ev_io_init (&w, my_cb, STDIN_FILENO, EV_READ); + =item C (loop *, ev_TYPE *watcher) Starts (activates) the given watcher. Only active watchers will receive events. If the watcher is already active nothing will happen. +Example: Start the C watcher that is being abused as example in this +whole section. + + ev_io_start (EV_DEFAULT_UC, &w); + =item C (loop *, ev_TYPE *watcher) -Stops the given watcher again (if active) and clears the pending -status. It is possible that stopped watchers are pending (for example, -non-repeating timers are being stopped when they become pending), but -C ensures that the watcher is neither active nor pending. If -you want to free or reuse the memory used by the watcher it is therefore a -good idea to always call its C function. +Stops the given watcher if active, and clears the pending status (whether +the watcher was active or not). + +It is possible that stopped watchers are pending - for example, +non-repeating timers are being stopped when they become pending - but +calling C ensures that the watcher is neither active nor +pending. If you want to free or reuse the memory used by the watcher it is +therefore a good idea to always call its C function. =item bool ev_is_active (ev_TYPE *watcher) @@ -784,74 +1040,85 @@ Invoke the C with the given C and C. Neither C nor C need to be valid as long as the watcher callback -can deal with that fact. +can deal with that fact, as both are simply passed through to the +callback. =item int ev_clear_pending (loop, ev_TYPE *watcher) -If the watcher is pending, this function returns clears its pending status -and returns its C bitset (as if its callback was invoked). If the +If the watcher is pending, this function clears its pending status and +returns its C bitset (as if its callback was invoked). If the watcher isn't pending it does nothing and returns C<0>. +Sometimes it can be useful to "poll" a watcher instead of waiting for its +callback to be invoked, which can be accomplished with this function. + =back =head2 ASSOCIATING CUSTOM DATA WITH A WATCHER Each watcher has, by default, a member C that you can change -and read at any time, libev will completely ignore it. This can be used +and read at any time: libev will completely ignore it. This can be used to associate arbitrary data with your watcher. If you need more data and don't want to allocate memory and store a pointer to it in that data member, you can also "subclass" the watcher type and provide your own data: - struct my_io - { - struct ev_io io; - int otherfd; - void *somedata; - struct whatever *mostinteresting; - } + struct my_io + { + ev_io io; + int otherfd; + void *somedata; + struct whatever *mostinteresting; + }; + + ... + struct my_io w; + ev_io_init (&w.io, my_cb, fd, EV_READ); And since your callback will be called with a pointer to the watcher, you can cast it back to your own type: - static void my_cb (struct ev_loop *loop, struct ev_io *w_, int revents) - { - struct my_io *w = (struct my_io *)w_; - ... - } + static void my_cb (struct ev_loop *loop, ev_io *w_, int revents) + { + struct my_io *w = (struct my_io *)w_; + ... + } More interesting and less C-conformant ways of casting your callback type instead have been omitted. -Another common scenario is having some data structure with multiple -watchers: +Another common scenario is to use some data structure with multiple +embedded watchers: + + struct my_biggy + { + int some_data; + ev_timer t1; + ev_timer t2; + } - struct my_biggy - { - int some_data; - ev_timer t1; - ev_timer t2; - } - -In this case getting the pointer to C is a bit more complicated, -you need to use C: - - #include - - static void - t1_cb (EV_P_ struct ev_timer *w, int revents) - { - struct my_biggy big = (struct my_biggy * - (((char *)w) - offsetof (struct my_biggy, t1)); - } - - static void - t2_cb (EV_P_ struct ev_timer *w, int revents) - { - struct my_biggy big = (struct my_biggy * - (((char *)w) - offsetof (struct my_biggy, t2)); - } +In this case getting the pointer to C is a bit more +complicated: Either you store the address of your C struct +in the C member of the watcher (for woozies), or you need to use +some pointer arithmetic using C inside your watchers (for real +programmers): + + #include + + static void + t1_cb (EV_P_ ev_timer *w, int revents) + { + struct my_biggy big = (struct my_biggy * + (((char *)w) - offsetof (struct my_biggy, t1)); + } + + static void + t2_cb (EV_P_ ev_timer *w, int revents) + { + struct my_biggy big = (struct my_biggy * + (((char *)w) - offsetof (struct my_biggy, t2)); + } =head1 WATCHER TYPES @@ -885,30 +1152,85 @@ descriptors to non-blocking mode is also usually a good idea (but not required if you know what you are doing). -You have to be careful with dup'ed file descriptors, though. Some backends -(the linux epoll backend is a notable example) cannot handle dup'ed file -descriptors correctly if you register interest in two or more fds pointing -to the same underlying file/socket/etc. description (that is, they share -the same underlying "file open"). - -If you must do this, then force the use of a known-to-be-good backend -(at the time of this writing, this includes only C and -C). +If you cannot use non-blocking mode, then force the use of a +known-to-be-good backend (at the time of this writing, this includes only +C and C). Another thing you have to watch out for is that it is quite easy to -receive "spurious" readyness notifications, that is your callback might +receive "spurious" readiness notifications, that is your callback might be called with C but a subsequent C(2) will actually block because there is no data. Not only are some backends known to create a -lot of those (for example solaris ports), it is very easy to get into +lot of those (for example Solaris ports), it is very easy to get into this situation even with a relatively standard program structure. Thus it is best to always use non-blocking I/O: An extra C(2) returning C is far preferable to a program hanging until some data arrives. -If you cannot run the fd in non-blocking mode (for example you should not -play around with an Xlib connection), then you have to seperately re-test -whether a file descriptor is really ready with a known-to-be good interface -such as poll (fortunately in our Xlib example, Xlib already does this on -its own, so its quite safe to use). +If you cannot run the fd in non-blocking mode (for example you should +not play around with an Xlib connection), then you have to separately +re-test whether a file descriptor is really ready with a known-to-be good +interface such as poll (fortunately in our Xlib example, Xlib already +does this on its own, so its quite safe to use). Some people additionally +use C and an interval timer, just to be sure you won't block +indefinitely. + +But really, best use non-blocking mode. + +=head3 The special problem of disappearing file descriptors + +Some backends (e.g. kqueue, epoll) need to be told about closing a file +descriptor (either due to calling C explicitly or any other means, +such as C). The reason is that you register interest in some file +descriptor, but when it goes away, the operating system will silently drop +this interest. If another file descriptor with the same number then is +registered with libev, there is no efficient way to see that this is, in +fact, a different file descriptor. + +To avoid having to explicitly tell libev about such cases, libev follows +the following policy: Each time C is being called, libev +will assume that this is potentially a new file descriptor, otherwise +it is assumed that the file descriptor stays the same. That means that +you I to call C (or C) when you change the +descriptor even if the file descriptor number itself did not change. + +This is how one would do it normally anyway, the important point is that +the libev application should not optimise around libev but should leave +optimisations to libev. + +=head3 The special problem of dup'ed file descriptors + +Some backends (e.g. epoll), cannot register events for file descriptors, +but only events for the underlying file descriptions. That means when you +have C'ed file descriptors or weirder constellations, and register +events for them, only one file descriptor might actually receive events. + +There is no workaround possible except not registering events +for potentially C'ed file descriptors, or to resort to +C or C. + +=head3 The special problem of fork + +Some backends (epoll, kqueue) do not support C at all or exhibit +useless behaviour. Libev fully supports fork, but needs to be told about +it in the child. + +To support fork in your programs, you either have to call +C or C after a fork in the child, +enable C, or resort to C or +C. + +=head3 The special problem of SIGPIPE + +While not really specific to libev, it is easy to forget about C: +when writing to a pipe whose other end has been closed, your program gets +sent 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 +somewhere, as that would have given you a big clue). + + +=head3 Watcher-Specific Functions =over 4 @@ -917,8 +1239,8 @@ =item ev_io_set (ev_io *, int fd, int events) Configures an C watcher. The C is the file descriptor to -rceeive events for and events is either C, C or -C to receive the given events. +receive events for and C is either C, C or +C, to express the desire to receive the given events. =item int fd [read-only] @@ -930,23 +1252,25 @@ =back +=head3 Examples + Example: Call C when STDIN_FILENO has become, well readable, but only once. Since it is likely line-buffered, you could attempt to read a whole line in the callback. - static void - stdin_readable_cb (struct ev_loop *loop, struct ev_io *w, int revents) - { - ev_io_stop (loop, w); - .. read from stdin here (or from w->fd) and haqndle any I/O errors - } - - ... - struct ev_loop *loop = ev_default_init (0); - struct 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); + static void + stdin_readable_cb (struct ev_loop *loop, ev_io *w, int revents) + { + ev_io_stop (loop, w); + .. read from stdin here (or from w->fd) and handle any I/O errors + } + + ... + struct ev_loop *loop = ev_default_init (0); + 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); =head2 C - relative and optionally repeating timeouts @@ -955,22 +1279,164 @@ given time, and optionally repeating in regular intervals after that. The timers are based on real time, that is, if you register an event that -times out after an hour and you reset your system clock to last years -time, it will still time out after (roughly) and hour. "Roughly" because +times out after an hour and you reset your system clock to January last +year, it will still time out after (roughly) one hour. "Roughly" because 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 I its timeout has +passed, but if multiple timers become ready during the same loop iteration +then order of execution is undefined. + +=head3 Be smart about timeouts + +Many real-world problems invole some kind of time-out, usually for error +recovery. A typical example is an HTTP request - if the other side hangs, +you want to raise some error after a while. + +Here are some ways on how to handle this problem, from simple and +inefficient to very efficient. + +In the following examples a 60 second activity timeout is assumed - a +timeout that gets reset to 60 seconds each time some data ("a lifesign") +was received. + +=over 4 + +=item 1. Use a timer and stop, reinitialise, start it on activity. + +This is the most obvious, but not the most simple way: In the beginning, +start the watcher: + + ev_timer_init (timer, callback, 60., 0.); + ev_timer_start (loop, timer); + +Then, each time there is some activity, C the timer, +initialise it again, and start it: + + ev_timer_stop (loop, timer); + ev_timer_set (timer, 60., 0.); + ev_timer_start (loop, timer); + +This is relatively simple to implement, but means that each time there +is some activity, libev will first have to remove the timer from it's +internal data strcuture and then add it again. + +=item 2. Use a timer and re-start it with C inactivity. + +This is the easiest way, and involves using C instead of +C. + +For this, configure an C with a C value of C<60> and +then call C at start and each time you successfully read +or write some data. If you go into an idle state where you do not expect +data to travel on the socket, you can C the timer, and +C will automatically restart it if need be. + +That means you can ignore the C value and C +altogether and only ever use the C value and C. + +At start: + + ev_timer_init (timer, callback, 0., 60.); + ev_timer_again (loop, timer); + +Each time you receive some data: + + ev_timer_again (loop, timer); + +It is even possible to change the time-out on the fly: + + timer->repeat = 30.; + ev_timer_again (loop, timer); + +This is slightly more efficient then stopping/starting the timer each time +you want to modify its timeout value, as libev does not have to completely +remove and re-insert the timer from/into it's internal data structure. + +=item 3. Let the timer time out, but then re-arm it as required. + +This method is more tricky, but usually most efficient: Most timeouts are +relatively long compared to the loop iteration time - in our example, +within 60 seconds, there are usually many I/O events with associated +activity resets. + +In this case, it would be more efficient to leave the C alone, +but remember the time of last activity, and check for a real timeout only +within the callback: + + ev_tstamp last_activity; // time of last activity + + static void + callback (EV_P_ ev_timer *w, int revents) + { + ev_tstamp now = ev_now (EV_A); + ev_tstamp timeout = last_activity + 60.; + + // if last_activity is older than now - timeout, we did time out + if (timeout < now) + { + // timeout occured, take action + } + else + { + // callback was invoked, but there was some activity, re-arm + // to fire in last_activity + 60. + w->again = timeout - now; + ev_timer_again (EV_A_ w); + } + } + +To summarise the callback: first calculate the real time-out (defined as +"60 seconds after the last activity"), then check if that time has been +reached, which means there was a real timeout. Otherwise the callback was +invoked too early (timeout is in the future), so re-schedule the timer to +fire at that future time. + +Note how C is used, taking advantage of the +C optimisation when the timer is already running. + +This scheme causes more callback invocations (about one every 60 seconds), +but virtually no calls to libev to change the timeout. + +To start the timer, simply intiialise the watcher and C, +then call the callback: + + ev_timer_init (timer, callback); + last_activity = ev_now (loop); + callback (loop, timer, EV_TIMEOUT); + +And when there is some activity, simply remember the time in +C: + + last_actiivty = ev_now (loop); + +This technique is slightly more complex, but in most cases where the +time-out is unlikely to be triggered, much more efficient. + +=back + +=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 collects new events, which causes a +growing difference between C and C when handling +lots of events in one iteration. + 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 guarenteed to be invoked only when 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 =over 4 @@ -978,91 +1444,72 @@ =item ev_timer_set (ev_timer *, ev_tstamp after, ev_tstamp repeat) -Configure the timer to trigger after C seconds. If C is -C<0.>, then it will automatically be stopped. If it is positive, then the -timer will automatically be configured to trigger again C seconds -later, again, and again, until stopped manually. - -The timer itself will do a best-effort at avoiding drift, that is, if you -configure a timer to trigger every 10 seconds, then it will trigger at -exactly 10 second intervals. If, however, your program cannot keep up with -the timer (because it takes longer than those 10 seconds to do stuff) the -timer will not fire more than once per event loop iteration. +Configure the timer to trigger after C seconds. If C +is C<0.>, then it will automatically be stopped once the timeout is +reached. If it is positive, then the timer will automatically be +configured to trigger again C seconds later, again, and again, +until stopped manually. + +The timer itself will do a best-effort at avoiding drift, that is, if +you configure a timer to trigger every 10 seconds, then it will normally +trigger at exactly 10 second intervals. If, however, your program cannot +keep up with the timer (because it takes longer than those 10 seconds to +do stuff) the timer will not fire more than once per event loop iteration. -=item ev_timer_again (loop) +=item ev_timer_again (loop, ev_timer *) This will act as if the timer timed out and restart it again if it is repeating. The exact semantics are: If the timer is pending, its pending status is cleared. -If the timer is started but nonrepeating, stop it (as if it timed out). +If the timer is started but non-repeating, stop it (as if it timed out). If the timer is repeating, either start it if necessary (with the C value), or reset the running timer to the C value. -This sounds a bit complicated, but here is a useful and typical -example: Imagine you have a tcp connection and you want a so-called idle -timeout, that is, you want to be called when there have been, say, 60 -seconds of inactivity on the socket. The easiest way to do this is to -configure an C with a C value of C<60> and then call -C each time you successfully read or write some data. If -you go into an idle state where you do not expect data to travel on the -socket, you can C the timer, and C will -automatically restart it if need be. - -That means you can ignore the C value and C -altogether and only ever use the C value and C: - - ev_timer_init (timer, callback, 0., 5.); - ev_timer_again (loop, timer); - ... - timer->again = 17.; - ev_timer_again (loop, timer); - ... - timer->again = 10.; - ev_timer_again (loop, timer); - -This is more slightly efficient then stopping/starting the timer each time -you want to modify its timeout value. +This sounds a bit complicated, see "Be smart about timeouts", above, for a +usage example. =item ev_tstamp repeat [read-write] The current C value. Will be used each time the watcher times out -or C is called and determines the next timeout (if any), +or C is called, and determines the next timeout (if any), which is also when any modifications are taken into account. =back +=head3 Examples + Example: Create a timer that fires after 60 seconds. - static void - one_minute_cb (struct ev_loop *loop, struct ev_timer *w, int revents) - { - .. one minute over, w is actually stopped right here - } - - struct ev_timer mytimer; - ev_timer_init (&mytimer, one_minute_cb, 60., 0.); - ev_timer_start (loop, &mytimer); + static void + one_minute_cb (struct ev_loop *loop, ev_timer *w, int revents) + { + .. one minute over, w is actually stopped right here + } + + ev_timer mytimer; + ev_timer_init (&mytimer, one_minute_cb, 60., 0.); + ev_timer_start (loop, &mytimer); Example: Create a timeout timer that times out after 10 seconds of inactivity. - static void - timeout_cb (struct ev_loop *loop, struct ev_timer *w, int revents) - { - .. ten seconds without any activity - } - - struct 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); - - // and in some piece of code that gets executed on any "activity": - // reset the timeout to start ticking again at 10 seconds - ev_timer_again (&mytimer); + static void + timeout_cb (struct ev_loop *loop, ev_timer *w, int revents) + { + .. ten seconds without any activity + } + + 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); + + // and in some piece of code that gets executed on any "activity": + // reset the timeout to start ticking again at 10 seconds + ev_timer_again (&mytimer); =head2 C - to cron or not to cron? @@ -1071,20 +1518,23 @@ (and unfortunately a bit complex). Unlike C's, they are not based on real time (or relative time) -but on wallclock time (absolute time). You can tell a periodic watcher -to trigger "at" some specific point in time. For example, if you tell a -periodic watcher to trigger in 10 seconds (by specifiying e.g. C) and then reset your system clock to the last year, then it will -take a year to trigger the event (unlike an C, which would trigger -roughly 10 seconds later). - -They can also be used to implement vastly more complex timers, such as -triggering an event on each midnight, local time or other, complicated, -rules. - -As with timers, the callback is guarenteed to be invoked only when the -time (C) has been passed, but if multiple periodic timers become ready -during the same loop iteration then order of execution is undefined. +but on wall clock time (absolute time). You can tell a periodic watcher +to trigger after some specific point in time. For example, if you tell a +periodic watcher to trigger in 10 seconds (by specifying e.g. C, that is, an absolute time not a delay) and then reset your system +clock to January of the previous year, then it will take more than year +to trigger the event (unlike an C, which would still trigger +roughly 10 seconds later as it uses a relative timeout). + +Cs can also be used to implement vastly more complex timers, +such as triggering an event on each "midnight, local time", or other +complicated rules. + +As with timers, the callback is guaranteed to be invoked only when the +time (C) has passed, but if multiple periodic timers become ready +during the same loop iteration, then order of execution is undefined. + +=head3 Watcher-Specific Functions and Data Members =over 4 @@ -1093,30 +1543,31 @@ =item ev_periodic_set (ev_periodic *, ev_tstamp after, ev_tstamp repeat, reschedule_cb) Lots of arguments, lets sort it out... There are basically three modes of -operation, and we will explain them from simplest to complex: +operation, and we will explain them from simplest to most complex: =over 4 =item * absolute timer (at = time, interval = reschedule_cb = 0) -In this configuration the watcher triggers an event at the wallclock time -C and doesn't repeat. It will not adjust when a time jump occurs, -that is, if it is to be run at January 1st 2011 then it will run when the -system time reaches or surpasses this time. +In this configuration the watcher triggers an event after the wall clock +time C has passed. It will not repeat and will not adjust when a time +jump occurs, that is, if it is to be run at January 1st 2011 then it will +only run when the system clock reaches or surpasses this time. -=item * non-repeating interval timer (at = offset, interval > 0, reschedule_cb = 0) +=item * repeating interval timer (at = offset, interval > 0, reschedule_cb = 0) In this mode the watcher will always be scheduled to time out at the next C time (for some integer N, which can also be negative) and then repeat, regardless of any time jumps. -This can be used to create timers that do not drift with respect to system -time: +This can be used to create timers that do not drift with respect to the +system clock, for example, here is a C that triggers each +hour, on the hour: ev_periodic_set (&periodic, 0., 3600., 0); This doesn't mean there will always be 3600 seconds in between triggers, -but only that the the callback will be called when the system time shows a +but only that the callback will be called when the system time shows a full hour (UTC), or more correctly, when the system time is evenly divisible by 3600. @@ -1126,7 +1577,12 @@ For numerical stability it is preferable that the C value is near C (the current time), but there is no range requirement for -this value. +this value, and in fact is often specified as zero. + +Note also that there is an upper limit to how often a timer can fire (CPU +speed for example), so if C is very small then timing stability +will of course deteriorate. Libev itself tries to be exact to be about one +millisecond (if the OS supports it and the machine is fast enough). =item * manual reschedule mode (at and interval ignored, reschedule_cb = callback) @@ -1136,14 +1592,17 @@ current time as second argument. NOTE: I. If you need to stop it, -return C (or so, fudge fudge) and stop it afterwards (e.g. by -starting an C watcher, which is legal). +ever, or make ANY event loop modifications whatsoever>. -Its prototype is C, e.g.: +If you need to stop it, return C (or so, fudge fudge) and stop +it afterwards (e.g. by starting an C watcher, which is the +only event loop modification you are allowed to do). - static ev_tstamp my_rescheduler (struct ev_periodic *w, ev_tstamp now) +The callback prototype is C, e.g.: + + static ev_tstamp + my_rescheduler (ev_periodic *w, ev_tstamp now) { return now + 60.; } @@ -1153,11 +1612,11 @@ will usually be called just before the callback will be triggered, but might be called at other times, too. -NOTE: I<< This callback must always return a time that is later than the -passed C value >>. Not even C itself will do, it I be larger. +NOTE: I<< This callback must always return a time that is higher than or +equal to the passed C value >>. This can be used to create very complex timers, such as a timer that -triggers on each midnight, local time. To do this, you would calculate the +triggers on "next midnight, local time". To do this, you would calculate the next midnight after C and return the timestamp value for this. How you do this is, again, up to you (but it is not trivial, which is the main reason I omitted it as an example). @@ -1171,6 +1630,11 @@ a different time than the last time it was called (e.g. in a crond like program when the crontabs have changed). +=item ev_tstamp ev_periodic_at (ev_periodic *) + +When active, returns the absolute time that the watcher is supposed to +trigger next. + =item ev_tstamp offset [read-write] When repeating, this contains the offset value, otherwise this is the @@ -1185,7 +1649,7 @@ take effect when the periodic timer fires or C is being called. -=item ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now) [read-write] +=item ev_tstamp (*reschedule_cb)(ev_periodic *w, ev_tstamp now) [read-write] The current reschedule callback, or C<0>, if this functionality is switched off. Can be changed any time, but changes only take effect when @@ -1193,38 +1657,40 @@ =back +=head3 Examples + Example: Call a callback every hour, or, more precisely, whenever the -system clock is divisible by 3600. The callback invocation times have -potentially a lot of jittering, but good long-term stability. +system time is divisible by 3600. The callback invocation times have +potentially a lot of jitter, but good long-term stability. - static void - clock_cb (struct ev_loop *loop, struct ev_io *w, int revents) - { - ... its now a full hour (UTC, or TAI or whatever your clock follows) - } - - struct ev_periodic hourly_tick; - ev_periodic_init (&hourly_tick, clock_cb, 0., 3600., 0); - ev_periodic_start (loop, &hourly_tick); + static void + clock_cb (struct ev_loop *loop, ev_io *w, int revents) + { + ... its now a full hour (UTC, or TAI or whatever your clock follows) + } + + ev_periodic hourly_tick; + ev_periodic_init (&hourly_tick, clock_cb, 0., 3600., 0); + ev_periodic_start (loop, &hourly_tick); Example: The same as above, but use a reschedule callback to do it: - #include + #include - static ev_tstamp - my_scheduler_cb (struct ev_periodic *w, ev_tstamp now) - { - return fmod (now, 3600.) + 3600.; - } + static ev_tstamp + my_scheduler_cb (ev_periodic *w, ev_tstamp now) + { + return now + (3600. - fmod (now, 3600.)); + } - ev_periodic_init (&hourly_tick, clock_cb, 0., 0., my_scheduler_cb); + ev_periodic_init (&hourly_tick, clock_cb, 0., 0., my_scheduler_cb); Example: Call a callback every hour, starting now: - struct ev_periodic hourly_tick; - ev_periodic_init (&hourly_tick, clock_cb, - fmod (ev_now (loop), 3600.), 3600., 0); - ev_periodic_start (loop, &hourly_tick); + ev_periodic hourly_tick; + ev_periodic_init (&hourly_tick, clock_cb, + fmod (ev_now (loop), 3600.), 3600., 0); + ev_periodic_start (loop, &hourly_tick); =head2 C - signal me when a signal gets signalled! @@ -1234,12 +1700,24 @@ will try it's best to deliver signals synchronously, i.e. as part of the normal event processing, like any other event. +If you want signals asynchronously, just use C as you would +do without libev and forget about sharing the signal. You can even use +C from a signal handler to synchronously wake up an event loop. + You can configure as many watchers as you like per signal. Only when the -first watcher gets started will libev actually register a signal watcher -with the kernel (thus it coexists with your own signal handlers as long -as you don't register any with libev). Similarly, when the last signal -watcher for a signal is stopped libev will reset the signal handler to -SIG_DFL (regardless of what it was set to before). +first watcher gets started will libev actually register a signal handler +with the kernel (thus it coexists with your own signal handlers as long as +you don't register any with libev for the same signal). Similarly, when +the last signal watcher for a signal is stopped, libev will reset the +signal handler to SIG_DFL (regardless of what it was set to before). + +If possible and supported, libev will install its handlers with +C behaviour enabled, so system calls should not be unduly +interrupted. If you have a problem with system calls getting interrupted by +signals you can block all signals in an C watcher and unblock +them in an C watcher. + +=head3 Watcher-Specific Functions and Data Members =over 4 @@ -1256,24 +1734,77 @@ =back +=head3 Examples + +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_signal signal_watcher; + ev_signal_init (&signal_watcher, sigint_cb, SIGINT); + ev_signal_start (loop, &signal_watcher); + =head2 C - watch out for process status changes Child watchers trigger when your process receives a SIGCHLD in response to -some child status changes (most typically when a child of yours dies). +some child status changes (most typically when a child of yours dies or +exits). It is permissible to install a child watcher I the child +has been forked (which implies it might have already exited), as long +as the event loop isn't entered (or is continued from a watcher), i.e., +forking and then immediately registering a watcher for the child is fine, +but forking and registering a watcher a few event loop iterations later is +not. + +Only the default event loop is capable of handling signals, and therefore +you can only register child watchers in the default event loop. + +=head3 Process Interaction + +Libev grabs C as soon as the default event loop is +initialised. This is necessary to guarantee proper behaviour even if +the first child watcher is started after the child exits. The occurrence +of C is recorded asynchronously, but child reaping is done +synchronously as part of the event loop processing. Libev always reaps all +children, even ones not watched. + +=head3 Overriding the Built-In Processing + +Libev offers no special support for overriding the built-in child +processing, but if your application collides with libev's default child +handler, you can override it easily by installing your own handler for +C after initialising the default loop, and making sure the +default loop never gets destroyed. You are encouraged, however, to use an +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 -=item ev_child_init (ev_child *, callback, int pid) +=item ev_child_init (ev_child *, callback, int pid, int trace) -=item ev_child_set (ev_child *, int pid) +=item ev_child_set (ev_child *, int pid, int trace) Configures the watcher to wait for status changes of process C (or I process if C is specified as C<0>). The callback can look at the C member of the C watcher structure to see the status word (use the macros from C and see your systems C documentation). The C member contains the pid of the -process causing the status change. +process causing the status change. C must be either C<0> (only +activate the watcher when the process terminates) or C<1> (additionally +activate the watcher when the process is stopped or continued). =item int pid [read-only] @@ -1290,22 +1821,39 @@ =back -Example: Try to exit cleanly on SIGINT and SIGTERM. +=head3 Examples + +Example: C a new process and install a child handler to wait for +its completion. + + ev_child cw; + + static void + child_cb (EV_P_ ev_child *w, int revents) + { + ev_child_stop (EV_A_ w); + printf ("process %d exited with status %x\n", w->rpid, w->rstatus); + } - static void - sigint_cb (struct ev_loop *loop, struct ev_signal *w, int revents) - { - ev_unloop (loop, EVUNLOOP_ALL); - } - - struct ev_signal signal_watcher; - ev_signal_init (&signal_watcher, sigint_cb, SIGINT); - ev_signal_start (loop, &sigint_cb); + pid_t pid = fork (); + + if (pid < 0) + // error + else if (pid == 0) + { + // the forked child executes here + exit (1); + } + else + { + ev_child_init (&cw, child_cb, pid, 0); + ev_child_start (EV_DEFAULT_ &cw); + } =head2 C - did the file attributes just change? -This watches a filesystem path for attribute changes. That is, it calls +This watches a file system path for attribute changes. That is, it calls C regularly (or when the OS says it changed) and sees if it changed compared to the last time, invoking the callback if it did. @@ -1318,26 +1866,87 @@ The path I be absolute and I end in a slash. If it is relative and your working directory changes, the behaviour is undefined. -Since there is no standard to do this, the portable implementation simply -calls C regularly on the path to see if it changed somehow. You -can specify a recommended polling interval for this case. If you specify -a polling interval of C<0> (highly recommended!) then a I value will be used (which you can expect to be around -five seconds, although this might change dynamically). Libev will also -impose a minimum interval which is currently around C<0.1>, but thats -usually overkill. +Since there is no standard kernel interface to do this, the portable +implementation simply calls C regularly on the path to see if +it changed somehow. You can specify a recommended polling interval for +this case. If you specify a polling interval of C<0> (highly recommended!) +then a I value will be used (which +you can expect to be around five seconds, although this might change +dynamically). Libev will also impose a minimum interval which is currently +around C<0.1>, but thats usually overkill. This watcher type is not meant for massive numbers of stat watchers, as even with OS-supported change notifications, this can be resource-intensive. -At the time of this writing, only the Linux inotify interface is -implemented (implementing kqueue support is left as an exercise for the -reader). Inotify will be used to give hints only and should not change the -semantics of C watchers, which means that libev sometimes needs -to fall back to regular polling again even with inotify, but changes are -usually detected immediately, and if the file exists there will be no -polling. +At the time of this writing, the only OS-specific interface implemented +is the Linux inotify interface (implementing kqueue support is left as +an exercise for the reader. Note, however, that the author sees no way +of implementing C semantics with kqueue). + +=head3 ABI Issues (Largefile Support) + +Libev by default (unless the user overrides this) uses the default +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 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 and Kqueue + +When C support has been compiled into libev (generally +only available with Linux 2.6.25 or above due to bugs in earlier +implementations) and present at runtime, it will be used to speed up +change detection where possible. The inotify descriptor will be created +lazily when the first C watcher is being started. + +Inotify presence does not change the semantics of C watchers +except that changes might be detected earlier, and in some cases, to avoid +making regular C calls. Even in the presence of inotify support +there are many cases where libev has to resort to regular C polling, +but as long as the path exists, libev usually gets away without polling. + +There is no support for kqueue, as apparently it cannot be used to +implement this functionality, due to the requirement of having a file +descriptor open on the object at all times, and detecting renames, unlinks +etc. is difficult. + +=head3 The special problem of stat time resolution + +The C system call only supports full-second resolution portably, and +even on systems where the resolution is higher, most file systems still +only support whole seconds. + +That means that, if the time is the only thing that changes, you can +easily miss updates: on the first update, C detects a change and +calls your callback, which does something. When there is another update +within the same second, C will be unable to detect unless the +stat data does change in other ways (e.g. file size). + +The solution to this is to delay acting on a change for slightly more +than a second (or till slightly after the next full second boundary), using +a roughly one-second-delay C (e.g. C). + +The C<.02> offset is added to work around small timing inconsistencies +of some operating systems (where the second counter of the current time +might be be delayed. One such system is the Linux kernel, where a call to +C might return a timestamp with a full second later than +a subsequent C