--- libev/ev.pod 2007/12/23 03:50:10 1.105 +++ libev/ev.pod 2019/06/25 04:58:36 1.452 @@ -1,58 +1,96 @@ +=encoding utf-8 + =head1 NAME libev - a high performance full-featured event loop written in C =head1 SYNOPSIS - #include + #include =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 */ - } + // every watcher type has its own typedef'd struct + // with the name ev_TYPE + ev_io stdin_watcher; + ev_timer timeout_watcher; - static void - timeout_cb (EV_P_ struct ev_timer *w, int revents) - { - /* puts ("timeout"); */ - ev_unloop (EV_A_ EVUNLOOP_ONE); /* leave one loop call */ - } + // 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); - int - main (void) - { - struct ev_loop *loop = ev_default_loop (0); + // this causes all nested ev_run's to stop iterating + ev_break (EV_A_ EVBREAK_ALL); + } - /* 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); + // 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); + } - /* simple non-repeating 5.5 second timeout */ - ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.); - ev_timer_start (loop, &timeout_watcher); + int + main (void) + { + // use the default event loop unless you have special needs + struct ev_loop *loop = EV_DEFAULT; - /* loop till timeout or data ready */ - ev_loop (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); - return 0; - } + // now wait for events to arrive + ev_run (loop, 0); -=head1 DESCRIPTION + // break was called, so exit + return 0; + } + +=head1 ABOUT THIS DOCUMENT -The newest version of this document is also available as a html-formatted +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. +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 occurring), and it will manage @@ -69,16 +107,17 @@ =head2 FEATURES -Libev supports C, C, the Linux-specific aio and C +interfaces, 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 @@ -86,23 +125,46 @@ =head2 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 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. +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 (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 some floatingpoint value. Unlike the name -component C might indicate, it is also used for time differences -throughout libev. +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. + =head1 GLOBAL FUNCTIONS @@ -115,13 +177,20 @@ 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 subsecond-resolution C. +Sleep for the given interval: The current thread will be blocked +until either it is interrupted or the given time interval has +passed (approximately - it might return a bit earlier even if not +interrupted). Returns immediately if C<< interval <= 0 >>. + +Basically this is a sub-second-resolution C. + +The range of the C is limited - libev only guarantees to work +with sleep times of up to one day (C<< interval <= 86400 >>). =item int ev_version_major () @@ -142,11 +211,12 @@ 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 () @@ -158,47 +228,71 @@ 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, long size)) +=item ev_set_allocator (void *(*cb)(void *ptr, long size) throw ()) Sets the allocation function to use (the prototype is similar - the -semantics is 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. +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: The following is the C function that libev itself uses +which should work with C and C functions of all kinds and +is probably a good basis for your own implementation. + + static void * + ev_realloc_emul (void *ptr, long size) EV_NOEXCEPT + { + if (size) + return realloc (ptr, size); + + free (ptr); + return 0; + } + Example: Replace the libev allocator with one that waits a bit and then -retries). +retries. static void * persistent_realloc (void *ptr, size_t size) { + if (!size) + { + free (ptr); + return 0; + } + for (;;) { void *newptr = realloc (ptr, size); @@ -213,12 +307,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) throw ()) -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). @@ -235,32 +329,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). @@ -276,33 +416,70 @@ =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. +useful to try out specific backends to test their performance, to work +around bugs, or to make libev threadsafe (accessing environment variables +cannot be done in a threadsafe way, but usually it works if no other +thread modifies them). =item C -Instead of calling C or C manually after -a fork, you can also make libev check for a fork in each iteration by -enabling this flag. +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 -Linux system for example, C is actually a simple 5-insn sequence -without a syscall and thus I fast, but my Linux system also has -C which is even faster). +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). (Update: glibc +versions 2.25 apparently removed the C optimisation again). 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. +forget about forgetting to tell libev about forking, although you still +have to ignore C) when you use this flag. -This flag setting cannot be overriden or specified in the C +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 have 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. + +It's also required by POSIX in a threaded program, as libev calls +C, whose behaviour is officially unspecified. + +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 @@ -312,11 +489,15 @@ 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 -parallelity (most of the file descriptors should be busy). If you are +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 -readyness notifications you get per iteration. +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) @@ -327,40 +508,125 @@ 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) -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). The epoll design has a number -of shortcomings, such as silently dropping events in some hard-to-detect -cases and rewiring a syscall per fd change, no fork support and bad -support for dup. +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 total_fds 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. Epoll also erroneously rounds down timeouts, but gives you +no way to know when and by how much, so sometimes you have to busy-wait +because epoll returns immediately despite a nonzero timeout. And last +not least, it also refuses to work with some file descriptors which work +perfectly fine with C or C. + +To work around all these problem, the current version of libev uses its +epoll backend as a fallback for file descriptor types that do not work. Or +falls back completely to epoll if the kernel acts up. + +This backend maps C and C in the same way as +C. =item C (value 8, most BSD clones) Kqueue deserves special mention, as at the time of this writing, it was broken on all BSDs except NetBSD (usually it doesn't work reliably with anything but sockets and pipes, except on Darwin, where of course -it's completely useless). For this reason it's not being "autodetected" -unless you explicitly specify it explicitly in the flags (i.e. using +it's completely useless). Unlike epoll, however, whose brokenness +is by design, these kqueue bugs can (and eventually will) be fixed +without API changes to existing programs. For this reason it's not being +"auto-detected" unless you explicitly specify it in the flags (i.e. using C) or libev was compiled on a known-to-be-good (-enough) system like NetBSD. @@ -371,8 +637,9 @@ It scales in the same way as the epoll backend, but the interface to the kernel is more efficient (which says nothing about its actual speed, of course). While stopping, setting and starting an I/O watcher does never -cause an extra syscall as with C, it still adds up to -two event changes per incident, support for C is very bad and it +cause an extra system call as with C, it still adds up to +two event changes per incident. Support for C is very bad (you +might have to leak fd's on fork, but it's more sane than epoll) and it drops fds silently in similarly hard-to-detect cases. This backend usually performs well under most conditions. @@ -381,8 +648,12 @@ everywhere, so you might need to test for this. And since it is broken almost everywhere, you should only use it when you have a lot of sockets (for which it usually works), by embedding it into another event loop -(e.g. C or C) and using it only for -sockets. +(e.g. C or C (but C is of course +also broken on OS X)) and, did I mention it, using it only for sockets. + +This backend maps C into an C kevent with +C, and C into an C kevent with +C. =item C (value 16, Solaris 8) @@ -396,119 +667,160 @@ This uses the Solaris 10 event port mechanism. As with everything on Solaris, it's really slow, but it still scales very well (O(active_fds)). -Please note that solaris event ports can deliver a lot of spurious -notifications, so you need to use non-blocking I/O or other means to avoid -blocking when no data (or space) is available. - While this backend scales well, it requires one system call per active file descriptor per loop iteration. For small and medium numbers of file descriptors a "slow" C or C backend might perform better. +On the positive side, this backend actually performed fully to +specification in all tests and is fully embeddable, which is a rare feat +among the OS-specific backends (I vastly prefer correctness over speed +hacks). + +On the negative side, the interface is I - so bizarre that +even sun itself gets it wrong in their code examples: The event polling +function sometimes returns events to the caller even though an error +occurred, but with no indication whether it has done so or not (yes, it's +even documented that way) - deadly for edge-triggered interfaces where you +absolutely have to know whether an event occurred or not because you have +to re-arm the watcher. + +Fortunately libev seems to be able to work around these idiocies. + +This backend maps C and C in the same way as +C. + =item C Try all backends (even potentially broken ones that wouldn't be tried with C). Since this is a mask, you can do stuff such as C. -It is definitely not recommended to use this flag. +It is definitely not recommended to use this flag, use whatever +C returns, or simply do not specify a backend +at all. + +=item C + +Not a backend at all, but a mask to select all backend bits from a +C value, in case you want to mask out any backends from a flags +value (e.g. when modifying the C environment variable). =back -If one or more of these are ored into the flags value, then only these -backends will be tried (in the reverse order as given here). If none are -specified, most compiled-in backend will be tried, usually in reverse -order of their flag values :) +If one or more of the backend flags are or'ed into the flags value, +then only these backends will be tried (in the reverse order as listed +here). If none are specified, all backends in C will be tried. -The most typical usage is like this: - - if (!ev_default_loop (0)) - fatal ("could not initialise libev, bad $LIBEV_FLAGS in environment?"); - -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); - -Use whatever libev has to offer, but make sure that kqueue is used if -available (warning, breaks stuff, best use only with your own private -event loop and only if you know the OS supports your types of fds): +Example: Try to create a event loop that uses epoll and nothing else. - ev_default_loop (ev_recommended_backends () | EVBACKEND_KQUEUE); + struct ev_loop *epoller = ev_loop_new (EVBACKEND_EPOLL | EVFLAG_NOENV); + if (!epoller) + fatal ("no epoll found here, maybe it hides under your chair"); -=item struct ev_loop *ev_loop_new (unsigned int flags) +Example: Use whatever libev has to offer, but make sure that kqueue is +used if available. -Similar to C, but always creates a new event loop that is -always distinct from the default loop. Unlike the default loop, it cannot -handle signal and child watchers, and attempts to do so will be greeted by -undefined behaviour (or a failed assertion if assertions are enabled). + struct ev_loop *loop = ev_loop_new (ev_recommended_backends () | EVBACKEND_KQUEUE); -Example: Try to create a event loop that uses epoll and nothing else. +Example: Similarly, on linux, you mgiht want to take advantage of the +linux aio backend if possible, but fall back to something else if that +isn't available. - struct ev_loop *epoller = ev_loop_new (EVBACKEND_EPOLL | EVFLAG_NOENV); - if (!epoller) - fatal ("no epoll found here, maybe it hides under your chair"); + struct ev_loop *loop = ev_loop_new (ev_recommended_backends () | EVBACKEND_LINUXAIO); -=item ev_default_destroy () +=item ev_loop_destroy (loop) -Destroys the default loop again (frees all memory and kernel state +Destroys an event loop object (frees all memory and kernel state etc.). None of the active event watchers will be stopped in the normal sense, so e.g. C might still return true. It is your -responsibility to either stop all watchers cleanly yoursef I +responsibility to either stop all watchers cleanly yourself I calling this function, or cope with the fact afterwards (which is usually the easiest thing, you can just ignore the watchers and/or C them for example). -Note that certain global state, such as signal state, will not be freed by -this function, and related watchers (such as signal and child watchers) -would need to be stopped manually. - -In general it is not advisable to call this function except in the -rare occasion where you really need to free e.g. the signal handling -pipe fds. If you need dynamically allocated loops it is better to use -C and C). +Note that certain global state, such as signal state (and installed signal +handlers), will not be freed by this function, and related watchers (such +as signal and child watchers) would need to be stopped manually. + +This function is normally used on loop objects allocated by +C, but it can also be used on the default loop returned by +C, in which case it is not thread-safe. + +Note that it is not advisable to call this function on the default loop +except in the rare occasion where you really need to free its resources. +If you need dynamically allocated loops it is better to use C +and C. -=item ev_loop_destroy (loop) +=item ev_loop_fork (loop) -Like C, but destroys an event loop created by an -earlier call to C. +This function sets a flag that causes subsequent C iterations +to reinitialise the kernel state for backends that have one. Despite +the name, you can call it anytime you are allowed to start or stop +watchers (except inside an C callback), but it makes most +sense after forking, in the child process. You I call it (or use +C) in the child before resuming or calling C. + +In addition, if you want to reuse a loop (via this function or +C), you I have to ignore C. + +Again, you I to call it on I loop that you want to re-use after +a fork, I. This is +because some kernel interfaces *cough* I *cough* do funny things +during fork. + +On the other hand, you only need to call this function in the child +process if and only if you want to use the event loop in the child. If +you just fork+exec or create a new loop in the child, you don't have to +call it at all (in fact, C is so badly broken that it makes a +difference, but libev will usually detect this case on its own and do a +costly reset of the backend). -=item ev_default_fork () +The function itself is quite fast and it's usually not a problem to call +it just in case after a fork. -This function reinitialises the kernel state for backends that have -one. Despite the name, you can call it anytime, but it makes most sense -after forking, in either the parent or child process (or both, but that -again makes little sense). - -You I call this function in the child process after forking if and -only if you want to use the event library in both processes. If you just -fork+exec, you don't have to call it. +Example: Automate calling C on the default loop when +using pthreads. -The function itself is quite fast and it's usually not a problem to call -it just in case after a fork. To make this easy, the function will fit in -quite nicely into a call to C: + static void + post_fork_child (void) + { + ev_loop_fork (EV_DEFAULT); + } - pthread_atfork (0, 0, ev_default_fork); + ... + pthread_atfork (0, 0, post_fork_child); -At the moment, C and C are safe to use -without calling this function, so if you force one of those backends you -do not need to care. +=item int ev_is_default_loop (loop) -=item ev_loop_fork (loop) +Returns true when the given loop is, in fact, the default loop, and false +otherwise. + +=item unsigned int ev_iteration (loop) -Like C, but acts on an event loop created by -C. Yes, you have to call this on every allocated event loop -after fork, and how you do this is entirely your own problem. - -=item unsigned int ev_loop_count (loop) - -Returns the count of loop iterations for the loop, which is identical to -the number of times libev did poll for new events. It starts at C<0> and -happily wraps around with enough iterations. +Returns the current iteration count for the event loop, which is identical +to the number of times libev did poll for new events. It starts at C<0> +and happily wraps around with enough iterations. This value can sometimes be useful as a generation counter of sorts (it "ticks" the number of loop iterations), as it roughly corresponds with -C and C calls. +C and C calls - and is incremented between the +prepare and check phases. + +=item unsigned int ev_depth (loop) + +Returns the number of times C was entered minus the number of +times C was exited normally, in other words, the recursion depth. + +Outside C, this number is zero. In a callback, this number is +C<1>, unless C was invoked recursively (or from another thread), +in which case it is higher. + +Leaving C abnormally (setjmp/longjmp, cancelling the thread, +throwing an exception etc.), doesn't count as "exit" - consider this +as a hint to avoid such ungentleman-like behaviour unless it's really +convenient, in which case it is fully supported. =item unsigned int ev_backend (loop) @@ -523,69 +835,148 @@ time used for relative timers. You can treat it as the timestamp of the event occurring (or more correctly, libev finding out about it). -=item ev_loop (loop, int flags) +=item ev_now_update (loop) + +Establishes the current time by querying the kernel, updating the time +returned by C in the progress. This is a costly operation and +is usually done automatically within C. + +This function is rarely useful, but when some event callback runs for a +very long time without entering the event loop, updating libev's idea of +the current time is a good idea. + +See also L in the C section. + +=item ev_suspend (loop) + +=item ev_resume (loop) + +These two functions suspend and resume an event loop, for use when the +loop is not used for a while and timeouts should not be processed. + +A typical use case would be an interactive program such as a game: When +the user presses C<^Z> to suspend the game and resumes it an hour later it +would be best to handle timeouts as if no time had actually passed while +the program was suspended. This can be achieved by calling C +in your C handler, sending yourself a C and calling +C directly afterwards to resume timer processing. + +Effectively, all C watchers will be delayed by the time spend +between C and C, and all C watchers +will be rescheduled (that is, they will lose any events that would have +occurred while suspended). + +After calling C you B call I function on the +given loop other than C, and you B call C +without a previous call to C. + +Calling C/C has the side effect of updating the +event loop time (see C). + +=item bool ev_run (loop, int flags) Finally, this is it, the event handler. This function usually is called -after you initialised all your watchers and you want to start handling -events. +after you have initialised all your watchers and you want to start +handling events. It will ask the operating system for any new events, call +the watcher callbacks, and then repeat the whole process indefinitely: This +is why event loops are called I. + +If the flags argument is specified as C<0>, it will keep handling events +until either no event watchers are active anymore or C was +called. -If the flags argument is specified as C<0>, it will not return until -either no event watchers are active anymore or C was called. +The return value is false if there are no more active watchers (which +usually means "all jobs done" or "deadlock"), and true in all other cases +(which usually means " you should call C again"). -Please note that an explicit C is usually better than +Please note that an explicit C is usually better than relying on all watchers to be stopped when deciding when a program has -finished (especially in interactive programs), but having a program that -automatically loops as long as it has to and no longer by virtue of -relying on its watchers stopping correctly is a thing of beauty. - -A flags value of C will look for new events, will handle -those events and any outstanding ones, but will not block your process in -case there are no events and will return after one iteration of the loop. - -A flags value of C will look for new events (waiting if -neccessary) and will handle those and any outstanding ones. It will block -your process until at least one new event arrives, and will return after -one iteration of the loop. This is useful if you are waiting for some -external event in conjunction with something not expressible using other -libev watchers. However, a pair of C/C watchers is +finished (especially in interactive programs), but having a program +that automatically loops as long as it has to and no longer by virtue +of relying on its watchers stopping correctly, that is truly a thing of +beauty. + +This function is I exception-safe - you can break out of a +C call by calling C in a callback, throwing a C++ +exception and so on. This does not decrement the C value, nor +will it clear any outstanding C breaks. + +A flags value of C will look for new events, will handle +those events and any already outstanding ones, but will not wait and +block your process in case there are no events and will return after one +iteration of the loop. This is sometimes useful to poll and handle new +events while doing lengthy calculations, to keep the program responsive. + +A flags value of C will look for new events (waiting if +necessary) and will handle those and any already outstanding ones. It +will block your process until at least one new event arrives (which could +be an event internal to libev itself, so there is no guarantee that a +user-registered callback will be called), and will return after one +iteration of the loop. + +This is useful if you are waiting for some external event in conjunction +with something not expressible using other libev watchers (i.e. "roll your +own C"). However, a pair of C/C watchers is usually a better approach for this kind of thing. -Here are the gory details of what C does: +Here are the gory details of what C does (this is for your +understanding, not a guarantee that things will work exactly like this in +future versions): + - Increment loop depth. + - Reset the ev_break status. - Before the first iteration, call any pending watchers. - * If there are no active watchers (reference count is zero), return. - - Queue all prepare watchers and then call all outstanding watchers. - - If we have been forked, recreate the kernel state. + LOOP: + - If EVFLAG_FORKCHECK was used, check for a fork. + - If a fork was detected (by any means), queue and call all fork watchers. + - Queue and call all prepare watchers. + - If ev_break was called, goto FINISH. + - If we have been forked, detach and recreate the kernel state + as to not disturb the other process. - Update the kernel state with all outstanding changes. - - Update the "event loop time". - - Calculate for how long to block. + - Update the "event loop time" (ev_now ()). + - Calculate for how long to sleep or block, if at all + (active idle watchers, EVRUN_NOWAIT or not having + any active watchers at all will result in not sleeping). + - Sleep if the I/O and timer collect interval say so. + - Increment loop iteration counter. - Block the process, waiting for any events. - Queue all outstanding I/O (fd) events. - - Update the "event loop time" and do time jump handling. - - Queue all outstanding timers. - - Queue all outstanding periodics. - - If no events are pending now, queue all idle watchers. + - Update the "event loop time" (ev_now ()), and do time jump adjustments. + - Queue all expired timers. + - Queue all expired periodics. + - Queue all idle watchers with priority higher than that of pending events. - Queue all check watchers. - Call all queued watchers in reverse order (i.e. check watchers first). Signals and child watchers are implemented as I/O watchers, and will be handled here by queueing them when their watcher gets executed. - - If ev_unloop has been called or EVLOOP_ONESHOT or EVLOOP_NONBLOCK - were used, return, otherwise continue with step *. + - If ev_break has been called, or EVRUN_ONCE or EVRUN_NOWAIT + were used, or there are no active watchers, goto FINISH, otherwise + continue with step LOOP. + FINISH: + - Reset the ev_break status iff it was EVBREAK_ONE. + - Decrement the loop depth. + - Return. -Example: Queue some jobs and then loop until no events are outsanding +Example: Queue some jobs and then loop until no events are outstanding anymore. ... queue jobs here, make sure they register event watchers as long ... as they still have work to do (even an idle watcher will do..) - ev_loop (my_loop, 0); - ... jobs done. yeah! + ev_run (my_loop, 0); + ... jobs done or somebody called break. yeah! -=item ev_unloop (loop, how) +=item ev_break (loop, how) -Can be used to make a call to C return early (but only after it +Can be used to make a call to C return early (but only after it has processed all outstanding events). The C argument must be either -C, which will make the innermost C call return, or -C, which will make all nested C calls return. +C, which will make the innermost C call return, or +C, which will make all nested C calls return. + +This "break state" will be cleared on the next call to C. + +It is safe to call C from outside any C calls, too, in +which case it will have no effect. =item ev_ref (loop) @@ -593,109 +984,231 @@ Ref/unref can be used to add or remove a reference count on the event loop: Every watcher keeps one reference, and as long as the reference -count is nonzero, C will not return on its own. If you have -a watcher you never unregister that should not keep C from -returning, ev_unref() after starting, and ev_ref() before stopping it. For -example, libev itself uses this for its internal signal pipe: It is not -visible to the libev user and should not keep C from exiting if -no event watchers registered by it are active. It is also an excellent -way to do this for generic recurring timers or from within third-party -libraries. Just remember to I and I. +count is nonzero, C will not return on its own. -Example: Create a signal watcher, but keep it from keeping C +This is useful when you have a watcher that you never intend to +unregister, but that nevertheless should not keep C from +returning. In such a case, call C after starting, and C +before stopping it. + +As an example, libev itself uses this for its internal signal pipe: It +is not visible to the libev user and should not keep C from +exiting if no event watchers registered by it are active. It is also an +excellent way to do this for generic recurring timers or from within +third-party libraries. Just remember to I and I (but only if the watcher wasn't active before, or was active +before, respectively. Note also that libev might stop watchers itself +(e.g. non-repeating timers) in which case you have to C +in the callback). + +Example: Create a signal watcher, but keep it from keeping C running when nothing else is active. - struct ev_signal exitsig; - ev_signal_init (&exitsig, sig_cb, SIGINT); - ev_signal_start (loop, &exitsig); - evf_unref (loop); + ev_signal exitsig; + ev_signal_init (&exitsig, sig_cb, SIGINT); + ev_signal_start (loop, &exitsig); + ev_unref (loop); Example: For some weird reason, unregister the above signal handler again. - ev_ref (loop); - ev_signal_stop (loop, &exitsig); + ev_ref (loop); + ev_signal_stop (loop, &exitsig); =item ev_set_io_collect_interval (loop, ev_tstamp interval) =item ev_set_timeout_collect_interval (loop, ev_tstamp interval) These advanced functions influence the time that libev will spend waiting -for events. Both are by default C<0>, meaning that libev will try to -invoke timer/periodic callbacks and I/O callbacks with minimum latency. +for events. Both time intervals are by default C<0>, meaning that libev +will try to invoke timer/periodic callbacks and I/O callbacks with minimum +latency. Setting these to a higher value (the C I be >= C<0>) -allows libev to delay invocation of I/O and timer/periodic callbacks to -increase efficiency of loop iterations. - -The background is that sometimes your program runs just fast enough to -handle one (or very few) event(s) per loop iteration. While this makes -the program responsive, it also wastes a lot of CPU time to poll for new +allows libev to delay invocation of I/O and timer/periodic callbacks +to increase efficiency of loop iterations (or to increase power-saving +opportunities). + +The idea is that sometimes your program runs just fast enough to handle +one (or very few) event(s) per loop iteration. While this makes the +program responsive, it also wastes a lot of CPU time to poll for new events, especially with backends like C (or libev) on file descriptors +representing files, and expect it to become ready when their program +doesn't block on disk accesses (which can take a long time on their own). + +However, this cannot ever work in the "expected" way - you get a readiness +notification as soon as the kernel knows whether and how much data is +there, and in the case of open files, that's always the case, so you +always get a readiness notification instantly, and your read (or possibly +write) will still block on the disk I/O. + +Another way to view it is that in the case of sockets, pipes, character +devices and so on, there is another party (the sender) that delivers data +on its own, but in the case of files, there is no such thing: the disk +will not send data on its own, simply because it doesn't know what you +wish to read - you would first have to request some data. + +Since files are typically not-so-well supported by advanced notification +mechanism, libev tries hard to emulate POSIX behaviour with respect +to files, even though you should not use it. The reason for this is +convenience: sometimes you want to watch STDIN or STDOUT, which is +usually a tty, often a pipe, but also sometimes files or special devices +(for example, C on Linux works with F but not with +F), and even though the file might better be served with +asynchronous I/O instead of with non-blocking I/O, it is still useful when +it "just works" instead of freezing. + +So avoid file descriptors pointing to files when you know it (e.g. use +libeio), but use them when it is convenient, e.g. for STDIN/STDOUT, or +when you rarely read from a file instead of from a socket, and want to +reuse the same code path. + =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. +Some backends (epoll, kqueue, probably linuxaio) do not support C +at all or exhibit useless behaviour. Libev fully supports fork, but needs +to be told about it in the child if you want to continue to use it in the +child. + +To support fork in your child processes, you have to call 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 @@ -1063,8 +1815,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] @@ -1076,23 +1828,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 - } + 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); - 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_run (loop, 0); =head2 C - relative and optionally repeating timeouts @@ -1101,22 +1855,329 @@ 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, see "the special problem of being too +early", below). 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 timeout = 60.; + ev_tstamp last_activity; // time of last activity + ev_timer timer; + + static void + callback (EV_P_ ev_timer *w, int revents) + { + // calculate when the timeout would happen + ev_tstamp after = last_activity - ev_now (EV_A) + timeout; + + // if negative, it means we the timeout already occurred + if (after < 0.) + { + // timeout occurred, take action + } + else + { + // callback was invoked, but there was some recent + // activity. simply restart the timer to time out + // after "after" seconds, which is the earliest time + // the timeout can occur. + ev_timer_set (w, after, 0.); + ev_timer_start (EV_A_ w); + } + } + +To summarise the callback: first calculate in how many seconds the +timeout will occur (by calculating the absolute time when it would occur, +C, and subtracting the current time, C from that). + +If this value is negative, then we are already past the timeout, i.e. we +timed out, and need to do whatever is needed in this case. + +Otherwise, we now the earliest time at which the timeout would trigger, +and simply start the timer with this timeout value. + +In other words, each time the callback is invoked it will check whether +the timeout occurred. If not, it will simply reschedule itself to check +again at the earliest time it could time out. Rinse. Repeat. + +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 machinery, simply initialise the watcher and set +C to the current time (meaning there was some activity just +now), then call the callback, which will "do the right thing" and start +the timer: + + last_activity = ev_now (EV_A); + ev_init (&timer, callback); + callback (EV_A_ &timer, 0); + +When there is some activity, simply store the current time in +C, no libev calls at all: + + if (activity detected) + last_activity = ev_now (EV_A); + +When your timeout value changes, then the timeout can be changed by simply +providing a new value, stopping the timer and calling the callback, which +will again do the right thing (for example, time out immediately :). + + timeout = new_value; + ev_timer_stop (EV_A_ &timer); + callback (EV_A_ &timer, 0); + +This technique is slightly more complex, but in most cases where the +time-out is unlikely to be triggered, much more efficient. + +=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 being too early + +If you ask a timer to call your callback after three seconds, then +you expect it to be invoked after three seconds - but of course, this +cannot be guaranteed to infinite precision. Less obviously, it cannot be +guaranteed to any precision by libev - imagine somebody suspending the +process with a STOP signal for a few hours for example. + +So, libev tries to invoke your callback as soon as possible I the +delay has occurred, but cannot guarantee this. + +A less obvious failure mode is calling your callback too early: many event +loops compare timestamps with a "elapsed delay >= requested delay", but +this can cause your callback to be invoked much earlier than you would +expect. + +To see why, imagine a system with a clock that only offers full second +resolution (think windows if you can't come up with a broken enough OS +yourself). If you schedule a one-second timer at the time 500.9, then the +event loop will schedule your timeout to elapse at a system time of 500 +(500.9 truncated to the resolution) + 1, or 501. + +If an event library looks at the timeout 0.1s later, it will see "501 >= +501" and invoke the callback 0.1s after it was started, even though a +one-second delay was requested - this is being "too early", despite best +intentions. + +This is the reason why libev will never invoke the callback if the elapsed +delay equals the requested delay, but only when the elapsed delay is +larger than the requested delay. In the example above, libev would only invoke +the callback at system time 502, or 1.1s after the timer was started. + +So, while libev cannot guarantee that your callback will be invoked +exactly when requested, it I and I guarantee that the requested +delay has actually elapsed, or in other words, it always errs on the "too +late" side of things. + +=head3 The special problem of time updates + +Establishing the current time is a costly operation (it usually takes +at least one system call): 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: - - 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. +you suspect event processing to be delayed and you I to base the +timeout on the current time, use something like the following to adjust +for it: + + ev_timer_set (&timer, after + (ev_time () - ev_now ()), 0.); + +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, although that will push the event time of all outstanding events +further into the future. + +=head3 The special problem of unsynchronised clocks + +Modern systems have a variety of clocks - libev itself uses the normal +"wall clock" clock and, if available, the monotonic clock (to avoid time +jumps). + +Neither of these clocks is synchronised with each other or any other clock +on the system, so C might return a considerably different time +than C or C