--- libev/ev.pod 2007/11/27 20:38:07 1.55 +++ libev/ev.pod 2011/01/10 14:30:15 1.352 @@ -4,54 +4,94 @@ =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; + #include // for puts - /* 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); + // every watcher type has its own typedef'd struct + // with the name ev_TYPE + ev_io stdin_watcher; + ev_timer timeout_watcher; - /* loop till timeout or data ready */ - ev_loop (loop, 0); + // 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_run's to stop iterating + ev_break (EV_A_ EVBREAK_ALL); + } - return 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_run to stop iterating + ev_break (EV_A_ EVBREAK_ONE); + } + + int + main (void) + { + // use the default event loop unless you have special needs + struct ev_loop *loop = EV_DEFAULT; + + // 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_run (loop, 0); + + // unloop was called, so exit + return 0; + } -=head1 DESCRIPTION +=head1 ABOUT THIS DOCUMENT + +This document documents the libev software package. + +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. + +While this document tries to be as complete as possible in documenting +libev, its usage and the rationale behind its design, it is not a tutorial +on event-based programming, nor will it introduce event-based programming +with libev. + +Familiarity with event based programming techniques in general is assumed +throughout this document. + +=head1 WHAT TO READ WHEN IN A HURRY + +This manual tries to be very detailed, but unfortunately, this also makes +it very long. If you just want to know the basics of libev, I suggest +reading L, then the L above and +look up the missing functions in L and the C and +C sections in L. + +=head1 ABOUT LIBEV 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 @@ -63,39 +103,66 @@ details of the event, and then hand it over to libev by I the watcher. -=head1 FEATURES +=head2 FEATURES -Libev supports C, C, the Linux-specific C, the +BSD-specific C and the Solaris-specific event port mechanisms +for file descriptor events (C), the Linux C interface +(for C), Linux eventfd/signalfd (for faster and cleaner +inter-thread wakeup (C)/signal handling (C)) relative +timers (C), absolute timers with customised rescheduling +(C), synchronous signals (C), process status +change events (C), and event watchers dealing with the event +loop mechanism itself (C, C, C and +C watchers) as well as file watchers (C) and even +limited support for fork events (C). It also is quite fast (see this L comparing it to libevent for example). -=head1 CONVENTIONS +=head2 CONVENTIONS + +Libev is very configurable. In this manual the default (and most common) +configuration will be described, which supports multiple event loops. For +more info about various configuration options please have a look at +B section in this manual. 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. + +=head2 TIME REPRESENTATION + +Libev represents time as a single floating point number, representing +the (fractional) number of seconds since the (POSIX) epoch (in practice +somewhere near the beginning of 1970, details are complicated, don't +ask). This type is called C, which is what you should use +too. It usually aliases to the C type in C. When you need to do +any calculations on it, you should treat it as some floating point value. + +Unlike the name component C might indicate, it is also used for +time differences (e.g. delays) throughout libev. + +=head1 ERROR HANDLING + +Libev knows three classes of errors: operating system errors, usage errors +and internal errors (bugs). + +When libev catches an operating system error it cannot handle (for example +a system call indicating a condition libev cannot fix), it calls the callback +set via C, which is supposed to fix the problem or +abort. The default is to print a diagnostic message and to call C. + +When libev detects a usage error such as a negative timer interval, then +it will print a diagnostic message and abort (via the C mechanism, +so C will disable this checking): these are programming errors in +the libev caller and need to be fixed there. + +Libev also has a few internal error-checking Cions, and also has +extensive consistency checking code. These do not trigger under normal +circumstances, as they indicate either a bug in libev or worse. -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 B section in -this manual. 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. - -=head1 TIME REPRESENTATION - -Libev represents time as a single floating point number, representing the -(fractional) number of seconds since the (POSIX) epoch (somewhere near -the beginning of 1970, details are complicated, don't ask). This type is -called C, which is what you should use too. It usually aliases -to the C type in C, and when you need to do any calculations on -it, you should treat it as such. =head1 GLOBAL FUNCTIONS @@ -108,29 +175,40 @@ Returns the current time as libev would use it. Please note that the C function is usually faster and also often returns the timestamp -you actually want to know. +you actually want to know. Also interesting is the combination of +C and C. + +=item ev_sleep (ev_tstamp interval) + +Sleep for the given interval: The current thread will be blocked until +either it is interrupted or the given time interval has passed. Basically +this is a sub-second-resolution C. =item int ev_version_major () =item int ev_version_minor () -You can find out the major and minor version numbers of the library +You can find out the major and minor ABI version numbers of the library you linked against by calling the functions C and C. If you want, you can compare against the global symbols C and C, which specify the version of the library your program was compiled against. +These version numbers refer to the ABI version of the library, not the +release version. + Usually, it's a good idea to terminate if the major versions mismatch, -as this indicates an incompatible change. Minor versions are usually +as this indicates an incompatible change. Minor versions are usually compatible to older versions, so a larger minor version alone is usually not a problem. Example: Make sure we haven't accidentally been linked against the wrong -version. +version (note, however, that this will not detect other ABI mismatches, +such as LFS or reentrancy). - assert (("libev version mismatch", - ev_version_major () == EV_VERSION_MAJOR - && ev_version_minor () >= EV_VERSION_MINOR)); + assert (("libev version mismatch", + ev_version_major () == EV_VERSION_MAJOR + && ev_version_minor () >= EV_VERSION_MINOR)); =item unsigned int ev_supported_backends () @@ -142,42 +220,47 @@ Example: make sure we have the epoll method, because yeah this is cool and a must have and can we have a torrent of it please!!!11 - assert (("sorry, no epoll, no sex", - ev_supported_backends () & EVBACKEND_EPOLL)); + assert (("sorry, no epoll, no sex", + ev_supported_backends () & EVBACKEND_EPOLL)); =item unsigned int ev_recommended_backends () -Return the set of all backends compiled into this binary of libev and also -recommended for this platform. This set is often smaller than the one -returned by C, as for example kqueue is broken on -most BSDs and will not be autodetected unless you explicitly request it -(assuming you know what you are doing). This is the set of backends that -libev will probe for if you specify no backends explicitly. +Return the set of all backends compiled into this binary of libev and +also recommended for this platform, meaning it will work for most file +descriptor types. This set is often smaller than the one returned by +C, as for example kqueue is broken on most BSDs +and will not be auto-detected unless you explicitly request it (assuming +you know what you are doing). This is the set of backends that libev will +probe for if you specify no backends explicitly. =item unsigned int ev_embeddable_backends () Returns the set of backends that are embeddable in other event loops. This -is the theoretical, all-platform, value. To find which backends -might be supported on the current system, you would need to look at -C, likewise for -recommended ones. +value is platform-specific but can include backends not available on the +current system. To find which embeddable backends might be supported on +the current system, you would need to look at C, likewise for recommended ones. See the description of C watchers for more info. -=item ev_set_allocator (void *(*cb)(void *ptr, size_t size)) +=item ev_set_allocator (void *(*cb)(void *ptr, long size)) -Sets the allocation function to use (the prototype and semantics are -identical to the realloc C function). It is used to allocate and free -memory (no surprises here). If it returns zero when memory needs to be -allocated, the library might abort or take some potentially destructive -action. The default is your system realloc function. +Sets the allocation function to use (the prototype is similar - the +semantics are identical to the C C89/SuS/POSIX function). It is +used to allocate and free memory (no surprises here). If it returns zero +when memory needs to be allocated (C), the library might abort +or take some potentially destructive action. + +Since some systems (at least OpenBSD and Darwin) fail to implement +correct C semantics, libev will use a wrapper around the system +C and C functions by default. You could override this function in high-availability programs to, say, free some memory if it cannot allocate memory, to use a special allocator, or even to sleep a while and retry until some memory is available. Example: Replace the libev allocator with one that waits a bit and then -retries). +retries (example requires a standards-compliant C). static void * persistent_realloc (void *ptr, size_t size) @@ -196,12 +279,12 @@ ... ev_set_allocator (persistent_realloc); -=item ev_set_syserr_cb (void (*cb)(const char *msg)); +=item ev_set_syserr_cb (void (*cb)(const char *msg)) -Set the callback function to call on a retryable syscall error (such +Set the callback function to call on a retryable system call error (such as failed select, poll, epoll_wait). The message is a printable string indicating the system call or subsystem causing the problem. If this -callback is set, then libev will expect it to remedy the sitution, no +callback is set, then libev will expect it to remedy the situation, no matter what, when it returns. That is, libev will generally retry the requested operation, or, if the condition doesn't go away, do bad stuff (such as abort). @@ -218,32 +301,78 @@ ... ev_set_syserr_cb (fatal_error); +=item ev_feed_signal (int signum) + +This function can be used to "simulate" a signal receive. It is completely +safe to call this function at any time, from any context, including signal +handlers or random threads. + +Its main use is to customise signal handling in your process, especially +in the presence of threads. For example, you could block signals +by default in all threads (and specifying C when +creating any loops), and in one thread, use C or any other +mechanism to wait for signals, then "deliver" them to libev by calling +C. + =back -=head1 FUNCTIONS CONTROLLING THE EVENT LOOP +=head1 FUNCTIONS CONTROLLING EVENT LOOPS -An event loop is described by a C. The library knows two -types of such loops, the I loop, which supports signals and child -events, and dynamically created loops which do not. - -If you use threads, a common model is to run the default event loop -in your main thread (or in a separate thread) and for each thread you -create, you also create another event loop. Libev itself does no locking -whatsoever, so if you mix calls to the same event loop in different -threads, make sure you lock (this is usually a bad idea, though, even if -done correctly, because it's hideous and inefficient). +An event loop is described by a C (the C is +I optional in this case unless libev 3 compatibility is disabled, as +libev 3 had an C function colliding with the struct name). + +The library knows two types of such loops, the I loop, which +supports child process events, and dynamically created event loops which +do not. =over 4 =item struct ev_loop *ev_default_loop (unsigned int flags) -This will initialise the default event loop if it hasn't been initialised -yet and return it. If the default loop could not be initialised, returns -false. If it already was initialised it simply returns it (and ignores the -flags. If that is troubling you, check C afterwards). +This returns the "default" event loop object, which is what you should +normally use when you just need "the event loop". Event loop objects and +the C parameter are described in more detail in the entry for +C. + +If the default loop is already initialised then this function simply +returns it (and ignores the flags. If that is troubling you, check +C afterwards). Otherwise it will create it with the given +flags, which should almost always be C<0>, unless the caller is also the +one calling C or otherwise qualifies as "the main program". If you don't know what event loop to use, use the one returned from this -function. +function (or via the C macro). + +Note that this function is I thread-safe, so if you want to use it +from multiple threads, you have to employ some kind of mutex (note also +that this case is unlikely, as loops cannot be shared easily between +threads anyway). + +The default loop is the only loop that can handle C watchers, +and to do this, it always registers a handler for C. If this is +a problem for your application you can either create a dynamic loop with +C which doesn't do that, or you can simply overwrite the +C signal handler I calling C. + +Example: This is the most typical usage. + + if (!ev_default_loop (0)) + fatal ("could not initialise libev, bad $LIBEV_FLAGS in environment?"); + +Example: Restrict libev to the select and poll backends, and do not allow +environment settings to be taken into account: + + ev_default_loop (EVBACKEND_POLL | EVBACKEND_SELECT | EVFLAG_NOENV); + +=item struct ev_loop *ev_loop_new (unsigned int flags) + +This will create and initialise a new event loop object. If the loop +could not be initialised, returns false. + +This function is thread-safe, and one common way to use libev with +threads is indeed to create one loop per thread, and using the default +loop in the "main" or "initial" thread. The flags argument can be used to specify special behaviour or specific backends to use, and is usually specified as C<0> (or C). @@ -259,72 +388,224 @@ =item C -If this flag bit is ored into the flag value (or the program runs setuid +If this flag bit is or'ed into the flag value (or the program runs setuid or setgid) then libev will I look at the environment variable C. Otherwise (the default), this environment variable will override the flags completely if it is found in the environment. This is useful to try out specific backends to test their performance, or to work around bugs. +=item C + +Instead of calling C manually after a fork, you can also +make libev check for a fork in each iteration by enabling this flag. + +This works by calling C on every iteration of the loop, +and thus this might slow down your event loop if you do a lot of loop +iterations and little real work, but is usually not noticeable (on my +GNU/Linux system for example, C is actually a simple 5-insn sequence +without a system call and thus I fast, but my GNU/Linux system also has +C which is even faster). + +The big advantage of this flag is that you can forget about fork (and +forget about forgetting to tell libev about forking) when you use this +flag. + +This flag setting cannot be overridden or specified in the C +environment variable. + +=item C + +When this flag is specified, then libev will not attempt to use the +I API for its C watchers. Apart from debugging and +testing, this flag can be useful to conserve inotify file descriptors, as +otherwise each loop using C watchers consumes one inotify handle. + +=item C + +When this flag is specified, then libev will attempt to use the +I API for its C (and C) watchers. This API +delivers signals synchronously, which makes it both faster and might make +it possible to get the queued signal data. It can also simplify signal +handling with threads, as long as you properly block signals in your +threads that are not interested in handling them. + +Signalfd will not be used by default as this changes your signal mask, and +there are a lot of shoddy libraries and programs (glib's threadpool for +example) that can't properly initialise their signal masks. + +=item C + +When this flag is specified, then libev will avoid to modify the signal +mask. Specifically, this means you ahve to make sure signals are unblocked +when you want to receive them. + +This behaviour is useful when you want to do your own signal handling, or +want to handle signals only in specific threads and want to avoid libev +unblocking the signals. + +This flag's behaviour will become the default in future versions of libev. + =item C (value 1, portable select backend) This is your standard select(2) backend. Not I standard, as libev tries to roll its own fd_set with no limits on the number of fds, but if that fails, expect a fairly low limit on the number of fds when -using this backend. It doesn't scale too well (O(highest_fd)), but its usually -the fastest backend for a low number of fds. +using this backend. It doesn't scale too well (O(highest_fd)), but its +usually the fastest backend for a low number of (low-numbered :) fds. + +To get good performance out of this backend you need a high amount of +parallelism (most of the file descriptors should be busy). If you are +writing a server, you should C in a loop to accept as many +connections as possible during one iteration. You might also want to have +a look at C to increase the amount of +readiness notifications you get per iteration. + +This backend maps C to the C set and C to the +C set (and to work around Microsoft Windows bugs, also onto the +C set on that platform). =item C (value 2, poll backend, available everywhere except on windows) -And this is your standard poll(2) backend. It's more complicated than -select, but handles sparse fds better and has no artificial limit on the -number of fds you can use (except it will slow down considerably with a -lot of inactive fds). It scales similarly to select, i.e. O(total_fds). +And this is your standard poll(2) backend. It's more complicated +than select, but handles sparse fds better and has no artificial +limit on the number of fds you can use (except it will slow down +considerably with a lot of inactive fds). It scales similarly to select, +i.e. O(total_fds). See the entry for C, above, for +performance tips. + +This backend maps C to C, and +C to C. =item C (value 4, Linux) +Use the linux-specific epoll(7) interface (for both pre- and post-2.6.9 +kernels). + For few fds, this backend is a bit little slower than poll and select, -but it scales phenomenally better. While poll and select usually scale like -O(total_fds) where n is the total number of fds (or the highest fd), epoll scales -either O(1) or O(active_fds). - -While stopping and starting an I/O watcher in the same iteration will -result in some caching, there is still a syscall per such incident -(because the fd could point to a different file description now), so its -best to avoid that. Also, dup()ed file descriptors might not work very -well if you register events for both fds. - -Please note that epoll sometimes generates spurious notifications, so you -need to use non-blocking I/O or other means to avoid blocking when no data -(or space) is available. +but it scales phenomenally better. While poll and select usually scale +like O(total_fds) where n is the total number of fds (or the highest fd), +epoll scales either O(1) or O(active_fds). + +The epoll mechanism deserves honorable mention as the most misdesigned +of the more advanced event mechanisms: mere annoyances include silently +dropping file descriptors, requiring a system call per change per file +descriptor (and unnecessary guessing of parameters), problems with dup, +returning before the timeout value, resulting in additional iterations +(and only giving 5ms accuracy while select on the same platform gives +0.1ms) and so on. The biggest issue is fork races, however - if a program +forks then I parent and child process have to recreate the epoll +set, which can take considerable time (one syscall per file descriptor) +and is of course hard to detect. + +Epoll is also notoriously buggy - embedding epoll fds I work, but +of course I, and epoll just loves to report events for totally +I file descriptors (even already closed ones, so one cannot +even remove them from the set) than registered in the set (especially +on SMP systems). Libev tries to counter these spurious notifications by +employing an additional generation counter and comparing that against the +events to filter out spurious ones, recreating the set when required. Last +not least, it also refuses to work with some file descriptors which work +perfectly fine with 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. The +sleep time ensures that libev will not poll for I/O events more often then +once per this interval, on average. + +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. Note that if +you do transactions with the outside world and you can't increase the +parallelity, then this setting will limit your transaction rate (if you +need to poll once per transaction and the I/O collect interval is 0.01, +then you can't do more than 100 transactions per second). + +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. + +Example: we only need 0.1s timeout granularity, and we wish not to poll +more often than 100 times per second: + + ev_set_timeout_collect_interval (EV_DEFAULT_UC_ 0.1); + ev_set_io_collect_interval (EV_DEFAULT_UC_ 0.01); + +=item ev_invoke_pending (loop) + +This call will simply invoke all pending watchers while resetting their +pending state. Normally, C does this automatically when required, +but when overriding the invoke callback this call comes handy. This +function can be invoked from a watcher - this can be useful for example +when you want to do some lengthy calculation and want to pass further +event handling to another thread (you still have to make sure only one +thread executes within C or C of course). + +=item int ev_pending_count (loop) + +Returns the number of pending watchers - zero indicates that no watchers +are pending. + +=item ev_set_invoke_pending_cb (loop, void (*invoke_pending_cb)(EV_P)) + +This overrides the invoke pending functionality of the loop: Instead of +invoking all pending watchers when there are any, C will call +this callback instead. This is useful, for example, when you want to +invoke the actual watchers inside another context (another thread etc.). + +If you want to reset the callback, use C as new +callback. + +=item ev_set_loop_release_cb (loop, void (*release)(EV_P), void (*acquire)(EV_P)) + +Sometimes you want to share the same loop between multiple threads. This +can be done relatively simply by putting mutex_lock/unlock calls around +each call to a libev function. + +However, C can run an indefinite time, so it is not feasible +to wait for it to return. One way around this is to wake up the event +loop via C and C, another way is to set these +I and I callbacks on the loop. + +When set, then C will be called just before the thread is +suspended waiting for new events, and C is called just +afterwards. + +Ideally, C will just call your mutex_unlock function, and +C will just call the mutex_lock function again. + +While event loop modifications are allowed between invocations of +C and C (that's their only purpose after all), no +modifications done will affect the event loop, i.e. adding watchers will +have no effect on the set of file descriptors being watched, or the time +waited. Use an C watcher to wake up C when you want it +to take note of any changes you made. + +In theory, threads executing C will be async-cancel safe between +invocations of C and C. + +See also the locking example in the C section later in this +document. + +=item ev_set_userdata (loop, void *data) + +=item void *ev_userdata (loop) + +Set and retrieve a single C associated with a loop. When +C has never been called, then C returns +C<0>. + +These two functions can be used to associate arbitrary data with a loop, +and are intended solely for the C, C and +C callbacks described above, but of course can be (ab-)used for +any other purpose as well. + +=item ev_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 -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); +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 an opaque structure that you allocate and register to record +your interest in some event. To make a concrete example, imagine 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, ev_io *w, int revents) + { + ev_io_stop (w); + ev_break (loop, EVBREAK_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_run (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 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 -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 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 is +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 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 @@ -577,7 +1127,7 @@ The file descriptor in the C watcher has become readable and/or writable. -=item C +=item C The C watcher has timed out. @@ -605,13 +1155,13 @@ =item C -All C watchers are invoked just I C starts +All C watchers are invoked just I C starts to gather new events, and all C watchers are invoked just after -C has gathered them, but before it invokes any callbacks for any +C has gathered them, but before it invokes any callbacks for any received events. Callbacks of both watcher types can start and stop as many watchers as they want, and all of them will be taken into account (for example, a C watcher might start an idle watcher to keep -C from blocking). +C from blocking). =item C @@ -622,27 +1172,42 @@ The event loop has been resumed in the child process after fork (see C). +=item C + +The event loop is about to be destroyed (see C). + +=item C + +The given async watcher has been asynchronously notified (see C). + +=item C + +Not ever sent (or otherwise used) by libev itself, but can be freely used +by libev users to signal watchers (e.g. via 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) @@ -657,10 +1222,16 @@ 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. -=item C (ev_TYPE *, [args]) +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 *watcher, [args]) This macro initialises the type-specific parts of a watcher. You need to call C at least once before you call this macro, but you can @@ -671,25 +1242,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. -=item C (loop *, ev_TYPE *watcher) +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. -=item C (loop *, ev_TYPE *watcher) +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) @@ -702,8 +1286,9 @@ 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) @@ -714,66 +1299,290 @@ Change the callback. You can change the callback at virtually any time (modulo threads). -=back +=item ev_set_priority (ev_TYPE *watcher, int 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). + +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. + +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. + +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 :). + +See L, below, for a more thorough treatment of +priorities. +=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. + +=item ev_feed_event (loop, ev_TYPE *watcher, int revents) + +Feeds the given event set into the event loop, as if the specified event +had happened for the specified watcher (which must be a pointer to an +initialised but not necessarily started event watcher). Obviously you must +not free the watcher as long as it has pending events. + +Stopping the watcher, letting libev invoke it, or calling +C will clear the pending event, even if the watcher was +not started in the first place. + +See also C and C for related +functions that do not need a watcher. + +=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; - } - -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)); - } + 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): + + #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)); + } + +=head2 WATCHER STATES + +There are various watcher states mentioned throughout this manual - +active, pending and so on. In this section these states and the rules to +transition between them will be described in more detail - and while these +rules might look complicated, they usually do "the right thing". + +=over 4 + +=item initialiased + +Before a watcher can be registered with the event looop it has to be +initialised. This can be done with a call to C, or calls to +C followed by the watcher-specific C function. + +In this state it is simply some block of memory that is suitable for use +in an event loop. It can be moved around, freed, reused etc. at will. + +=item started/running/active + +Once a watcher has been started with a call to C it becomes +property of the event loop, and is actively waiting for events. While in +this state it cannot be accessed (except in a few documented ways), moved, +freed or anything else - the only legal thing is to keep a pointer to it, +and call libev functions on it that are documented to work on active watchers. + +=item pending + +If a watcher is active and libev determines that an event it is interested +in has occurred (such as a timer expiring), it will become pending. It will +stay in this pending state until either it is stopped or its callback is +about to be invoked, so it is not normally pending inside the watcher +callback. + +The watcher might or might not be active while it is pending (for example, +an expired non-repeating timer can be pending but no longer active). If it +is stopped, it can be freely accessed (e.g. by calling C), +but it is still property of the event loop at this time, so cannot be +moved, freed or reused. And if it is active the rules described in the +previous item still apply. + +It is also possible to feed an event on a watcher that is not active (e.g. +via C), in which case it becomes pending without being +active. + +=item stopped + +A watcher can be stopped implicitly by libev (in which case it might still +be pending), or explicitly by calling its C function. The +latter will clear any pending state the watcher might be in, regardless +of whether it was active or not, so stopping a watcher explicitly before +freeing it is often a good idea. + +While stopped (and not pending) the watcher is essentially in the +initialised state, that is it can be reused, moved, modified in any way +you wish. + +=back + +=head2 WATCHER PRIORITY MODELS + +Many event loops support I, which are usually small +integers that influence the ordering of event callback invocation +between watchers in some way, all else being equal. + +In libev, Watcher priorities can be set using C. See its +description for the more technical details such as the actual priority +range. + +There are two common ways how these these priorities are being interpreted +by event loops: + +In the more common lock-out model, higher priorities "lock out" invocation +of lower priority watchers, which means as long as higher priority +watchers receive events, lower priority watchers are not being invoked. + +The less common only-for-ordering model uses priorities solely to order +callback invocation within a single event loop iteration: Higher priority +watchers are invoked before lower priority ones, but they all get invoked +before polling for new events. + +Libev uses the second (only-for-ordering) model for all its watchers +except for idle watchers (which use the lock-out model). + +The rationale behind this is that implementing the lock-out model for +watchers is not well supported by most kernel interfaces, and most event +libraries will just poll for the same events again and again as long as +their callbacks have not been executed, which is very inefficient in the +common case of one high-priority watcher locking out a mass of lower +priority ones. + +Static (ordering) priorities are most useful when you have two or more +watchers handling the same resource: a typical usage example is having an +C watcher to receive data, and an associated C to handle +timeouts. Under load, data might be received while the program handles +other jobs, but since timers normally get invoked first, the timeout +handler will be executed before checking for data. In that case, giving +the timer a lower priority than the I/O watcher ensures that I/O will be +handled first even under adverse conditions (which is usually, but not +always, what you want). + +Since idle watchers use the "lock-out" model, meaning that idle watchers +will only be executed when no same or higher priority watchers have +received events, they can be used to implement the "lock-out" model when +required. + +For example, to emulate how many other event libraries handle priorities, +you can associate an C watcher to each such watcher, and in +the normal watcher callback, you just start the idle watcher. The real +processing is done in the idle watcher callback. This causes libev to +continuously poll and process kernel event data for the watcher, but when +the lock-out case is known to be rare (which in turn is rare :), this is +workable. + +Usually, however, the lock-out model implemented that way will perform +miserably under the type of load it was designed to handle. In that case, +it might be preferable to stop the real watcher before starting the +idle watcher, so the kernel will not have to process the event in case +the actual processing will be delayed for considerable time. + +Here is an example of an I/O watcher that should run at a strictly lower +priority than the default, and which should only process data when no +other events are pending: + + ev_idle idle; // actual processing watcher + ev_io io; // actual event watcher + + static void + io_cb (EV_P_ ev_io *w, int revents) + { + // stop the I/O watcher, we received the event, but + // are not yet ready to handle it. + ev_io_stop (EV_A_ w); + + // start the idle watcher to handle the actual event. + // it will not be executed as long as other watchers + // with the default priority are receiving events. + ev_idle_start (EV_A_ &idle); + } + + static void + idle_cb (EV_P_ ev_idle *w, int revents) + { + // actual processing + read (STDIN_FILENO, ...); + + // have to start the I/O watcher again, as + // we have handled the event + ev_io_start (EV_P_ &io); + } + + // initialisation + ev_idle_init (&idle, idle_cb); + ev_io_init (&io, io_cb, STDIN_FILENO, EV_READ); + ev_io_start (EV_DEFAULT_ &io); + +In the "real" world, it might also be beneficial to start a timer, so that +low-priority connections can not be locked out forever under load. This +enables your program to keep a lower latency for important connections +during short periods of high load, while not completely locking out less +important ones. =head1 WATCHER TYPES @@ -807,30 +1616,125 @@ 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). The same applies to file +descriptors for which non-blocking operation makes no sense (such as +files) - libev doesn't guarantee any specific behaviour in that case. 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 The special problem of accept()ing when you can't + +Many implementations of the POSIX C function (for example, +found in post-2004 Linux) have the peculiar behaviour of not removing a +connection from the pending queue in all error cases. + +For example, larger servers often run out of file descriptors (because +of resource limits), causing C to fail with C but not +rejecting the connection, leading to libev signalling readiness on +the next iteration again (the connection still exists after all), and +typically causing the program to loop at 100% CPU usage. + +Unfortunately, the set of errors that cause this issue differs between +operating systems, there is usually little the app can do to remedy the +situation, and no known thread-safe method of removing the connection to +cope with overload is known (to me). + +One of the easiest ways to handle this situation is to just ignore it +- when the program encounters an overload, it will just loop until the +situation is over. While this is a form of busy waiting, no OS offers an +event-based way to handle this situation, so it's the best one can do. + +A better way to handle the situation is to log any errors other than +C and C, making sure not to flood the log with such +messages, and continue as usual, which at least gives the user an idea of +what could be wrong ("raise the ulimit!"). For extra points one could stop +the C watcher on the listening fd "for a while", which reduces CPU +usage. + +If your program is single-threaded, then you could also keep a dummy file +descriptor for overload situations (e.g. by opening F), and +when you run into C or C, close it, run C, +close that fd, and create a new dummy fd. This will gracefully refuse +clients under typical overload conditions. + +The last way to handle it is to simply log the error and C, as +is often done with C failures, but this results in an easy +opportunity for a DoS attack. + +=head3 Watcher-Specific Functions =over 4 @@ -839,8 +1743,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] @@ -852,23 +1756,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_run (loop, 0); =head2 C - relative and optionally repeating timeouts @@ -877,22 +1783,244 @@ 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 (not I, so on systems with very low-resolution clocks this +might introduce a small delay). If multiple timers become ready during the +same loop iteration then the ones with earlier time-out values are invoked +before ones of the same priority with later time-out values (but this is +no longer true when a callback calls C recursively). + +=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_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 occurred, 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->repeat = 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_init (timer, callback); + last_activity = ev_now (loop); + callback (loop, timer, EV_TIMER); + +And when there is some activity, simply store the current time in +C, no libev calls at all: + + last_activity = 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 The special problems of suspended animation + +When you leave the server world it is quite customary to hit machines that +can suspend/hibernate - what happens to the clocks during such a suspend? + +Some quick tests made with a Linux 2.6.28 indicate that a suspend freezes +all processes, while the clocks (C, C) continue +to run until the system is suspended, but they will not advance while the +system is suspended. That means, on resume, it will be as if the program +was frozen for a few seconds, but the suspend time will not be counted +towards C when a monotonic clock source is used. The real time +clock advanced as expected, but if it is used as sole clocksource, then a +long suspend would be detected as a time jump by libev, and timers would +be adjusted accordingly. + +I would not be surprised to see different behaviour in different between +operating systems, OS versions or even different hardware. + +The other form of suspend (job control, or sending a SIGSTOP) will see a +time jump in the monotonic clocks and the realtime clock. If the program +is suspended for a very long time, and monotonic clock sources are in use, +then you can expect Cs to expire as the full suspension time +will be counted towards the timers. When no monotonic clock source is in +use, then libev will again assume a timejump and adjust accordingly. + +It might be beneficial for this latter case to call C +and C in code that handles C, to at least get +deterministic behaviour in this case (you can do nothing against +C). + +=head3 Watcher-Specific Functions and Data Members =over 4 @@ -900,89 +2028,84 @@ =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 repeating, either start it if necessary (with the repeat -value), or reset the running timer to the repeat value. +If the timer is started but non-repeating, stop it (as if it timed out). -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 C=C=C<60> and calling -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 stop the timer, and again will automatically restart it if -need be. +If the timer is repeating, either start it if necessary (with the +C value), or reset the running timer to the C value. -You can also ignore the C value and C altogether -and only ever use the C value: +This sounds a bit complicated, see L, above, for a +usage example. - 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); +=item ev_tstamp ev_timer_remaining (loop, ev_timer *) + +Returns the remaining time until a timer fires. If the timer is active, +then this time is relative to the current event loop time, otherwise it's +the timeout value currently configured. -This is more efficient then stopping/starting the timer eahc time you want -to modify its timeout value. +That is, after an C, C returns +C<5>. When the timer is started and one second passes, C +will return C<4>. When the timer expires and is restarted, it will return +roughly C<7> (likely slightly less as callback invocation takes some time, +too), and so on. =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_run (loop, 0); + + // and in some piece of code that gets executed on any "activity": + // reset the timeout to start ticking again at 10 seconds + ev_timer_again (&mytimer); =head2 C - to cron or not to cron? @@ -990,76 +2113,104 @@ Periodic watchers are also timers of a kind, but they are very versatile (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). +Unlike C, periodic watchers are not based on real time (or +relative time, the physical time that passes) but on wall clock time +(absolute time, the thing you can read on your calender or clock). The +difference is that wall clock time can run faster or slower than real +time, and time jumps are not uncommon (e.g. when you adjust your +wrist-watch). + +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 a year or more to trigger the event (unlike an +C, which would still trigger roughly 10 seconds after starting +it, as it uses a relative timeout). + +C watchers can also be used to implement vastly more complex +timers, such as triggering an event on each "midnight, local time", or +other complicated rules. This cannot be done with C watchers, as +those cannot react to time jumps. + +As with timers, the callback is guaranteed to be invoked only when the +point in time where it is supposed to trigger has passed. If multiple +timers become ready during the same loop iteration then the ones with +earlier time-out values are invoked before ones with later time-out values +(but this is no longer true when a callback calls C recursively). -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. +=head3 Watcher-Specific Functions and Data Members =over 4 -=item ev_periodic_init (ev_periodic *, callback, ev_tstamp at, ev_tstamp interval, reschedule_cb) +=item ev_periodic_init (ev_periodic *, callback, ev_tstamp offset, ev_tstamp interval, reschedule_cb) -=item ev_periodic_set (ev_periodic *, ev_tstamp after, ev_tstamp repeat, reschedule_cb) +=item ev_periodic_set (ev_periodic *, ev_tstamp offset, ev_tstamp interval, 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: +Lots of arguments, let's sort it out... There are basically three modes of +operation, and we will explain them from simplest to most complex: =over 4 -=item * absolute timer (interval = reschedule_cb = 0) +=item * absolute timer (offset = absolute time, interval = 0, 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 be stopped and invoked when the system clock reaches or surpasses +this point in time. -=item * non-repeating interval timer (interval > 0, reschedule_cb = 0) +=item * repeating interval timer (offset = offset within interval, 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. - -This can be used to create timers that do not drift with respect to system -time: +C time (for some integer N, which can also be +negative) and then repeat, regardless of any time jumps. The C +argument is merely an offset into the C periods. + +This can be used to create timers that do not drift with respect to the +system clock, for example, here is an C that triggers each +hour, on the hour (with respect to UTC): 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. Another way to think about it (for the mathematically inclined) is that C will try to run the callback in this mode at the next possible -time where C