--- libev/ev.pod 2007/11/26 10:20:43 1.46 +++ libev/ev.pod 2008/10/28 12:31:38 1.206 @@ -4,12 +4,72 @@ =head1 SYNOPSIS - #include + #include + +=head2 EXAMPLE PROGRAM + + // a single header file is required + #include + + // every watcher type has its own typedef'd struct + // with the name ev_TYPE + ev_io stdin_watcher; + ev_timer 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); + } + + // 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); + } + + 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 an html-formatted +web page you might find easier to navigate when reading it for the first +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 @@ -21,34 +81,63 @@ details of the event, and then hand it over to libev by I the watcher. -=head1 FEATURES +=head2 FEATURES -Libev supports select, poll, the linux-specific epoll and the bsd-specific -kqueue mechanisms for file descriptor events, relative timers, absolute -timers with customised rescheduling, signal events, process status change -events (related to SIGCHLD), and event watchers dealing with the event -loop mechanism itself (idle, prepare and check watchers). It also is quite -fast (see this L comparing -it to libevent for example). - -=head1 CONVENTIONS - -Libev is very configurable. In this manual the default configuration -will be described, which supports multiple event loops. For more info -about various configuration options please have a look at the file -F in the libev distribution. If libev was configured without -support for multiple event loops, then all functions taking an initial -argument of name C (which is always of type C) -will not have this argument. +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 =head1 ANATOMY OF A WATCHER +In the following description, uppercase C in names stands for the +watcher type, e.g. C can mean C for timer +watchers and C for I/O watchers. + A watcher is a structure that you create and register to record your 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, -although this can sometimes be quite valid). +watcher structures (and it is I a bad idea to do this on the +stack). + +Each watcher has an associated watcher structure (called C +or simply C, as typedefs are provided for all watcher structs). 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). -Each watcher type has its own C<< ev__set (watcher *, ...) >> macro -with arguments specific to this watcher type. There is also a macro -to combine initialisation and setting in one call: C<< ev__init -(watcher *, callback, ...) >>. +Each watcher type further has its own C<< ev_TYPE_set (watcher *, ...) >> +macro to configure it, with arguments specific to the watcher type. There +is also a macro to combine initialisation and setting in one call: C<< +ev_TYPE_init (watcher *, callback, ...) >>. To make the watcher actually watch out for events, you have to start it -with a watcher-specific start function (C<< ev__start (loop, watcher +with a watcher-specific start function (C<< ev_TYPE_start (loop, watcher *) >>), and you can stop watching for events at any time by calling the -corresponding stop function (C<< ev__stop (loop, watcher *) >>. +corresponding stop function (C<< ev_TYPE_stop (loop, watcher *) >>. As long as your watcher is active (has been started but not stopped) you must not touch the values stored in it. Most specifically you must never -reinitialise it or call its C macro. +reinitialise it or call its C macro. Each and every callback receives the event loop pointer as first, the registered watcher structure as second, and a bitset of received events as @@ -547,6 +884,10 @@ The pid specified in the C watcher has received a status change. +=item C + +The path specified in the C watcher changed its attributes somehow. + =item C The C watcher has determined that you have nothing better to do. @@ -563,27 +904,42 @@ (for example, a C watcher might start an idle watcher to keep C from blocking). +=item C + +The embedded event loop specified in the C watcher needs attention. + +=item C + +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 =head2 GENERIC WATCHER FUNCTIONS -In the following description, C stands for the watcher type, -e.g. C for C watchers and C for C watchers. - =over 4 =item C (ev_TYPE *watcher, callback) @@ -598,9 +954,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 @@ -612,25 +974,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) @@ -643,10 +1018,11 @@ Returns a true value iff the watcher is pending, (i.e. it has outstanding events but its callback has not yet been invoked). As long as a watcher is pending (but not active) you must not call an init function on it (but -C is safe) and you must make sure the watcher is available to -libev (e.g. you cnanot C it). +C is safe), you must not change its priority, and you must +make sure the watcher is available to libev (e.g. you cannot C +it). -=item callback = ev_cb (ev_TYPE *watcher) +=item callback ev_cb (ev_TYPE *watcher) Returns the callback currently set on the watcher. @@ -655,43 +1031,133 @@ Change the callback. You can change the callback at virtually any time (modulo threads). +=item ev_set_priority (ev_TYPE *watcher, priority) + +=item int ev_priority (ev_TYPE *watcher) + +Set and query the priority of the watcher. The priority is a small +integer between C (default: C<2>) and C +(default: C<-2>). Pending watchers with higher priority will be invoked +before watchers with lower priority, but priority will not keep watchers +from being executed (except for C watchers). + +This means that priorities are I used for ordering callback +invocation after new events have been received. This is useful, for +example, to reduce latency after idling, or more often, to bind two +watchers on the same event and make sure one is called first. + +If you need to suppress invocation when higher priority events are pending +you need to look at C watchers, which provide this functionality. + +You I change the priority of a watcher as long as it is active or +pending. + +The default priority used by watchers when no priority has been set is +always C<0>, which is supposed to not be too high and not be too low :). + +Setting a priority outside the range of C to C is +fine, as long as you do not mind that the priority value you query might +or might not have been clamped to the valid range. + +=item ev_invoke (loop, ev_TYPE *watcher, int revents) + +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, 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 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 to use some data structure with multiple +embedded watchers: + + 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: 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): -More interesting and less C-conformant ways of catsing your callback type -have been omitted.... + #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 This section describes each watcher in detail, but will not repeat -information given in the last section. +information given in the last section. Any initialisation/set macros, +functions and members specific to the watcher type are explained. + +Members are additionally marked with either I<[read-only]>, meaning that, +while the watcher is active, you can look at the member and expect some +sensible content, but you must not modify it (you can modify it while the +watcher is stopped to your hearts content), or I<[read-write]>, which +means you can expect it to have some sensible content while the watcher +is active, but you can also modify it. Modifying it may not do something +sensible or take immediate effect (or do anything at all), but libev will +not crash or malfunction in any way. =head2 C - is this file descriptor readable or writable? @@ -709,30 +1175,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 -wether 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 @@ -741,28 +1262,38 @@ =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] + +The file descriptor being watched. + +=item int events [read-only] + +The events being watched. =back -Example: call C when STDIN_FILENO has become, well +=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: +attempt to read a whole line in the callback. + + 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 + } - 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); + ... + 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 @@ -771,22 +1302,211 @@ 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 involve some kind of timeout, 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. + +What follows are some ways to handle this problem, from obvious and +inefficient to smart and efficient. + +In the following, a 60 second activity timeout is assumed - a timeout that +gets reset to 60 seconds each time there is activity (e.g. each time some +data or other life sign was received). + +=over 4 + +=item 1. Use a timer and stop, reinitialise and 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 it, initialise it +and start it again: + + 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 its internal +data structure and then add it again. Libev tries to be fast, but it's +still not a constant-time operation. + +=item 2. Use a timer and re-start it with C inactivity. + +This is the easiest way, and involves using C instead of +C. + +To implement 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 both the C function and the +C argument to C, and only ever use the C +member and C. + +At start: + + ev_timer_init (timer, callback); + timer->repeat = 60.; + ev_timer_again (loop, timer); + +Each time there is some activity: + + ev_timer_again (loop, timer); + +It is even possible to change the time-out on the fly, regardless of +whether the watcher is active or not: + + 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 its internal data structure. + +It is, however, even simpler than the "obvious" way to do it. + +=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 intervals between other activity - 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 + 60. is older than now, we did time out + if (timeout < now) + { + // timeout occured, take action + } + else + { + // callback was invoked, but there was some activity, re-arm + // the watcher to fire in last_activity + 60, which is + // guaranteed to be in the future, so "again" is positive: + w->again = timeout - now; + ev_timer_again (EV_A_ w); + } + } + +To summarise the callback: first calculate the real timeout (defined +as "60 seconds after the last activity"), then check if that time has +been reached, which means something I, in fact, time out. Otherwise +the callback was invoked too early (C is in the future), so +re-schedule the timer to fire at that future time, to see if maybe we have +a timeout then. + +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 +minus half the average time between activity), but virtually no calls to +libev to change the timeout. + +To start the timer, simply initialise the watcher and set C +to the current time (meaning we just have some activity :), then call the +callback, which will "do the right thing" and start the timer: + + ev_timer_init (timer, callback); + last_activity = ev_now (loop); + callback (loop, timer, EV_TIMEOUT); + +And when there is some activity, simply store the current time in +C, no libev calls at all: + + 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. + +Changing the timeout is trivial as well (if it isn't hard-coded in the +callback :) - just change the timeout and invoke the callback, which will +fix things for you. + +=item 4. Wee, just use a double-linked list for your timeouts. + +If there is not one request, but many thousands (millions...), all +employing some kind of timeout with the same timeout value, then one can +do even better: + +When starting the timeout, calculate the timeout value and put the timeout +at the I of the list. + +Then use an C to fire when the timeout at the I of +the list is expected to fire (for example, using the technique #3). + +When there is some activity, remove the timer from the list, recalculate +the timeout, append it to the end of the list again, and make sure to +update the C if it was taken from the beginning of the list. + +This way, one can manage an unlimited number of timeouts in O(1) time for +starting, stopping and updating the timers, at the expense of a major +complication, and having to use a constant timeout. The constant timeout +ensures that the list stays sorted. + +=back + +So which method the best? + +Method #2 is a simple no-brain-required solution that is adequate in most +situations. Method #3 requires a bit more thinking, but handles many cases +better, and isn't very complicated either. In most case, choosing either +one is fine, with #3 being better in typical situations. + +Method #1 is almost always a bad idea, and buys you nothing. Method #4 is +rather complicated, but extremely efficient, something that really pays +off after the first million or so of active timers, i.e. it's usually +overkill :) + +=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 @@ -794,67 +1514,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 started but nonrepeating, stop it. +If the timer is pending, its pending status is cleared. + +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. -If the timer is repeating, either start it if necessary (with the repeat -value), or reset the running timer to the repeat value. +This sounds a bit complicated, see "Be smart about timeouts", above, for a +usage example. -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 after=repeat=60 and calling ev_timer_again 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 stop -the timer, and again will automatically restart it if need be. +=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), +which is also when any modifications are taken into account. =back -Example: create a timer that fires after 60 seconds. +=head3 Examples - static void - one_minute_cb (struct ev_loop *loop, struct ev_timer *w, int revents) - { - .. one minute over, w is actually stopped right here - } +Example: Create a timer that fires after 60 seconds. - 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 +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? @@ -863,20 +1588,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 and of course not if you reset your system time -again). - -They can also be used to implement vastly more complex timers, such as -triggering an event on eahc midnight, local time. - -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 @@ -885,30 +1613,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 (interval = reschedule_cb = 0) +=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 (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) and then repeat, regardless -of any time jumps. +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. @@ -916,7 +1645,16 @@ C will try to run the callback in this mode at the next possible time where C