=head1 NAME libev - a high performance full-featured event loop written in C =head1 SYNOPSIS #include =head2 EXAMPLE PROGRAM // a single header file is required #include #include // for puts // every watcher type has its own typedef'd struct // with the name ev_TYPE ev_io stdin_watcher; ev_timer timeout_watcher; // all watcher callbacks have a similar signature // this callback is called when data is readable on stdin static void stdin_cb (EV_P_ ev_io *w, int revents) { puts ("stdin ready"); // for one-shot events, one must manually stop the watcher // with its corresponding stop function. ev_io_stop (EV_A_ w); // this causes all nested ev_run's to stop iterating ev_break (EV_A_ EVBREAK_ALL); } // another callback, this time for a time-out static void timeout_cb (EV_P_ ev_timer *w, int revents) { puts ("timeout"); // this causes the innermost ev_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 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 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 these event sources and provide your program with events. To do this, it must take more or less complete control over your process (or thread) by executing the I handler, and will then communicate events via a callback mechanism. You register interest in certain events by registering so-called I, which are relatively small C structures you initialise with the details of the event, and then hand it over to libev by I the watcher. =head2 FEATURES Libev supports C (files, many character devices...). While stopping, setting and starting an I/O watcher in the same iteration will result in some caching, there is still a system call per such incident (because the same I could point to a different I now), so its best to avoid that. Also, C'ed file descriptors might not work very well if you register events for both file descriptors. Best performance from this backend is achieved by not unregistering all watchers for a file descriptor until it has been closed, if possible, i.e. keep at least one watcher active per fd at all times. Stopping and starting a watcher (without re-setting it) also usually doesn't cause extra overhead. A fork can both result in spurious notifications as well as in libev having to destroy and recreate the epoll object, which can take considerable time and thus should be avoided. All this means that, in practice, C can be as fast or faster than epoll for maybe up to a hundred file descriptors, depending on the usage. So sad. While nominally embeddable in other event loops, this feature is broken in all kernel versions tested so far. 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). 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. You still can embed kqueue into a normal poll or select backend and use it only for sockets (after having made sure that sockets work with kqueue on the target platform). See C watchers for more info. 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 system call as with C, it still adds up to two event changes per incident. Support for C is very bad (but sane, unlike epoll) and it drops fds silently in similarly hard-to-detect cases This backend usually performs well under most conditions. While nominally embeddable in other event loops, this doesn't work 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 (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) This is not implemented yet (and might never be, unless you send me an implementation). According to reports, C only supports sockets and is not embeddable, which would limit the usefulness of this backend immensely. =item C (value 32, Solaris 10) 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, with the exception of the spurious readiness notifications, 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). 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. =back 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. Example: Try to create a event loop that uses epoll and nothing else. struct ev_loop *epoller = ev_loop_new (EVBACKEND_EPOLL | EVFLAG_NOENV); if (!epoller) fatal ("no epoll found here, maybe it hides under your chair"); Example: Use whatever libev has to offer, but make sure that kqueue is used if available. struct ev_loop *loop = ev_loop_new (ev_recommended_backends () | EVBACKEND_KQUEUE); =item ev_loop_destroy (loop) 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 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 (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 it's resources. If you need dynamically allocated loops it is better to use C and C. =item ev_loop_fork (loop) 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, 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. 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). The function itself is quite fast and it's usually not a problem to call it just in case after a fork. Example: Automate calling C on the default loop when using pthreads. static void post_fork_child (void) { ev_loop_fork (EV_DEFAULT); } ... pthread_atfork (0, 0, post_fork_child); =item int ev_is_default_loop (loop) Returns true when the given loop is, in fact, the default loop, and false otherwise. =item unsigned int ev_iteration (loop) 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 - 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, 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 etc.), doesn't count as "exit" - consider this as a hint to avoid such ungentleman-like behaviour unless it's really convenient. =item unsigned int ev_backend (loop) Returns one of the C flags indicating the event backend in use. =item ev_tstamp ev_now (loop) Returns the current "event loop time", which is the time the event loop received events and started processing them. This timestamp does not change as long as callbacks are being processed, and this is also the base time used for relative timers. You can treat it as the timestamp of the event occurring (or more correctly, libev finding out about it). =item ev_now_update (loop) Establishes the current time by querying the kernel, updating the time returned by C in the progress. This is a costly operation and is usually done automatically within C. This function is rarely useful, but when some event callback runs for a very long time without entering the event loop, updating libev's idea of the current time is a good idea. See also 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 ev_run (loop, int flags) Finally, this is it, the event handler. This function usually is called 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, an 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. 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, that is truly a thing of beauty. 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: - Increment loop depth. - Reset the ev_break status. - Before the first iteration, call any pending watchers. 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" (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" (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_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 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_run (my_loop, 0); ... jobs done or somebody called unloop. yeah! =item ev_break (loop, how) 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. This "unloop state" will be cleared when entering C again. It is safe to call C from outside any C calls. ##TODO## =item ev_ref (loop) =item ev_unref (loop) 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. 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. ev_signal exitsig; ev_signal_init (&exitsig, sig_cb, SIGINT); ev_signal_start (loop, &exitsig); evf_unref (loop); Example: For some weird reason, unregister the above signal handler again. 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 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 (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. =item EV_USE_EVENTFD If defined to be C<1>, then libev will assume that C is available and will probe for kernel support at runtime. This will improve C and C performance and reduce resource consumption. If undefined, it will be enabled if the headers indicate GNU/Linux + Glibc 2.7 or newer, otherwise disabled. =item EV_USE_SELECT If undefined or defined to be C<1>, libev will compile in support for the C is buggy All that's left is C actively limits the number of file descriptors you can pass in to 1024 - your program suddenly crashes when you use more. There is an undocumented "workaround" for this - defining C<_DARWIN_UNLIMITED_SELECT>, which libev tries to use, so select I work on OS/X. =head2 SOLARIS PROBLEMS AND WORKAROUNDS =head3 C reentrancy The default compile environment on Solaris is unfortunately so thread-unsafe that you can't even use components/libraries compiled without C<-D_REENTRANT> in a threaded program, which, of course, isn't defined by default. A valid, if stupid, implementation choice. If you want to use libev in threaded environments you have to make sure it's compiled with C<_REENTRANT> defined. =head3 Event port backend The scalable event interface for Solaris is called "event ports". Unfortunately, this mechanism is very buggy in all major releases. If you run into high CPU usage, your program freezes or you get a large number of spurious wakeups, make sure you have all the relevant and latest kernel patches applied. No, I don't know which ones, but there are multiple ones to apply, and afterwards, event ports actually work great. If you can't get it to work, you can try running the program by setting the environment variable C to only allow C and C works fine with large bitsets on AIX, and AIX is dead anyway. =head2 WIN32 PLATFORM LIMITATIONS AND WORKAROUNDS =head3 General issues Win32 doesn't support any of the standards (e.g. POSIX) that libev requires, and its I/O model is fundamentally incompatible with the POSIX model. Libev still offers limited functionality on this platform in the form of the C backend, and only supports socket descriptors. This only applies when using Win32 natively, not when using e.g. cygwin. Actually, it only applies to the microsofts own compilers, as every compielr comes with a slightly differently broken/incompatible environment. Lifting these limitations would basically require the full re-implementation of the I/O system. If you are into this kind of thing, then note that glib does exactly that for you in a very portable way (note also that glib is the slowest event library known to man). There is no supported compilation method available on windows except embedding it into other applications. Sensible signal handling is officially unsupported by Microsoft - libev tries its best, but under most conditions, signals will simply not work. Not a libev limitation but worth mentioning: windows apparently doesn't accept large writes: instead of resulting in a partial write, windows will either accept everything or return C if the buffer is too large, so make sure you only write small amounts into your sockets (less than a megabyte seems safe, but this apparently depends on the amount of memory available). Due to the many, low, and arbitrary limits on the win32 platform and the abysmal performance of winsockets, using a large number of sockets is not recommended (and not reasonable). If your program needs to use more than a hundred or so sockets, then likely it needs to use a totally different implementation for windows, as libev offers the POSIX readiness notification model, which cannot be implemented efficiently on windows (due to Microsoft monopoly games). A typical way to use libev under windows is to embed it (see the embedding section for details) and use the following F header file instead of F: #define EV_STANDALONE /* keeps ev from requiring config.h */ #define EV_SELECT_IS_WINSOCKET 1 /* configure libev for windows select */ #include "ev.h" And compile the following F file into your project (make sure you do I compile the F or any other embedded source files!): #include "evwrap.h" #include "ev.c" =head3 The winsocket C function doesn't follow POSIX in that it requires socket I and not socket I (it is also extremely buggy). This makes select very inefficient, and also requires a mapping from file descriptors to socket handles (the Microsoft C runtime provides the function C<_open_osfhandle> for this). See the discussion of the C, C and C preprocessor symbols for more info. The configuration for a "naked" win32 using the Microsoft runtime libraries and raw winsocket select is: #define EV_USE_SELECT 1 #define EV_SELECT_IS_WINSOCKET 1 /* forces EV_SELECT_USE_FD_SET, too */ Note that winsockets handling of fd sets is O(n), so you can easily get a complexity in the O(n²) range when using win32. =head3 Limited number of file descriptors Windows has numerous arbitrary (and low) limits on things. Early versions of winsocket's select only supported waiting for a maximum of C<64> handles (probably owning to the fact that all windows kernels can only wait for C<64> things at the same time internally; Microsoft recommends spawning a chain of threads and wait for 63 handles and the previous thread in each. Sounds great!). Newer versions support more handles, but you need to define C to some high number (e.g. C<2048>) before compiling the winsocket select call (which might be in libev or elsewhere, for example, perl and many other interpreters do their own select emulation on windows). Another limit is the number of file descriptors in the Microsoft runtime libraries, which by default is C<64> (there must be a hidden I<64> fetish or something like this inside Microsoft). You can increase this by calling C<_setmaxstdio>, which can increase this limit to C<2048> (another arbitrary limit), but is broken in many versions of the Microsoft runtime libraries. This might get you to about C<512> or C<2048> sockets (depending on windows version and/or the phase of the moon). To get more, you need to wrap all I/O functions and provide your own fd management, but the cost of calling select (O(n²)) will likely make this unworkable. =head2 PORTABILITY REQUIREMENTS In addition to a working ISO-C implementation and of course the backend-specific APIs, libev relies on a few additional extensions: =over 4 =item C must have compatible calling conventions regardless of C. Libev assumes not only that all watcher pointers have the same internal structure (guaranteed by POSIX but not by ISO C for example), but it also assumes that the same (machine) code can be used to call any watcher callback: The watcher callbacks have different type signatures, but libev calls them using an C internally. =item C must be thread-atomic as well The type C (or whatever is defined as C) must be atomic with respect to accesses from different threads. This is not part of the specification for C, but is believed to be sufficiently portable. =item C must work in a threaded environment Libev uses C to temporarily block signals. This is not allowed in a threaded program (C has to be used). Typical pthread implementations will either allow C in the "main thread" or will block signals process-wide, both behaviours would be compatible with libev. Interaction between C and C could complicate things, however. The most portable way to handle signals is to block signals in all threads except the initial one, and run the default loop in the initial thread as well. =item C must be large enough for common memory allocation sizes To improve portability and simplify its API, libev uses C internally instead of C when allocating its data structures. On non-POSIX systems (Microsoft...) this might be unexpectedly low, but is still at least 31 bits everywhere, which is enough for hundreds of millions of watchers. =item C must hold a time value in seconds with enough accuracy The type C is used to represent timestamps. It is required to have at least 51 bits of mantissa (and 9 bits of exponent), which is good enough for at least into the year 4000 with millisecond accuracy (the design goal for libev). This requirement is overfulfilled by implementations using IEEE 754, which is basically all existing ones. With IEEE 754 doubles, you get microsecond accuracy until at least 2200. =back If you know of other additional requirements drop me a note. =head1 ALGORITHMIC COMPLEXITIES In this section the complexities of (many of) the algorithms used inside libev will be documented. For complexity discussions about backends see the documentation for C. All of the following are about amortised time: If an array needs to be extended, libev needs to realloc and move the whole array, but this happens asymptotically rarer with higher number of elements, so O(1) might mean that libev does a lengthy realloc operation in rare cases, but on average it is much faster and asymptotically approaches constant time. =over 4 =item Starting and stopping timer/periodic watchers: O(log skipped_other_timers) This means that, when you have a watcher that triggers in one hour and there are 100 watchers that would trigger before that, then inserting will have to skip roughly seven (C) of these watchers. =item Changing timer/periodic watchers (by autorepeat or calling again): O(log skipped_other_timers) That means that changing a timer costs less than removing/adding them, as only the relative motion in the event queue has to be paid for. =item Starting io/check/prepare/idle/signal/child/fork/async watchers: O(1) These just add the watcher into an array or at the head of a list. =item Stopping check/prepare/idle/fork/async watchers: O(1) =item Stopping an io/signal/child watcher: O(number_of_watchers_for_this_(fd/signal/pid % EV_PID_HASHSIZE)) These watchers are stored in lists, so they need to be walked to find the correct watcher to remove. The lists are usually short (you don't usually have many watchers waiting for the same fd or signal: one is typical, two is rare). =item Finding the next timer in each loop iteration: O(1) By virtue of using a binary or 4-heap, the next timer is always found at a fixed position in the storage array. =item Each change on a file descriptor per loop iteration: O(number_of_watchers_for_this_fd) A change means an I/O watcher gets started or stopped, which requires libev to recalculate its status (and possibly tell the kernel, depending on backend and whether C was used). =item Activating one watcher (putting it into the pending state): O(1) =item Priority handling: O(number_of_priorities) Priorities are implemented by allocating some space for each priority. When doing priority-based operations, libev usually has to linearly search all the priorities, but starting/stopping and activating watchers becomes O(1) with respect to priority handling. =item Sending an ev_async: O(1) =item Processing ev_async_send: O(number_of_async_watchers) =item Processing signals: O(max_signal_number) Sending involves a system call I there were no other C calls in the current loop iteration. Checking for async and signal events involves iterating over all running async watchers or all signal numbers. =back =head1 PORTING FROM LIBEV 3.X TO 4.X The major version 4 introduced some minor incompatible changes to the API. At the moment, the C header file tries to implement superficial compatibility, so most programs should still compile. Those might be removed in later versions of libev, so better update early than late. =over 4 =item C and C have been removed These calls can be replaced easily by their C counterparts: ev_loop_destroy (EV_DEFAULT_UC); ev_loop_fork (EV_DEFAULT); =item function/symbol renames A number of functions and symbols have been renamed: ev_loop => ev_run EVLOOP_NONBLOCK => EVRUN_NOWAIT EVLOOP_ONESHOT => EVRUN_ONCE ev_unloop => ev_break EVUNLOOP_CANCEL => EVBREAK_CANCEL EVUNLOOP_ONE => EVBREAK_ONE EVUNLOOP_ALL => EVBREAK_ALL EV_TIMEOUT => EV_TIMER ev_loop_count => ev_iteration ev_loop_depth => ev_depth ev_loop_verify => ev_verify Most functions working on C objects don't have an C prefix, so it was removed; C, C and associated constants have been renamed to not collide with the C anymore and C now follows the same naming scheme as all other watcher types. Note that C is still called C because it would otherwise clash with the C typedef. =item C backwards compatibility mechanism The backward compatibility mechanism can be controlled by C. See L in the L section. =item C mechanism replaced by C The preprocessor symbol C has been replaced by a different mechanism, C. Programs using C usually compile and work, but the library code will of course be larger. =back =head1 GLOSSARY =over 4 =item active A watcher is active as long as it has been started and not yet stopped. See L for details. =item application In this document, an application is whatever is using libev. =item backend The part of the code dealing with the operating system interfaces. =item callback The address of a function that is called when some event has been detected. Callbacks are being passed the event loop, the watcher that received the event, and the actual event bitset. =item callback/watcher invocation The act of calling the callback associated with a watcher. =item event A change of state of some external event, such as data now being available for reading on a file descriptor, time having passed or simply not having any other events happening anymore. In libev, events are represented as single bits (such as C or C). =item event library A software package implementing an event model and loop. =item event loop An entity that handles and processes external events and converts them into callback invocations. =item event model The model used to describe how an event loop handles and processes watchers and events. =item pending A watcher is pending as soon as the corresponding event has been detected. See L for details. =item real time The physical time that is observed. It is apparently strictly monotonic :) =item wall-clock time The time and date as shown on clocks. Unlike real time, it can actually be wrong and jump forwards and backwards, e.g. when the you adjust your clock. =item watcher A data structure that describes interest in certain events. Watchers need to be started (attached to an event loop) before they can receive events. =back =head1 AUTHOR Marc Lehmann , with repeated corrections by Mikael Magnusson.