--- libev/ev.pod 2009/12/26 09:21:54 1.275 +++ libev/ev.pod 2010/03/16 00:26:41 1.286 @@ -372,13 +372,18 @@ testing, this flag can be useful to conserve inotify file descriptors, as otherwise each loop using C watchers consumes one inotify handle. -=item C +=item C -When this flag is specified, then libev will not attempt to use the -I API for it's C (and C) watchers. This is -probably only useful to work around any bugs in libev. Consequently, this -flag might go away once the signalfd functionality is considered stable, -so it's useful mostly in environment variables and not in program code. +When this flag is specified, then libev will attempt to use the +I API for it's 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 (value 1, portable select backend) @@ -794,9 +799,10 @@ 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, call ev_unref() after starting, and ev_ref() before -stopping it. +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 @@ -1534,6 +1540,44 @@ 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 port-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 @@ -1863,7 +1907,7 @@ the timeout value currently configured. That is, after an C, C returns -C<5>. When the timer is started and one second passes, C +C<5>. When the timer is started and one second passes, C will return C<4>. When the timer expires and is restarted, it will return roughly C<7> (likely slightly less as callback invocation takes some time, too), and so on. @@ -2133,7 +2177,7 @@ interrupted by signals you can block all signals in an C watcher and unblock them in an C watcher. -=head3 The special problem of inheritance over execve +=head3 The special problem of inheritance over fork/execve/pthread_create Both the signal mask (C) and the signal disposition (C) are unspecified after starting a signal watcher (and after @@ -2153,10 +2197,14 @@ to install a fork handler with C that resets it. That will catch fork calls done by libraries (such as the libc) as well. -In current versions of libev, you can also ensure that the signal mask is -not blocking any signals (except temporarily, so thread users watch out) -by specifying the C when creating the event loop. This -is not guaranteed for future versions, however. +In current versions of libev, the signal will not be blocked indefinitely +unless you use the C API (C). While this reduces +the window of opportunity for problems, it will not go away, as libev +I to modify the signal mask, at least temporarily. + +So I can't stress this enough: I. This +is not a libev-specific thing, this is true for most event libraries. =head3 Watcher-Specific Functions and Data Members @@ -3443,8 +3491,8 @@ =item Lua -Brian Maher has written a partial interface to libev -for lua (only C and C), to be found at +Brian Maher has written a partial interface to libev for lua (at the +time of this writing, only C and C), to be found at L. =back @@ -3609,12 +3657,19 @@ =head2 PREPROCESSOR SYMBOLS/MACROS Libev can be configured via a variety of preprocessor symbols you have to -define before including any of its files. The default in the absence of -autoconf is documented for every option. +define before including (or compiling) any of its files. The default in +the absence of autoconf is documented for every option. + +Symbols marked with "(h)" do not change the ABI, and can have different +values when compiling libev vs. including F, so it is permissible +to redefine them before including F without breakign compatibility +to a compiled library. All other symbols change the ABI, which means all +users of libev and the libev code itself must be compiled with compatible +settings. =over 4 -=item EV_STANDALONE +=item EV_STANDALONE (h) Must always be C<1> if you do not use autoconf configuration, which keeps libev from including F, and it also defines dummy @@ -3774,24 +3829,24 @@ In the absence of this define, libev will use C (from F), which is usually good enough on most platforms. -=item EV_H +=item EV_H (h) The name of the F header file used to include it. The default if undefined is C<"ev.h"> in F, F and F. This can be used to virtually rename the F header file in case of conflicts. -=item EV_CONFIG_H +=item EV_CONFIG_H (h) If C isn't C<1>, this variable can be used to override F's idea of where to find the F file, similarly to C, above. -=item EV_EVENT_H +=item EV_EVENT_H (h) Similarly to C, this macro can be used to override F's idea of how the F header can be found, the default is C<"event.h">. -=item EV_PROTOTYPES +=item EV_PROTOTYPES (h) If defined to be C<0>, then F will not define any function prototypes, but still define all the structs and other symbols. This is @@ -3823,55 +3878,107 @@ If your embedding application does not need any priorities, defining these both to C<0> will save some memory and CPU. -=item EV_PERIODIC_ENABLE +=item EV_PERIODIC_ENABLE, EV_IDLE_ENABLE, EV_EMBED_ENABLE, EV_STAT_ENABLE, +EV_PREPARE_ENABLE, EV_CHECK_ENABLE, EV_FORK_ENABLE, EV_SIGNAL_ENABLE, +EV_ASYNC_ENABLE, EV_CHILD_ENABLE. + +If undefined or defined to be C<1> (and the platform supports it), then +the respective watcher type is supported. If defined to be C<0>, then it +is not. Disabling watcher types mainly saves codesize. + +=item EV_FEATURES -If undefined or defined to be C<1>, then periodic timers are supported. If -defined to be C<0>, then they are not. Disabling them saves a few kB of -code. +If you need to shave off some kilobytes of code at the expense of some +speed (but with the full API), you can define this symbol to request +certain subsets of functionality. The default is to enable all features +that can be enabled on the platform. -=item EV_IDLE_ENABLE +Note that using autoconf will usually override most of the features, so +using this symbol makes sense mostly when embedding libev. -If undefined or defined to be C<1>, then idle watchers are supported. If -defined to be C<0>, then they are not. Disabling them saves a few kB of -code. +A typical way to use this symbol is to define it to C<0> (or to a bitset +with some broad features you want) and then selectively re-enable +additional parts you want, for example if you want everything minimal, +but multiple event loop support, async and child watchers and the poll +backend, use this: -=item EV_EMBED_ENABLE + #define EV_FEATURES 0 + #define EV_MULTIPLICITY 1 + #define EV_USE_POLL 1 + #define EV_CHILD_ENABLE 1 + #define EV_ASYNC_ENABLE 1 -If undefined or defined to be C<1>, then embed watchers are supported. If -defined to be C<0>, then they are not. Embed watchers rely on most other -watcher types, which therefore must not be disabled. +The actual value is a bitset, it can be a combination of the following +values: -=item EV_STAT_ENABLE +=over 4 -If undefined or defined to be C<1>, then stat watchers are supported. If -defined to be C<0>, then they are not. +=item C<1> - faster/larger code -=item EV_FORK_ENABLE +Use larger code to speed up some operations. -If undefined or defined to be C<1>, then fork watchers are supported. If -defined to be C<0>, then they are not. +Currently this is used to override some inlining decisions (enlarging the roughly +30% code size on amd64. -=item EV_ASYNC_ENABLE +When optimising for size, use of compiler flags such as C<-Os> with +gcc recommended, as well as C<-DNDEBUG>, as libev contains a number of +assertions. -If undefined or defined to be C<1>, then async watchers are supported. If -defined to be C<0>, then they are not. +=item C<2> - faster/larger data structures -=item EV_MINIMAL +Replaces the small 2-heap for timer management by a faster 4-heap, larger +hash table sizes and so on. This will usually further increase codesize +and can additionally have an effect on the size of data structures at +runtime. -If you need to shave off some kilobytes of code at the expense of some -speed (but with the full API), define this symbol to C<1>. Currently this -is used to override some inlining decisions, saves roughly 30% code size -on amd64. It also selects a much smaller 2-heap for timer management over -the default 4-heap. - -You can save even more by disabling watcher types you do not need -and setting C == C. Also, disabling C -(C<-DNDEBUG>) will usually reduce code size a lot. - -Defining C to C<2> will additionally reduce the core API to -provide a bare-bones event library. See C for details on what parts -of the API are still available, and do not complain if this subset changes -over time. +=item C<4> - full API configuration + +This enables priorities (sets C=2 and C=-2), and +enables multiplicity (C=1). + +It also enables a lot of the "lesser used" core API functions. See C +for details on which parts of the API are still available without this +feature, and do not complain if this subset changes over time. + +=item C<8> - enable all optional watcher types + +Enables all optional watcher types. If you want to selectively enable +only some watcher types other than I/O and timers (e.g. prepare, +embed, async, child...) you can enable them manually by defining +C to C<1> instead. + +=item C<16> - enable all backends + +This enables all backends - without this feature, you need to enable at +least one backend manually (C is a good choice). + +=item C<32> - enable OS-specific "helper" APIs + +Enable inotify, eventfd, signalfd and similar OS-specific helper APIs by +default. + +=back + +Compiling with C +reduces the compiled size of libev from 24.7Kb to 6.5Kb on my GNU/Linux +amd64 system, while still giving you I/O watchers, timers and monotonic +clock support. + +With an intelligent-enough linker (gcc+binutils are intelligent enough +when you use C<-Wl,--gc-sections -ffunction-sections>) functions unused by +your program might be left out as well - a binary starting a timer and an +I/O watcher then might come out at only 5Kb. + +=item EV_AVOID_STDIO + +If this is set to C<1> at compiletime, then libev will avoid using stdio +functions (printf, scanf, perror etc.). This will increase the codesize +somewhat, but if your program doesn't otherwise depend on stdio and your +libc allows it, this avoids linking in the stdio library which is quite +big. + +Note that error messages might become less precise when this option is +enabled. =item EV_NSIG @@ -3885,17 +3992,17 @@ =item EV_PID_HASHSIZE C watchers use a small hash table to distribute workload by -pid. The default size is C<16> (or C<1> with C), usually more -than enough. If you need to manage thousands of children you might want to -increase this value (I be a power of two). +pid. The default size is C<16> (or C<1> with C disabled), +usually more than enough. If you need to manage thousands of children you +might want to increase this value (I be a power of two). =item EV_INOTIFY_HASHSIZE C watchers use a small hash table to distribute workload by -inotify watch id. The default size is C<16> (or C<1> with C), -usually more than enough. If you need to manage thousands of C -watchers you might want to increase this value (I be a power of -two). +inotify watch id. The default size is C<16> (or C<1> with C +disabled), usually more than enough. If you need to manage thousands of +C watchers you might want to increase this value (I be a +power of two). =item EV_USE_4HEAP @@ -3904,8 +4011,8 @@ to C<1>. The 4-heap uses more complicated (longer) code but has noticeably faster performance with many (thousands) of watchers. -The default is C<1> unless C is set in which case it is C<0> -(disabled). +The default is C<1>, unless C overrides it, in which case it +will be C<0>. =item EV_HEAP_CACHE_AT @@ -3916,8 +4023,8 @@ but avoids random read accesses on heap changes. This improves performance noticeably with many (hundreds) of watchers. -The default is C<1> unless C is set in which case it is C<0> -(disabled). +The default is C<1>, unless C overrides it, in which case it +will be C<0>. =item EV_VERIFY @@ -3929,8 +4036,8 @@ verification code will be called very frequently, which will slow down libev considerably. -The default is C<1>, unless C is set, in which case it will be -C<0>. +The default is C<1>, unless C overrides it, in which case it +will be C<0>. =item EV_COMMON @@ -3998,15 +4105,9 @@ The usage in rxvt-unicode is simpler. It has a F header file that everybody includes and which overrides some configure choices: - #define EV_MINIMAL 1 - #define EV_USE_POLL 0 - #define EV_MULTIPLICITY 0 - #define EV_PERIODIC_ENABLE 0 - #define EV_STAT_ENABLE 0 - #define EV_FORK_ENABLE 0 + #define EV_FEATURES 0 + #define EV_USE_SELECT 1 #define EV_CONFIG_H - #define EV_MINPRI 0 - #define EV_MAXPRI 0 #include "ev++.h"