--- libev/ev.pod 2008/09/23 09:13:59 1.185 +++ libev/ev.pod 2008/09/30 19:33:33 1.189 @@ -216,7 +216,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 @@ -252,7 +252,7 @@ ... 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 system call error (such as failed select, poll, epoll_wait). The message is a printable string @@ -1627,7 +1627,7 @@ =head3 Examples -Example: Try to exit cleanly on SIGINT and SIGTERM. +Example: Try to exit cleanly on SIGINT. static void sigint_cb (struct ev_loop *loop, struct ev_signal *w, int revents) @@ -1637,7 +1637,7 @@ struct ev_signal signal_watcher; ev_signal_init (&signal_watcher, sigint_cb, SIGINT); - ev_signal_start (loop, &sigint_cb); + ev_signal_start (loop, &signal_watcher); =head2 C - watch out for process status changes @@ -2244,6 +2244,14 @@ this is to have a separate variables for your embeddable loop, try to create it, and if that fails, use the normal loop for everything. +=head3 C and fork + +While the C watcher is running, forks in the embedding loop will +automatically be applied to the embedded loop as well, so no special +fork handling is required in that case. When the watcher is not running, +however, it is still the task of the libev user to call C +as applicable. + =head3 Watcher-Specific Functions and Data Members =over 4 @@ -3300,17 +3308,19 @@ #include "ev_cpp.h" #include "ev.c" +=head1 INTERACTION WITH OTHER PROGRAMS OR LIBRARIES -=head1 THREADS AND COROUTINES +=head2 THREADS AND COROUTINES -=head2 THREADS +=head3 THREADS -Libev itself is thread-safe (unless the opposite is specifically -documented for a function), but it uses no locking itself. This means that -you can use as many loops as you want in parallel, as long as only one -thread ever calls into one libev function with the same loop parameter: -libev guarantees that different event loops share no data structures that -need locking. +All libev functions are reentrant and thread-safe unless explicitly +documented otherwise, but it uses no locking itself. This means that you +can use as many loops as you want in parallel, as long as there are no +concurrent calls into any libev function with the same loop parameter +(C calls have an implicit default loop parameter, of +course): libev guarantees that different event loops share no data +structures that need any locking. Or to put it differently: calls with different loop parameters can be done concurrently from multiple threads, calls with the same loop parameter @@ -3320,11 +3330,12 @@ Specifically to support threads (and signal handlers), libev implements so-called C watchers, which allow some limited form of -concurrency on the same event loop. +concurrency on the same event loop, namely waking it up "from the +outside". If you want to know which design (one loop, locking, or multiple loops without or something else still) is best for your problem, then I cannot -help you. I can give some generic advice however: +help you, but here is some generic advice: =over 4 @@ -3358,7 +3369,7 @@ =back -=head2 COROUTINES +=head3 COROUTINES Libev is much more accommodating to coroutines ("cooperative threads"): libev fully supports nesting calls to it's functions from different @@ -3370,6 +3381,68 @@ Care has been taken to ensure that libev does not keep local state inside C, and other calls do not usually allow coroutine switches. +=head2 COMPILER WARNINGS + +Depending on your compiler and compiler settings, you might get no or a +lot of warnings when compiling libev code. Some people are apparently +scared by this. + +However, these are unavoidable for many reasons. For one, each compiler +has different warnings, and each user has different tastes regarding +warning options. "Warn-free" code therefore cannot be a goal except when +targeting a specific compiler and compiler-version. + +Another reason is that some compiler warnings require elaborate +workarounds, or other changes to the code that make it less clear and less +maintainable. + +And of course, some compiler warnings are just plain stupid, or simply +wrong (because they don't actually warn about the condition their message +seems to warn about). For example, certain older gcc versions had some +warnings that resulted an extreme number of false positives. These have +been fixed, but some people still insist on making code warn-free with +such buggy versions. + +While libev is written to generate as few warnings as possible, +"warn-free" code is not a goal, and it is recommended not to build libev +with any compiler warnings enabled unless you are prepared to cope with +them (e.g. by ignoring them). Remember that warnings are just that: +warnings, not errors, or proof of bugs. + + +=head1 VALGRIND + +Valgrind has a special section here because it is a popular tool that is +highly useful. Unfortunately, valgrind reports are very hard to interpret. + +If you think you found a bug (memory leak, uninitialised data access etc.) +in libev, then check twice: If valgrind reports something like: + + ==2274== definitely lost: 0 bytes in 0 blocks. + ==2274== possibly lost: 0 bytes in 0 blocks. + ==2274== still reachable: 256 bytes in 1 blocks. + +Then there is no memory leak, just as memory accounted to global variables +is not a memleak - the memory is still being refernced, and didn't leak. + +Similarly, under some circumstances, valgrind might report kernel bugs +as if it were a bug in libev (e.g. in realloc or in the poll backend, +although an acceptable workaround has been found here), or it might be +confused. + +Keep in mind that valgrind is a very good tool, but only a tool. Don't +make it into some kind of religion. + +If you are unsure about something, feel free to contact the mailing list +with the full valgrind report and an explanation on why you think this +is a bug in libev (best check the archives, too :). However, don't be +annoyed when you get a brisk "this is no bug" answer and take the chance +of learning how to interpret valgrind properly. + +If you need, for some reason, empty reports from valgrind for your project +I suggest using suppression lists. + + =head1 COMPLEXITIES @@ -3441,7 +3514,9 @@ =back -=head1 WIN32 PLATFORM LIMITATIONS AND WORKAROUNDS +=head1 PORTABILITY + +=head2 WIN32 PLATFORM LIMITATIONS AND WORKAROUNDS 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 @@ -3538,11 +3613,10 @@ =back +=head2 PORTABILITY REQUIREMENTS -=head1 PORTABILITY REQUIREMENTS - -In addition to a working ISO-C implementation, libev relies on a few -additional extensions: +In addition to a working ISO-C implementation and of course the +backend-specific APIs, libev relies on a few additional extensions: =over 4 @@ -3577,11 +3651,11 @@ =item C must be large enough for common memory allocation sizes -To improve portability and simplify using libev, 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. +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 @@ -3595,58 +3669,6 @@ If you know of other additional requirements drop me a note. -=head1 COMPILER WARNINGS - -Depending on your compiler and compiler settings, you might get no or a -lot of warnings when compiling libev code. Some people are apparently -scared by this. - -However, these are unavoidable for many reasons. For one, each compiler -has different warnings, and each user has different tastes regarding -warning options. "Warn-free" code therefore cannot be a goal except when -targeting a specific compiler and compiler-version. - -Another reason is that some compiler warnings require elaborate -workarounds, or other changes to the code that make it less clear and less -maintainable. - -And of course, some compiler warnings are just plain stupid, or simply -wrong (because they don't actually warn about the condition their message -seems to warn about). - -While libev is written to generate as few warnings as possible, -"warn-free" code is not a goal, and it is recommended not to build libev -with any compiler warnings enabled unless you are prepared to cope with -them (e.g. by ignoring them). Remember that warnings are just that: -warnings, not errors, or proof of bugs. - - -=head1 VALGRIND - -Valgrind has a special section here because it is a popular tool that is -highly useful, but valgrind reports are very hard to interpret. - -If you think you found a bug (memory leak, uninitialised data access etc.) -in libev, then check twice: If valgrind reports something like: - - ==2274== definitely lost: 0 bytes in 0 blocks. - ==2274== possibly lost: 0 bytes in 0 blocks. - ==2274== still reachable: 256 bytes in 1 blocks. - -Then there is no memory leak. Similarly, under some circumstances, -valgrind might report kernel bugs as if it were a bug in libev, or it -might be confused (it is a very good tool, but only a tool). - -If you are unsure about something, feel free to contact the mailing list -with the full valgrind report and an explanation on why you think this is -a bug in libev. However, don't be annoyed when you get a brisk "this is -no bug" answer and take the chance of learning how to interpret valgrind -properly. - -If you need, for some reason, empty reports from valgrind for your project -I suggest using suppression lists. - - =head1 AUTHOR Marc Lehmann .