--- libev/ev.pod 2008/05/22 02:44:57 1.159 +++ libev/ev.pod 2009/04/25 14:23:26 1.241 @@ -4,70 +4,84 @@ =head1 SYNOPSIS - #include + #include =head2 EXAMPLE PROGRAM - // a single header file is required - #include + // a single header file is required + #include - // every watcher type has its own typedef'd struct - // with the name ev_ - 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_ struct ev_io *w, int revents) - { - puts ("stdin ready"); - // for one-shot events, one must manually stop the watcher - // with its corresponding stop function. - ev_io_stop (EV_A_ w); - - // this causes all nested ev_loop's to stop iterating - ev_unloop (EV_A_ EVUNLOOP_ALL); - } - - // another callback, this time for a time-out - static void - timeout_cb (EV_P_ struct ev_timer *w, int revents) - { - puts ("timeout"); - // this causes the innermost ev_loop to stop iterating - ev_unloop (EV_A_ EVUNLOOP_ONE); - } - - int - main (void) - { - // use the default event loop unless you have special needs - struct ev_loop *loop = ev_default_loop (0); - - // initialise an io watcher, then start it - // this one will watch for stdin to become readable - ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ); - ev_io_start (loop, &stdin_watcher); - - // initialise a timer watcher, then start it - // simple non-repeating 5.5 second timeout - ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.); - ev_timer_start (loop, &timeout_watcher); - - // now wait for events to arrive - ev_loop (loop, 0); - - // unloop was called, so exit - return 0; - } + #include // for puts -=head1 DESCRIPTION + // every watcher type has its own typedef'd struct + // with the name ev_TYPE + ev_io stdin_watcher; + ev_timer timeout_watcher; + + // all watcher callbacks have a similar signature + // this callback is called when data is readable on stdin + static void + stdin_cb (EV_P_ ev_io *w, int revents) + { + puts ("stdin ready"); + // for one-shot events, one must manually stop the watcher + // with its corresponding stop function. + ev_io_stop (EV_A_ w); + + // this causes all nested ev_loop's to stop iterating + ev_unloop (EV_A_ EVUNLOOP_ALL); + } + + // another callback, this time for a time-out + static void + timeout_cb (EV_P_ ev_timer *w, int revents) + { + puts ("timeout"); + // this causes the innermost ev_loop to stop iterating + ev_unloop (EV_A_ EVUNLOOP_ONE); + } + + int + main (void) + { + // use the default event loop unless you have special needs + struct ev_loop *loop = ev_default_loop (0); + + // initialise an io watcher, then start it + // this one will watch for stdin to become readable + ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ); + ev_io_start (loop, &stdin_watcher); + + // initialise a timer watcher, then start it + // simple non-repeating 5.5 second timeout + ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.); + ev_timer_start (loop, &timeout_watcher); + + // now wait for events to arrive + ev_loop (loop, 0); + + // unloop was called, so exit + return 0; + } + +=head1 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. + +Familarity 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. @@ -105,20 +119,41 @@ 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 +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 +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. 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 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 These functions can be called anytime, even before initialising the @@ -136,7 +171,7 @@ 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. +this is a sub-second-resolution C. =item int ev_version_major () @@ -159,9 +194,9 @@ Example: Make sure we haven't accidentally been linked against the wrong version. - 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 () @@ -173,15 +208,15 @@ 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 +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. @@ -195,7 +230,7 @@ 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)) [NOT REENTRANT] Sets the allocation function to use (the prototype is similar - the semantics are identical to the C C89/SuS/POSIX function). It is @@ -231,12 +266,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)); [NOT REENTRANT] -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). @@ -257,9 +292,13 @@ =head1 FUNCTIONS CONTROLLING THE EVENT LOOP -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. +An event loop is described by a C (the C +is I optional in this case, as there is also an C +I). + +The library knows two types of such loops, the I loop, which +supports signals and child events, and dynamically created loops which do +not. =over 4 @@ -275,11 +314,11 @@ Note that this function is I thread-safe, so if you want to use it from multiple threads, you have to lock (note also that this is unlikely, -as loops cannot bes hared easily between threads anyway). +as loops cannot be shared easily between threads anyway). The default loop is the only loop that can handle C and C watchers, and to do this, it always registers a handler -for C. If this is a problem for your app you can either +for C. If this is a problem for your application you can either create a dynamic loop with C that doesn't do that, or you can simply overwrite the C signal handler I calling C. @@ -298,7 +337,7 @@ =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 @@ -315,14 +354,14 @@ and thus this might slow down your event loop if you do a lot of loop iterations and little real work, but is usually not noticeable (on my GNU/Linux system for example, C is actually a simple 5-insn sequence -without a syscall and thus I fast, but my GNU/Linux system also has +without a system call and thus I fast, but my GNU/Linux system also has C which is even faster). The big advantage of this flag is that you can forget about fork (and forget about forgetting to tell libev about forking) when you use this flag. -This flag setting cannot be overriden or specified in the C +This flag setting cannot be overridden or specified in the C environment variable. =item C (value 1, portable select backend) @@ -334,12 +373,16 @@ 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 readiness notifications you get per iteration. +This backend maps C to the C set and C to the +C set (and to work around Microsoft Windows bugs, also onto the +C set on that platform). + =item C (value 2, poll backend, available everywhere except on windows) And this is your standard poll(2) backend. It's more complicated @@ -349,40 +392,67 @@ 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 requiring a syscall per fd change, no fork support and bad -support for dup. +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 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. While stopping, setting and starting an I/O watcher in the same iteration -will result in some caching, there is still a syscall per such incident -(because the fd could point to a different file description now), so its -best to avoid that. Also, C'ed file descriptors might not work -very well if you register events for both fds. - -Please note that epoll sometimes generates spurious notifications, so you -need to use non-blocking I/O or other means to avoid blocking when no data -(or space) is available. +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. +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 embeddeble in other event loops, this feature is broken in +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). 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. @@ -393,9 +463,10 @@ 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 -drops fds silently in similarly hard-to-detect cases. +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. @@ -403,8 +474,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) @@ -418,7 +493,7 @@ 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 +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. @@ -427,9 +502,13 @@ descriptors a "slow" C or C backend might perform better. -On the positive side, ignoring the spurious readiness notifications, this -backend actually performed to specification in all tests and is fully -embeddable, which is a rare feat among the OS-specific backends. +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 @@ -441,25 +520,26 @@ =back -If one or more of these are ored into the flags value, then only these +If one or more of these 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: +Example: This is the most typical usage. - if (!ev_default_loop (0)) - fatal ("could not initialise libev, bad $LIBEV_FLAGS in environment?"); + 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 +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); + 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: 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): - ev_default_loop (ev_recommended_backends () | EVBACKEND_KQUEUE); + ev_default_loop (ev_recommended_backends () | EVBACKEND_KQUEUE); =item struct ev_loop *ev_loop_new (unsigned int flags) @@ -474,23 +554,23 @@ 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"); + 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 ev_default_destroy () Destroys the default loop again (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. +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. 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 @@ -525,11 +605,13 @@ 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. +after fork that you want to re-use in the child, and how you do this is +entirely your own problem. =item int ev_is_default_loop (loop) -Returns true when the given loop actually is the default loop, false otherwise. +Returns true when the given loop is, in fact, the default loop, and false +otherwise. =item unsigned int ev_loop_count (loop) @@ -554,6 +636,44 @@ 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 a 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 +occured 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_loop (loop, int flags) Finally, this is it, the event handler. This function usually is called @@ -565,41 +685,48 @@ 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. +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 outstanding ones, but will not block your process in -case there are no events and will return after one iteration of the loop. +those events and any already 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 +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: - Before the first iteration, call any pending watchers. * If EVFLAG_FORKCHECK was used, check for a fork. - - If a fork was detected, queue and call all fork watchers. + - If a fork was detected (by any means), queue and call all fork watchers. - Queue and call all prepare watchers. - - If we have been forked, recreate the kernel state. + - 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". + - Update the "event loop time" (ev_now ()). - Calculate for how long to sleep or block, if at all (active idle watchers, EVLOOP_NONBLOCK or not having any active watchers at all will result in not sleeping). - Sleep if the I/O and timer collect interval say so. - 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. + - Unless any events are pending now, queue all idle watchers. - 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 @@ -614,7 +741,7 @@ ... 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! + ... jobs done or somebody called unloop. yeah! =item ev_unloop (loop, how) @@ -625,51 +752,60 @@ This "unloop state" will be cleared when entering C again. +It is safe to call C from otuside any C calls. + =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. 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 -(but only if the watcher wasn't active before, or was active before, -respectively). +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, call ev_unref() after starting, and ev_ref() 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); + evf_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(2) backend. No attempt at autodetection will be done: if no +C function doesn't follow POSIX in that it requires -socket I and not socket I. This makes select -very inefficient, and also requires a mapping from file descriptors -to socket handles. See the discussion of the C, -C and C preprocessor -symbols for more info. +The winsocket C