--- libev/ev.pod 2010/02/15 05:15:55 1.279 +++ libev/ev.pod 2010/03/16 00:54:52 1.288 @@ -1540,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 @@ -1869,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. @@ -3619,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 @@ -3784,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 @@ -3833,55 +3878,106 @@ 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 +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: -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. + #define EV_FEATURES 0 + #define EV_MULTIPLICITY 1 + #define EV_USE_POLL 1 + #define EV_CHILD_ENABLE 1 + #define EV_ASYNC_ENABLE 1 -=item EV_EMBED_ENABLE +The actual value is a bitset, it can be a combination of the following +values: -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. +=over 4 -=item EV_STAT_ENABLE +=item C<1> - faster/larger code -If undefined or defined to be C<1>, then stat watchers are supported. If -defined to be C<0>, then they are not. +Use larger code to speed up some operations. -=item EV_FORK_ENABLE +Currently this is used to override some inlining decisions (enlarging the roughly +30% code size on amd64. -If undefined or defined to be C<1>, then fork watchers are supported. If -defined to be C<0>, then they are not. +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. -=item EV_ASYNC_ENABLE +=item C<2> - faster/larger data structures -If undefined or defined to be C<1>, then async watchers are supported. If -defined to be C<0>, then they are not. +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. -=item EV_MINIMAL +=item C<4> - full API configuration -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. +This enables priorities (sets C=2 and C=-2), and +enables multiplicity (C=1). + +=item C<8> - full API + +This enables a lot of the "lesser used" 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<16> - 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<32> - 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<64> - 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 code/2.8Kb data to 6.5Kb +code/0.3Kb data 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 @@ -3895,17 +3991,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 @@ -3914,8 +4010,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 @@ -3926,8 +4022,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 @@ -3939,8 +4035,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 @@ -4008,15 +4104,14 @@ 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 8 + #define EV_USE_SELECT 1 + #define EV_PREPARE_ENABLE 1 + #define EV_IDLE_ENABLE 1 + #define EV_SIGNAL_ENABLE 1 + #define EV_CHILD_ENABLE 1 + #define EV_USE_STDEXCEPT 0 #define EV_CONFIG_H - #define EV_MINPRI 0 - #define EV_MAXPRI 0 #include "ev++.h"