EV-4.22/0000755000000000000000000000000012635402734010457 5ustar rootrootEV-4.22/typemap0000644000000000000000000000250411462612617012062 0ustar rootrootSignal T_SIGNAL struct ev_loop * T_LOOP ev_watcher * T_WATCHER ev_io * T_WATCHER ev_timer * T_WATCHER ev_periodic * T_WATCHER ev_signal * T_WATCHER ev_idle * T_WATCHER ev_prepare * T_WATCHER ev_check * T_WATCHER ev_child * T_WATCHER ev_embed * T_WATCHER ev_stat * T_WATCHER ev_fork * T_WATCHER ev_cleanup * T_WATCHER ev_async * T_WATCHER char * T_PVbyte const char * T_PVbyte INPUT T_SIGNAL if (($var = s_signum_croak ($arg)) <= 0) croak (\"'%s' is not a valid signal number or name\", SvPV_nolen ($arg)); T_PVbyte $var = ($type)SvPVbyte_nolen ($arg) T_LOOP if (!(SvROK ($arg) && SvOBJECT (SvRV ($arg)) && (SvSTASH (SvRV ($arg)) == stash_loop || sv_derived_from ($arg, \"EV::Loop\")))) croak (\"object is not of type EV::Loop\"); $var = ($type)SvIVX (SvRV ($arg)); T_WATCHER if (!(SvROK ($arg) && SvOBJECT (SvRV ($arg)) && (SvSTASH (SvRV ($arg)) == stash_" . ($type =~ /ev_(\S+)/, "$1") . " || sv_derived_from ($arg, \"EV::" . ($type =~ /ev_(\S+)/, ucfirst "$1") . "\")))) croak (\"object is not of type EV::" . ($type =~ /ev_(\S+)/, ucfirst "$1") . "\"); $var = ($type)SvPVX (SvRV ($arg)); OUTPUT T_PVbyte sv_setpv ((SV *)$arg, $var); T_WATCHER $arg = e_bless ((struct ev_watcher *)$var, stash_${ ($type =~ /ev_(\S+)/, \"$1") }); EV-4.22/libev/0000755000000000000000000000000012635402734011560 5ustar rootrootEV-4.22/libev/Changes0000644000000000000000000006604112635402372013060 0ustar rootrootRevision history for libev, a high-performance and full-featured event loop. TODO: ev_loop_wakeup TODO: EV_STANDALONE == NO_HASSEL (do not use clock_gettime in ev_standalone) TODO: faq, process a thing in each iteration TODO: dbeugging tips, ev_verify, ev_init twice TODO: ev_break for immediate exit (EVBREAK_NOW?) TODO: ev_feed_child_event TODO: document the special problem of signals around fork. TODO: store pid for each signal TODO: document file descriptor usage per loop TODO: store loop pid_t and compare isndie signal handler,store 1 for same, 2 for differign pid, clean up in loop_fork TODO: embed watchers need updating when fd changes TODO: document portability requirements for atomic pointer access TODO: document requirements for function pointers and calling conventions. 4.22 - when epoll detects unremovable fds in the fd set, rebuild only the epoll descriptor, not the signal pipe, to avoid SIGPIPE in ev_async_send. This doesn't solve it on fork, so document what needs to be done in ev_loop_fork (analyzed by Benjamin Mahler). - remove superfluous sys/timeb.h include on win32 (analyzed by Jason Madden). - updated libecb. 4.20 Sat Jun 20 13:01:43 CEST 2015 - prefer noexcept over throw () with C++ 11. - update ecb.h due to incompatibilities with c11. - fix a potential aliasing issue when reading and writing watcher callbacks. 4.19 Thu Sep 25 08:18:25 CEST 2014 - ev.h wasn't valid C++ anymore, which tripped compilers other than clang, msvc or gcc (analyzed by Raphael 'kena' Poss). Unfortunately, C++ doesn't support typedefs for function pointers fully, so the affected declarations have to spell out the types each time. - when not using autoconf, tighten the check for clock_gettime and related functionality. 4.18 Fri Sep 5 17:55:26 CEST 2014 - events on files were not always generated properly with the epoll backend (testcase by Assaf Inbal). - mark event pipe fd as cloexec after a fork (analyzed by Sami Farin). - (ecb) support m68k, m88k and sh (patch by Miod Vallat). - use a reasonable fallback for EV_NSIG instead of erroring out when we can't detect the signal set size. - in the absence of autoconf, do not use the clock syscall on glibc >= 2.17 (avoids the syscall AND -lrt on systems doing clock_gettime in userspace). - ensure extern "C" function pointers are used for externally-visible loop callbacks (not watcher callbacks yet). - (ecb) work around memory barriers and volatile apparently both being broken in visual studio 2008 and later (analysed and patch by Nicolas Noble). 4.15 Fri Mar 1 12:04:50 CET 2013 - destroying a non-default loop would stop the global waitpid watcher (Denis Bilenko). - queueing pending watchers of higher priority from a watcher now invokes them in a timely fashion (reported by Denis Bilenko). - add throw() to all libev functions that cannot throw exceptions, for further code size decrease when compiling for C++. - add throw () to callbacks that must not throw exceptions (allocator, syserr, loop acquire/release, periodic reschedule cbs). - fix event_base_loop return code, add event_get_callback, event_base_new, event_base_get_method calls to improve libevent 1.x emulation and add some libevent 2.x functionality (based on a patch by Jeff Davey). - add more memory fences to fix a bug reported by Jeff Davey. Better be overfenced than underprotected. - ev_run now returns a boolean status (true meaning watchers are still active). - ev_once: undef EV_ERROR in ev_kqueue.c, to avoid clashing with libev's EV_ERROR (reported by 191919). - (ecb) add memory fence support for xlC (Darin McBride). - (ecb) add memory fence support for gcc-mips (Anton Kirilov). - (ecb) add memory fence support for gcc-alpha (Christian Weisgerber). - work around some kernels losing file descriptors by leaking the kqueue descriptor in the child. - work around linux inotify not reporting IN_ATTRIB changes for directories in many cases. - include sys/syscall.h instead of plain syscall.h. - check for io watcher loops in ev_verify, check for the most common reported usage bug in ev_io_start. - choose socket vs. WSASocket at compiletime using EV_USE_WSASOCKET. - always use WSASend/WSARecv directly on windows, hoping that this works in all cases (unlike read/write/send/recv...). - try to detect signals around a fork faster (test program by Denis Bilenko). - work around recent glibc versions that leak memory in realloc. - rename ev::embed::set to ev::embed::set_embed to avoid clashing the watcher base set (loop) method. - rewrite the async/signal pipe logic to always keep a valid fd, which simplifies (and hopefully correctifies :) the race checking on fork, at the cost of one extra fd. - add fat, msdos, jffs2, ramfs, ntfs and btrfs to the list of inotify-supporting filesystems. - move orig_CFLAGS assignment to after AC_INIT, as newer autoconf versions ignore it before (https://bugzilla.redhat.com/show_bug.cgi?id=908096). - add some untested android support. - enum expressions must be of type int (reported by Juan Pablo L). 4.11 Sat Feb 4 19:52:39 CET 2012 - INCOMPATIBLE CHANGE: ev_timer_again now clears the pending status, as was documented already, but not implemented in the repeating case. - new compiletime symbols: EV_NO_SMP and EV_NO_THREADS. - fix a race where the workaround against the epoll fork bugs caused signals to not be handled anymore. - correct backend_fudge for most backends, and implement a windows specific workaround to avoid looping because we call both select and Sleep, both with different time resolutions. - document range and guarantees of ev_sleep. - document reasonable ranges for periodics interval and offset. - rename backend_fudge to backend_mintime to avoid future confusion :) - change the default periodic reschedule function to hopefully be more exact and correct even in corner cases or in the far future. - do not rely on -lm anymore: use it when available but use our own floor () if it is missing. This should make it easier to embed, as no external libraries are required. - strategically import macros from libecb and mark rarely-used functions as cache-cold (saving almost 2k code size on typical amd64 setups). - add Symbols.ev and Symbols.event files, that were missing. - fix backend_mintime value for epoll (was 1/1024, is 1/1000 now). - fix #3 "be smart about timeouts" to not "deadlock" when timeout == now, also improve the section overall. - avoid "AVOIDING FINISHING BEFORE RETURNING" idiom. - support new EV_API_STATIC mode to make all libev symbols static. - supply default CFLAGS of -g -O3 with gcc when original CFLAGS were empty. 4.04 Wed Feb 16 09:01:51 CET 2011 - fix two problems in the native win32 backend, where reuse of fd's with different underlying handles caused handles not to be removed or added to the select set (analyzed and tested by Bert Belder). - do no rely on ceil() in ev_e?poll.c. - backport libev to HP-UX versions before 11 v3. - configure did not detect nanosleep and clock_gettime properly when they are available in the libc (as opposed to -lrt). 4.03 Tue Jan 11 14:37:25 CET 2011 - officially support polling files with all backends. - support files, /dev/zero etc. the same way as select in the epoll backend, by generating events on our own. - ports backend: work around solaris bug 6874410 and many related ones (EINTR, maybe more), with no performance loss (note that the solaris bug report is actually wrong, reality is far more bizarre and broken than that). - define EV_READ/EV_WRITE as macros in event.h, as some programs use #ifdef to test for them. - new (experimental) function: ev_feed_signal. - new (to become default) EVFLAG_NOSIGMASK flag. - new EVBACKEND_MASK symbol. - updated COMMON IDIOMS SECTION. 4.01 Fri Nov 5 21:51:29 CET 2010 - automake fucked it up, apparently, --add-missing -f is not quite enough to make it update its files, so 4.00 didn't install ev++.h and event.h on make install. grrr. - ev_loop(count|depth) didn't return anything (Robin Haberkorn). - change EV_UNDEF to 0xffffffff to silence some overzealous compilers. - use "(libev) " prefix for all libev error messages now. 4.00 Mon Oct 25 12:32:12 CEST 2010 - "PORTING FROM LIBEV 3.X TO 4.X" (in ev.pod) is recommended reading. - ev_embed_stop did not correctly stop the watcher (very good testcase by Vladimir Timofeev). - ev_run will now always update the current loop time - it erroneously didn't when idle watchers were active, causing timers not to fire. - fix a bug where a timeout of zero caused the timer not to fire in the libevent emulation (testcase by Péter Szabó). - applied win32 fixes by Michael Lenaghan (also James Mansion). - replace EV_MINIMAL by EV_FEATURES. - prefer EPOLL_CTL_ADD over EPOLL_CTL_MOD in some more cases, as it seems the former is *much* faster than the latter. - linux kernel version detection (for inotify bug workarounds) did not work properly. - reduce the number of spurious wake-ups with the ports backend. - remove dependency on sys/queue.h on freebsd (patch by Vanilla Hsu). - do async init within ev_async_start, not ev_async_set, which avoids an API quirk where the set function must be called in the C++ API even when there is nothing to set. - add (undocumented) EV_ENABLE when adding events with kqueue, this might help with OS X, which seems to need it despite documenting not to need it (helpfully pointed out by Tilghman Lesher). - do not use poll by default on freebsd, it's broken (what isn't on freebsd...). - allow to embed epoll on kernels >= 2.6.32. - configure now prepends -O3, not appends it, so one can still override it. - ev.pod: greatly expanded the portability section, added a porting section, a description of watcher states and made lots of minor fixes. - disable poll backend on AIX, the poll header spams the namespace and it's not worth working around dead platforms (reported and analyzed by Aivars Kalvans). - improve header file compatibility of the standalone eventfd code in an obscure case. - implement EV_AVOID_STDIO option. - do not use sscanf to parse linux version number (smaller, faster, no sscanf dependency). - new EV_CHILD_ENABLE and EV_SIGNAL_ENABLE configurable settings. - update libev.m4 HAVE_CLOCK_SYSCALL test for newer glibcs. - add section on accept() problems to the manpage. - rename EV_TIMEOUT to EV_TIMER. - rename ev_loop_count/depth/verify/loop/unloop. - remove ev_default_destroy and ev_default_fork. - switch to two-digit minor version. - work around an apparent gentoo compiler bug. - define _DARWIN_UNLIMITED_SELECT. just so. - use enum instead of #define for most constants. - improve compatibility to older C++ compilers. - (experimental) ev_run/ev_default_loop/ev_break/ev_loop_new have now default arguments when compiled as C++. - enable automake dependency tracking. - ev_loop_new no longer leaks memory when loop creation failed. - new ev_cleanup watcher type. 3.9 Thu Dec 31 07:59:59 CET 2009 - signalfd is no longer used by default and has to be requested explicitly - this means that easy to catch bugs become hard to catch race conditions, but the users have spoken. - point out the unspecified signal mask in the documentation, and that this is a race condition regardless of EV_SIGNALFD. - backport inotify code to C89. - inotify file descriptors could leak into child processes. - ev_stat watchers could keep an erroneous extra ref on the loop, preventing exit when unregistering all watchers (testcases provided by ry@tinyclouds.org). - implement EV_WIN32_HANDLE_TO_FD and EV_WIN32_CLOSE_FD configuration symbols to make it easier for apps to do their own fd management. - support EV_IDLE_ENABLE being disabled in ev++.h (patch by Didier Spezia). - take advantage of inotify_init1, if available, to set cloexec/nonblock on fd creation, to avoid races. - the signal handling pipe wasn't always initialised under windows (analysed by lekma). - changed minimum glibc requirement from glibc 2.9 to 2.7, for signalfd. - add missing string.h include (Denis F. Latypoff). - only replace ev_stat.prev when we detect an actual difference, so prev is (almost) always different to attr. this might have caused the problems with 04_stat.t. - add ev::timer->remaining () method to C++ API. 3.8 Sun Aug 9 14:30:45 CEST 2009 - incompatible change: do not necessarily reset signal handler to SIG_DFL when a sighandler is stopped. - ev_default_destroy did not properly free or zero some members, potentially causing crashes and memory corruption on repeated ev_default_destroy/ev_default_loop calls. - take advantage of signalfd on GNU/Linux systems. - document that the signal mask might be in an unspecified state when using libev's signal handling. - take advantage of some GNU/Linux calls to set cloexec/nonblock on fd creation, to avoid race conditions. 3.7 Fri Jul 17 16:36:32 CEST 2009 - ev_unloop and ev_loop wrongly used a global variable to exit loops, instead of using a per-loop variable (bug caught by accident...). - the ev_set_io_collect_interval interpretation has changed. - add new functionality: ev_set_userdata, ev_userdata, ev_set_invoke_pending_cb, ev_set_loop_release_cb, ev_invoke_pending, ev_pending_count, together with a long example about thread locking. - add ev_timer_remaining (as requested by Denis F. Latypoff). - add ev_loop_depth. - calling ev_unloop in fork/prepare watchers will no longer poll for new events. - Denis F. Latypoff corrected many typos in example code snippets. - honor autoconf detection of EV_USE_CLOCK_SYSCALL, also double- check that the syscall number is available before trying to use it (reported by ry@tinyclouds). - use GetSystemTimeAsFileTime instead of _timeb on windows, for slightly higher accuracy. - properly declare ev_loop_verify and ev_now_update even when !EV_MULTIPLICITY. - do not compile in any priority code when EV_MAXPRI == EV_MINPRI. - support EV_MINIMAL==2 for a reduced API. - actually 0-initialise struct sigaction when installing signals. - add section on hibernate and stopped processes to ev_timer docs. 3.6 Tue Apr 28 02:49:30 CEST 2009 - multiple timers becoming ready within an event loop iteration will be invoked in the "correct" order now. - do not leave the event loop early just because we have no active watchers, fixing a problem when embedding a kqueue loop that has active kernel events but no registered watchers (reported by blacksand blacksand). - correctly zero the idx values for arrays, so destroying and reinitialising the default loop actually works (patch by Malek Hadj-Ali). - implement ev_suspend and ev_resume. - new EV_CUSTOM revents flag for use by applications. - add documentation section about priorities. - add a glossary to the documentation. - extend the ev_fork description slightly. - optimize a jump out of call_pending. 3.53 Sun Feb 15 02:38:20 CET 2009 - fix a bug in event pipe creation on win32 that would cause a failed assertion on event loop creation (patch by Malek Hadj-Ali). - probe for CLOCK_REALTIME support at runtime as well and fall back to gettimeofday if there is an error, to support older operating systems with newer header files/libraries. - prefer gettimeofday over clock_gettime with USE_CLOCK_SYSCALL (default most everywhere), otherwise not. 3.52 Wed Jan 7 21:43:02 CET 2009 - fix compilation of select backend in fd_set mode when NFDBITS is missing (to get it to compile on QNX, reported by Rodrigo Campos). - better select-nfds handling when select backend is in fd_set mode. - diagnose fd_set overruns when select backend is in fd_set mode. - due to a thinko, instead of disabling everything but select on the borked OS X platform, everything but select was allowed (reported by Emanuele Giaquinta). - actually verify that local and remote port are matching in libev's socketpair emulation, which makes denial-of-service attacks harder (but not impossible - it's windows). Make sure it even works under vista, which thinks that getpeer/sockname should return fantasy port numbers. - include "libev" in all assertion messages for potentially clearer diagnostics. - event_get_version (libevent compatibility) returned a useless string instead of the expected version string (patch by W.C.A. Wijngaards). 3.51 Wed Dec 24 23:00:11 CET 2008 - fix a bug where an inotify watcher was added twice, causing freezes on hash collisions (reported and analysed by Graham Leggett). - new config symbol, EV_USE_CLOCK_SYSCALL, to make libev use a direct syscall - slower, but no dependency on librt et al. - assume negative return values != -1 signals success of port_getn (http://cvs.epicsol.org/cgi/viewcvs.cgi/epic5/source/newio.c?rev=1.52) (no known failure reports, but it doesn't hurt). - fork detection in ev_embed now stops and restarts the watcher automatically. - EXPERIMENTAL: default the method to operator () in ev++.h, to make it nicer to use functors (requested by Benedek László). - fixed const object callbacks in ev++.h. - replaced loop_ref argument of watcher.set (loop) by a direct ev_loop * in ev++.h, to avoid clashes with functor patch. - do not try to watch the empty string via inotify. - inotify watchers could be leaked under certain circumstances. - OS X 10.5 is actually even more broken than earlier versions, so fall back to select on that piece of garbage. - fixed some weirdness in the ev_embed documentation. 3.49 Wed Nov 19 11:26:53 CET 2008 - ev_stat watchers will now use inotify as a mere hint on kernels <2.6.25, or if the filesystem is not in the "known to be good" list. - better mingw32 compatibility (it's not as borked as native win32) (analysed by Roger Pack). - include stdio.h in the example program, as too many people are confused by the weird C language otherwise. I guess the next thing I get told is that the "..." ellipses in the examples don't compile with their C compiler. 3.48 Thu Oct 30 09:02:37 CET 2008 - further optimise away the EPOLL_CTL_ADD/MOD combo in the epoll backend by assuming the kernel event mask hasn't changed if ADD fails with EEXIST. - work around spurious event notification bugs in epoll by using a 32-bit generation counter. recreate kernel state if we receive spurious notifications or unwanted events. this is very costly, but I didn't come up with this horrible design. - use memset to initialise most arrays now and do away with the init functions. - expand time-out strategies into a "Be smart about timeouts" section. - drop the "struct" from all ev_watcher declarations in the documentation and did other clarifications (yeah, it was a mistake to have a struct AND a function called ev_loop). - fix a bug where ev_default would not initialise the default loop again after it was destroyed with ev_default_destroy. - rename syserr to ev_syserr to avoid name clashes when embedding, do similar changes for event.c. 3.45 Tue Oct 21 21:59:26 CEST 2008 - disable inotify usage on linux <2.6.25, as it is broken (reported by Yoann Vandoorselaere). - ev_stat erroneously would try to add inotify watchers even when inotify wasn't available (this should only have a performance impact). - ev_once now passes both timeout and io to the callback if both occur concurrently, instead of giving timeouts precedence. - disable EV_USE_INOTIFY when sys/inotify.h is too old. 3.44 Mon Sep 29 05:18:39 CEST 2008 - embed watchers now automatically invoke ev_loop_fork on the embedded loop when the parent loop forks. - new function: ev_now_update (loop). - verify_watcher was not marked static. - improve the "associating..." manpage section. - documentation tweaks here and there. 3.43 Sun Jul 6 05:34:41 CEST 2008 - include more include files on windows to get struct _stati64 (reported by Chris Hulbert, but doesn't quite fix his issue). - add missing #include in ev.c on windows (reported by Matt Tolton). 3.42 Tue Jun 17 12:12:07 CEST 2008 - work around yet another windows bug: FD_SET actually adds fd's multiple times to the fd_*SET*, despite official MSN docs claiming otherwise. Reported and well-analysed by Matt Tolton. - define NFDBITS to 0 when EV_SELECT_IS_WINSOCKET to make it compile (reported any analysed by Chris Hulbert). - fix a bug in ev_ebadf (this function is only used to catch programming errors in the libev user). reported by Matt Tolton. - fix a bug in fd_intern on win32 (could lead to compile errors under some circumstances, but would work correctly if it compiles). reported by Matt Tolton. - (try to) work around missing lstat on windows. - pass in the write fd set as except fd set under windows. windows is so uncontrollably lame that it requires this. this means that switching off oobinline is not supported (but tcp/ip doesn't have oob, so that would be stupid anyways. - use posix module symbol to auto-detect monotonic clock presence and some other default values. 3.41 Fri May 23 18:42:54 CEST 2008 - work around an obscure bug in winsocket select: if you provide only empty fd sets then select returns WSAEINVAL. how sucky. - improve timer scheduling stability and reduce use of time_epsilon. - use 1-based 2-heap for EV_MINIMAL, simplifies code, reduces codesize and makes for better cache-efficiency. - use 3-based 4-heap for !EV_MINIMAL. this makes better use of cpu cache lines and gives better growth behaviour than 2-based heaps. - cache timestamp within heap for !EV_MINIMAL, to avoid random memory accesses. - document/add EV_USE_4HEAP and EV_HEAP_CACHE_AT. - fix a potential aliasing issue in ev_timer_again. - add/document ev_periodic_at, retract direct access to ->at. - improve ev_stat docs. - add portability requirements section. - fix manpage headers etc. - normalise WSA error codes to lower range on windows. - add consistency check code that can be called automatically or on demand to check for internal structures (ev_loop_verify). 3.31 Wed Apr 16 20:45:04 CEST 2008 - added last minute fix for ev_poll.c by Brandon Black. 3.3 Wed Apr 16 19:04:10 CEST 2008 - event_base_loopexit should return 0 on success (W.C.A. Wijngaards). - added linux eventfd support. - try to autodetect epoll and inotify support by libc header version if not using autoconf. - new symbols: EV_DEFAULT_UC and EV_DEFAULT_UC_. - declare functions defined in ev.h as inline if C99 or gcc are available. - enable inlining with gcc versions 2 and 3. - work around broken poll implementations potentially not clearing revents field in ev_poll (Brandon Black) (no such systems are known at this time). - work around a bug in realloc on openbsd and darwin, also makes the erroneous valgrind complaints go away (noted by various people). - fix ev_async_pending, add c++ wrapper for ev_async (based on patch sent by Johannes Deisenhofer). - add sensible set method to ev::embed. - made integer constants type int in ev.h. 3.2 Wed Apr 2 17:11:19 CEST 2008 - fix a 64 bit overflow issue in the select backend, by using fd_mask instead of int for the mask. - rename internal sighandler to avoid clash with very old perls. - entering ev_loop will not clear the ONESHOT or NONBLOCKING flags of any outer loops anymore. - add ev_async_pending. 3.1 Thu Mar 13 13:45:22 CET 2008 - implement ev_async watchers. - only initialise signal pipe on demand. - make use of sig_atomic_t configurable. - improved documentation. 3.0 Mon Jan 28 13:14:47 CET 2008 - API/ABI bump to version 3.0. - ev++.h includes "ev.h" by default now, not . - slightly improved documentation. - speed up signal detection after a fork. - only optionally return trace status changed in ev_child watchers. - experimental (and undocumented) loop wrappers for ev++.h. 2.01 Tue Dec 25 08:04:41 CET 2007 - separate Changes file. - fix ev_path_set => ev_stat_set typo. - remove event_compat.h from the libev tarball. - change how include files are found. - doc updates. - update licenses, explicitly allow for GPL relicensing. 2.0 Sat Dec 22 17:47:03 CET 2007 - new ev_sleep, ev_set_(io|timeout)_collect_interval. - removed epoll from embeddable fd set. - fix embed watchers. - renamed ev_embed.loop to other. - added exported Symbol tables. - undefine member wrapper macros at the end of ev.c. - respect EV_H in ev++.h. 1.86 Tue Dec 18 02:36:57 CET 2007 - fix memleak on loop destroy (not relevant for perl). 1.85 Fri Dec 14 20:32:40 CET 2007 - fix some aliasing issues w.r.t. timers and periodics (not relevant for perl). (for historic versions refer to EV/Changes, found in the Perl interface) 0.1 Wed Oct 31 21:31:48 CET 2007 - original version; hacked together in <24h. EV-4.22/libev/ev_epoll.c0000644000000000000000000002321612606771604013540 0ustar rootroot/* * libev epoll fd activity backend * * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License ("GPL") version 2 or any later version, * in which case the provisions of the GPL are applicable instead of * the above. If you wish to allow the use of your version of this file * only under the terms of the GPL and not to allow others to use your * version of this file under the BSD license, indicate your decision * by deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete the * provisions above, a recipient may use your version of this file under * either the BSD or the GPL. */ /* * general notes about epoll: * * a) epoll silently removes fds from the fd set. as nothing tells us * that an fd has been removed otherwise, we have to continually * "rearm" fds that we suspect *might* have changed (same * problem with kqueue, but much less costly there). * b) the fact that ADD != MOD creates a lot of extra syscalls due to a) * and seems not to have any advantage. * c) the inability to handle fork or file descriptors (think dup) * limits the applicability over poll, so this is not a generic * poll replacement. * d) epoll doesn't work the same as select with many file descriptors * (such as files). while not critical, no other advanced interface * seems to share this (rather non-unixy) limitation. * e) epoll claims to be embeddable, but in practise you never get * a ready event for the epoll fd (broken: <=2.6.26, working: >=2.6.32). * f) epoll_ctl returning EPERM means the fd is always ready. * * lots of "weird code" and complication handling in this file is due * to these design problems with epoll, as we try very hard to avoid * epoll_ctl syscalls for common usage patterns and handle the breakage * ensuing from receiving events for closed and otherwise long gone * file descriptors. */ #include #define EV_EMASK_EPERM 0x80 static void epoll_modify (EV_P_ int fd, int oev, int nev) { struct epoll_event ev; unsigned char oldmask; /* * we handle EPOLL_CTL_DEL by ignoring it here * on the assumption that the fd is gone anyways * if that is wrong, we have to handle the spurious * event in epoll_poll. * if the fd is added again, we try to ADD it, and, if that * fails, we assume it still has the same eventmask. */ if (!nev) return; oldmask = anfds [fd].emask; anfds [fd].emask = nev; /* store the generation counter in the upper 32 bits, the fd in the lower 32 bits */ ev.data.u64 = (uint64_t)(uint32_t)fd | ((uint64_t)(uint32_t)++anfds [fd].egen << 32); ev.events = (nev & EV_READ ? EPOLLIN : 0) | (nev & EV_WRITE ? EPOLLOUT : 0); if (expect_true (!epoll_ctl (backend_fd, oev && oldmask != nev ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, fd, &ev))) return; if (expect_true (errno == ENOENT)) { /* if ENOENT then the fd went away, so try to do the right thing */ if (!nev) goto dec_egen; if (!epoll_ctl (backend_fd, EPOLL_CTL_ADD, fd, &ev)) return; } else if (expect_true (errno == EEXIST)) { /* EEXIST means we ignored a previous DEL, but the fd is still active */ /* if the kernel mask is the same as the new mask, we assume it hasn't changed */ if (oldmask == nev) goto dec_egen; if (!epoll_ctl (backend_fd, EPOLL_CTL_MOD, fd, &ev)) return; } else if (expect_true (errno == EPERM)) { /* EPERM means the fd is always ready, but epoll is too snobbish */ /* to handle it, unlike select or poll. */ anfds [fd].emask = EV_EMASK_EPERM; /* add fd to epoll_eperms, if not already inside */ if (!(oldmask & EV_EMASK_EPERM)) { array_needsize (int, epoll_eperms, epoll_epermmax, epoll_epermcnt + 1, EMPTY2); epoll_eperms [epoll_epermcnt++] = fd; } return; } fd_kill (EV_A_ fd); dec_egen: /* we didn't successfully call epoll_ctl, so decrement the generation counter again */ --anfds [fd].egen; } static void epoll_poll (EV_P_ ev_tstamp timeout) { int i; int eventcnt; if (expect_false (epoll_epermcnt)) timeout = 0.; /* epoll wait times cannot be larger than (LONG_MAX - 999UL) / HZ msecs, which is below */ /* the default libev max wait time, however. */ EV_RELEASE_CB; eventcnt = epoll_wait (backend_fd, epoll_events, epoll_eventmax, timeout * 1e3); EV_ACQUIRE_CB; if (expect_false (eventcnt < 0)) { if (errno != EINTR) ev_syserr ("(libev) epoll_wait"); return; } for (i = 0; i < eventcnt; ++i) { struct epoll_event *ev = epoll_events + i; int fd = (uint32_t)ev->data.u64; /* mask out the lower 32 bits */ int want = anfds [fd].events; int got = (ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0) | (ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0); /* * check for spurious notification. * this only finds spurious notifications on egen updates * other spurious notifications will be found by epoll_ctl, below * we assume that fd is always in range, as we never shrink the anfds array */ if (expect_false ((uint32_t)anfds [fd].egen != (uint32_t)(ev->data.u64 >> 32))) { /* recreate kernel state */ postfork |= 2; continue; } if (expect_false (got & ~want)) { anfds [fd].emask = want; /* * we received an event but are not interested in it, try mod or del * this often happens because we optimistically do not unregister fds * when we are no longer interested in them, but also when we get spurious * notifications for fds from another process. this is partially handled * above with the gencounter check (== our fd is not the event fd), and * partially here, when epoll_ctl returns an error (== a child has the fd * but we closed it). */ ev->events = (want & EV_READ ? EPOLLIN : 0) | (want & EV_WRITE ? EPOLLOUT : 0); /* pre-2.6.9 kernels require a non-null pointer with EPOLL_CTL_DEL, */ /* which is fortunately easy to do for us. */ if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev)) { postfork |= 2; /* an error occurred, recreate kernel state */ continue; } } fd_event (EV_A_ fd, got); } /* if the receive array was full, increase its size */ if (expect_false (eventcnt == epoll_eventmax)) { ev_free (epoll_events); epoll_eventmax = array_nextsize (sizeof (struct epoll_event), epoll_eventmax, epoll_eventmax + 1); epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax); } /* now synthesize events for all fds where epoll fails, while select works... */ for (i = epoll_epermcnt; i--; ) { int fd = epoll_eperms [i]; unsigned char events = anfds [fd].events & (EV_READ | EV_WRITE); if (anfds [fd].emask & EV_EMASK_EPERM && events) fd_event (EV_A_ fd, events); else { epoll_eperms [i] = epoll_eperms [--epoll_epermcnt]; anfds [fd].emask = 0; } } } int inline_size epoll_init (EV_P_ int flags) { #ifdef EPOLL_CLOEXEC backend_fd = epoll_create1 (EPOLL_CLOEXEC); if (backend_fd < 0 && (errno == EINVAL || errno == ENOSYS)) #endif backend_fd = epoll_create (256); if (backend_fd < 0) return 0; fcntl (backend_fd, F_SETFD, FD_CLOEXEC); backend_mintime = 1e-3; /* epoll does sometimes return early, this is just to avoid the worst */ backend_modify = epoll_modify; backend_poll = epoll_poll; epoll_eventmax = 64; /* initial number of events receivable per poll */ epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax); return EVBACKEND_EPOLL; } void inline_size epoll_destroy (EV_P) { ev_free (epoll_events); array_free (epoll_eperm, EMPTY); } void inline_size epoll_fork (EV_P) { close (backend_fd); while ((backend_fd = epoll_create (256)) < 0) ev_syserr ("(libev) epoll_create"); fcntl (backend_fd, F_SETFD, FD_CLOEXEC); fd_rearm_all (EV_A); } EV-4.22/libev/ev_port.c0000644000000000000000000001440412337443634013410 0ustar rootroot/* * libev solaris event port backend * * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License ("GPL") version 2 or any later version, * in which case the provisions of the GPL are applicable instead of * the above. If you wish to allow the use of your version of this file * only under the terms of the GPL and not to allow others to use your * version of this file under the BSD license, indicate your decision * by deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete the * provisions above, a recipient may use your version of this file under * either the BSD or the GPL. */ /* useful reading: * * http://bugs.opensolaris.org/view_bug.do?bug_id=6268715 (random results) * http://bugs.opensolaris.org/view_bug.do?bug_id=6455223 (just totally broken) * http://bugs.opensolaris.org/view_bug.do?bug_id=6873782 (manpage ETIME) * http://bugs.opensolaris.org/view_bug.do?bug_id=6874410 (implementation ETIME) * http://www.mail-archive.com/networking-discuss@opensolaris.org/msg11898.html ETIME vs. nget * http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/gen/event_port.c (libc) * http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/fs/portfs/port.c#1325 (kernel) */ #include #include #include #include #include #include void inline_speed port_associate_and_check (EV_P_ int fd, int ev) { if (0 > port_associate ( backend_fd, PORT_SOURCE_FD, fd, (ev & EV_READ ? POLLIN : 0) | (ev & EV_WRITE ? POLLOUT : 0), 0 ) ) { if (errno == EBADFD) fd_kill (EV_A_ fd); else ev_syserr ("(libev) port_associate"); } } static void port_modify (EV_P_ int fd, int oev, int nev) { /* we need to reassociate no matter what, as closes are * once more silently being discarded. */ if (!nev) { if (oev) port_dissociate (backend_fd, PORT_SOURCE_FD, fd); } else port_associate_and_check (EV_A_ fd, nev); } static void port_poll (EV_P_ ev_tstamp timeout) { int res, i; struct timespec ts; uint_t nget = 1; /* we initialise this to something we will skip in the loop, as */ /* port_getn can return with nget unchanged, but no indication */ /* whether it was the original value or has been updated :/ */ port_events [0].portev_source = 0; EV_RELEASE_CB; EV_TS_SET (ts, timeout); res = port_getn (backend_fd, port_events, port_eventmax, &nget, &ts); EV_ACQUIRE_CB; /* port_getn may or may not set nget on error */ /* so we rely on port_events [0].portev_source not being updated */ if (res == -1 && errno != ETIME && errno != EINTR) ev_syserr ("(libev) port_getn (see http://bugs.opensolaris.org/view_bug.do?bug_id=6268715, try LIBEV_FLAGS=3 env variable)"); for (i = 0; i < nget; ++i) { if (port_events [i].portev_source == PORT_SOURCE_FD) { int fd = port_events [i].portev_object; fd_event ( EV_A_ fd, (port_events [i].portev_events & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0) | (port_events [i].portev_events & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0) ); fd_change (EV_A_ fd, EV__IOFDSET); } } if (expect_false (nget == port_eventmax)) { ev_free (port_events); port_eventmax = array_nextsize (sizeof (port_event_t), port_eventmax, port_eventmax + 1); port_events = (port_event_t *)ev_malloc (sizeof (port_event_t) * port_eventmax); } } int inline_size port_init (EV_P_ int flags) { /* Initialize the kernel queue */ if ((backend_fd = port_create ()) < 0) return 0; assert (("libev: PORT_SOURCE_FD must not be zero", PORT_SOURCE_FD)); fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */ /* if my reading of the opensolaris kernel sources are correct, then * opensolaris does something very stupid: it checks if the time has already * elapsed and doesn't round up if that is the case,m otherwise it DOES round * up. Since we can't know what the case is, we need to guess by using a * "large enough" timeout. Normally, 1e-9 would be correct. */ backend_mintime = 1e-3; /* needed to compensate for port_getn returning early */ backend_modify = port_modify; backend_poll = port_poll; port_eventmax = 64; /* initial number of events receivable per poll */ port_events = (port_event_t *)ev_malloc (sizeof (port_event_t) * port_eventmax); return EVBACKEND_PORT; } void inline_size port_destroy (EV_P) { ev_free (port_events); } void inline_size port_fork (EV_P) { close (backend_fd); while ((backend_fd = port_create ()) < 0) ev_syserr ("(libev) port"); fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* re-register interest in fds */ fd_rearm_all (EV_A); } EV-4.22/libev/ev.pod0000644000000000000000000065147412606503200012703 0ustar rootroot=encoding utf-8 =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); // break 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 WHAT TO READ WHEN IN A HURRY This manual tries to be very detailed, but unfortunately, this also makes it very long. If you just want to know the basics of libev, I suggest reading L, then the L above and look up the missing functions in L and the C and C sections in L. =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...). Epoll is truly the train wreck among event poll mechanisms, a frankenpoll, cobbled together in a hurry, no thought to design or interaction with others. Oh, the pain, will it ever stop... 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 (you might have to leak fd's on fork, but it's more sane than 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)). 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, 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). On the negative side, the interface is I - so bizarre that even sun itself gets it wrong in their code examples: The event polling function sometimes returns events to the caller even though an error occurred, but with no indication whether it has done so or not (yes, it's even documented that way) - deadly for edge-triggered interfaces where you absolutely have to know whether an event occurred or not because you have to re-arm the watcher. Fortunately libev seems to be able to work around these idiocies. 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, use whatever C returns, or simply do not specify a backend at all. =item C Not a backend at all, but a mask to select all backend bits from a C value, in case you want to mask out any backends from a flags value (e.g. when modifying the C environment variable). =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 its 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 you are allowed to start or stop watchers (except inside an C callback), 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. In addition, if you want to reuse a loop (via this function or C), you I have to ignore 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 normally, 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, throwing an exception etc.), doesn't count as "exit" - consider this as a hint to avoid such ungentleman-like behaviour unless it's really convenient, in which case it is fully supported. =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 bool 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, and 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. The return value is false if there are no more active watchers (which usually means "all jobs done" or "deadlock"), and true in all other cases (which usually means " you should call C again"). 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. This function is I exception-safe - you can break out of a C call by calling C in a callback, throwing a C++ exception and so on. This does not decrement the C value, nor will it clear any outstanding C breaks. 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 (this is for your understanding, not a guarantee that things will work exactly like this in future versions): - 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 break. 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 "break state" will be cleared on the next call to C. It is safe to call C from outside any C calls, too, in which case it will have no effect. =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); ev_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 (or libev) on file descriptors representing files, and expect it to become ready when their program doesn't block on disk accesses (which can take a long time on their own). However, this cannot ever work in the "expected" way - you get a readiness notification as soon as the kernel knows whether and how much data is there, and in the case of open files, that's always the case, so you always get a readiness notification instantly, and your read (or possibly write) will still block on the disk I/O. Another way to view it is that in the case of sockets, pipes, character devices and so on, there is another party (the sender) that delivers data on its own, but in the case of files, there is no such thing: the disk will not send data on its own, simply because it doesn't know what you wish to read - you would first have to request some data. Since files are typically not-so-well supported by advanced notification mechanism, libev tries hard to emulate POSIX behaviour with respect to files, even though you should not use it. The reason for this is convenience: sometimes you want to watch STDIN or STDOUT, which is usually a tty, often a pipe, but also sometimes files or special devices (for example, C on Linux works with F but not with F), and even though the file might better be served with asynchronous I/O instead of with non-blocking I/O, it is still useful when it "just works" instead of freezing. So avoid file descriptors pointing to files when you know it (e.g. use libeio), but use them when it is convenient, e.g. for STDIN/STDOUT, or when you rarely read from a file instead of from a socket, and want to reuse the same code path. =head3 The special problem of fork Some backends (epoll, kqueue) do not support C at all or exhibit useless behaviour. Libev fully supports fork, but needs to be told about it in the child if you want to continue to use it in the child. To support fork in your child processes, you have to call C after a fork in the child, enable C, or resort to C or C. =head3 The special problem of SIGPIPE While not really specific to libev, it is easy to forget about C: when writing to a pipe whose other end has been closed, your program gets sent a SIGPIPE, which, by default, aborts your program. For most programs this is sensible behaviour, for daemons, this is usually undesirable. So when you encounter spurious, unexplained daemon exits, make sure you 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 post-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 =over 4 =item ev_io_init (ev_io *, callback, int fd, int events) =item ev_io_set (ev_io *, int fd, int events) Configures an C watcher. The C is the file descriptor to receive events for and C is either C, C or C, to express the desire to receive the given events. =item int fd [read-only] The file descriptor being watched. =item int events [read-only] The events being watched. =back =head3 Examples Example: Call C when STDIN_FILENO has become, well readable, but only once. Since it is likely line-buffered, you could attempt to read a whole line in the callback. static void stdin_readable_cb (struct ev_loop *loop, ev_io *w, int revents) { ev_io_stop (loop, w); .. read from stdin here (or from w->fd) and handle any I/O errors } ... struct ev_loop *loop = ev_default_init (0); ev_io stdin_readable; ev_io_init (&stdin_readable, stdin_readable_cb, STDIN_FILENO, EV_READ); ev_io_start (loop, &stdin_readable); ev_run (loop, 0); =head2 C - relative and optionally repeating timeouts Timer watchers are simple relative timers that generate an event after a given time, and optionally repeating in regular intervals after that. The timers are based on real time, that is, if you register an event that times out after an hour and you reset your system clock to January last year, it will still time out after (roughly) one hour. "Roughly" because detecting time jumps is hard, and some inaccuracies are unavoidable (the monotonic clock option helps a lot here). The callback is guaranteed to be invoked only I its timeout has passed (not I, so on systems with very low-resolution clocks this might introduce a small delay, see "the special problem of being too early", below). If multiple timers become ready during the same loop iteration then the ones with earlier time-out values are invoked before ones of the same priority with later time-out values (but this is no longer true when a callback calls C recursively). =head3 Be smart about timeouts Many real-world problems involve some kind of timeout, usually for error recovery. A typical example is an HTTP request - if the other side hangs, you want to raise some error after a while. What follows are some ways to handle this problem, from obvious and inefficient to smart and efficient. In the following, a 60 second activity timeout is assumed - a timeout that gets reset to 60 seconds each time there is activity (e.g. each time some data or other life sign was received). =over 4 =item 1. Use a timer and stop, reinitialise and start it on activity. This is the most obvious, but not the most simple way: In the beginning, start the watcher: ev_timer_init (timer, callback, 60., 0.); ev_timer_start (loop, timer); Then, each time there is some activity, C it, initialise it and start it again: ev_timer_stop (loop, timer); ev_timer_set (timer, 60., 0.); ev_timer_start (loop, timer); This is relatively simple to implement, but means that each time there is some activity, libev will first have to remove the timer from its internal data structure and then add it again. Libev tries to be fast, but it's still not a constant-time operation. =item 2. Use a timer and re-start it with C inactivity. This is the easiest way, and involves using C instead of C. To implement this, configure an C with a C value of C<60> and then call C at start and each time you successfully read or write some data. If you go into an idle state where you do not expect data to travel on the socket, you can C the timer, and C will automatically restart it if need be. That means you can ignore both the C function and the C argument to C, and only ever use the C member and C. At start: ev_init (timer, callback); timer->repeat = 60.; ev_timer_again (loop, timer); Each time there is some activity: ev_timer_again (loop, timer); It is even possible to change the time-out on the fly, regardless of whether the watcher is active or not: timer->repeat = 30.; ev_timer_again (loop, timer); This is slightly more efficient then stopping/starting the timer each time you want to modify its timeout value, as libev does not have to completely remove and re-insert the timer from/into its internal data structure. It is, however, even simpler than the "obvious" way to do it. =item 3. Let the timer time out, but then re-arm it as required. This method is more tricky, but usually most efficient: Most timeouts are relatively long compared to the intervals between other activity - in our example, within 60 seconds, there are usually many I/O events with associated activity resets. In this case, it would be more efficient to leave the C alone, but remember the time of last activity, and check for a real timeout only within the callback: ev_tstamp timeout = 60.; ev_tstamp last_activity; // time of last activity ev_timer timer; static void callback (EV_P_ ev_timer *w, int revents) { // calculate when the timeout would happen ev_tstamp after = last_activity - ev_now (EV_A) + timeout; // if negative, it means we the timeout already occurred if (after < 0.) { // timeout occurred, take action } else { // callback was invoked, but there was some recent // activity. simply restart the timer to time out // after "after" seconds, which is the earliest time // the timeout can occur. ev_timer_set (w, after, 0.); ev_timer_start (EV_A_ w); } } To summarise the callback: first calculate in how many seconds the timeout will occur (by calculating the absolute time when it would occur, C, and subtracting the current time, C from that). If this value is negative, then we are already past the timeout, i.e. we timed out, and need to do whatever is needed in this case. Otherwise, we now the earliest time at which the timeout would trigger, and simply start the timer with this timeout value. In other words, each time the callback is invoked it will check whether the timeout occurred. If not, it will simply reschedule itself to check again at the earliest time it could time out. Rinse. Repeat. This scheme causes more callback invocations (about one every 60 seconds minus half the average time between activity), but virtually no calls to libev to change the timeout. To start the machinery, simply initialise the watcher and set C to the current time (meaning there was some activity just now), then call the callback, which will "do the right thing" and start the timer: last_activity = ev_now (EV_A); ev_init (&timer, callback); callback (EV_A_ &timer, 0); When there is some activity, simply store the current time in C, no libev calls at all: if (activity detected) last_activity = ev_now (EV_A); When your timeout value changes, then the timeout can be changed by simply providing a new value, stopping the timer and calling the callback, which will again do the right thing (for example, time out immediately :). timeout = new_value; ev_timer_stop (EV_A_ &timer); callback (EV_A_ &timer, 0); This technique is slightly more complex, but in most cases where the time-out is unlikely to be triggered, much more efficient. =item 4. Wee, just use a double-linked list for your timeouts. If there is not one request, but many thousands (millions...), all employing some kind of timeout with the same timeout value, then one can do even better: When starting the timeout, calculate the timeout value and put the timeout at the I of the list. Then use an C to fire when the timeout at the I of the list is expected to fire (for example, using the technique #3). When there is some activity, remove the timer from the list, recalculate the timeout, append it to the end of the list again, and make sure to update the C if it was taken from the beginning of the list. This way, one can manage an unlimited number of timeouts in O(1) time for starting, stopping and updating the timers, at the expense of a major complication, and having to use a constant timeout. The constant timeout ensures that the list stays sorted. =back So which method the best? Method #2 is a simple no-brain-required solution that is adequate in most situations. Method #3 requires a bit more thinking, but handles many cases better, and isn't very complicated either. In most case, choosing either one is fine, with #3 being better in typical situations. Method #1 is almost always a bad idea, and buys you nothing. Method #4 is rather complicated, but extremely efficient, something that really pays off after the first million or so of active timers, i.e. it's usually overkill :) =head3 The special problem of being too early If you ask a timer to call your callback after three seconds, then you expect it to be invoked after three seconds - but of course, this cannot be guaranteed to infinite precision. Less obviously, it cannot be guaranteed to any precision by libev - imagine somebody suspending the process with a STOP signal for a few hours for example. So, libev tries to invoke your callback as soon as possible I the delay has occurred, but cannot guarantee this. A less obvious failure mode is calling your callback too early: many event loops compare timestamps with a "elapsed delay >= requested delay", but this can cause your callback to be invoked much earlier than you would expect. To see why, imagine a system with a clock that only offers full second resolution (think windows if you can't come up with a broken enough OS yourself). If you schedule a one-second timer at the time 500.9, then the event loop will schedule your timeout to elapse at a system time of 500 (500.9 truncated to the resolution) + 1, or 501. If an event library looks at the timeout 0.1s later, it will see "501 >= 501" and invoke the callback 0.1s after it was started, even though a one-second delay was requested - this is being "too early", despite best intentions. This is the reason why libev will never invoke the callback if the elapsed delay equals the requested delay, but only when the elapsed delay is larger than the requested delay. In the example above, libev would only invoke the callback at system time 502, or 1.1s after the timer was started. So, while libev cannot guarantee that your callback will be invoked exactly when requested, it I and I guarantee that the requested delay has actually elapsed, or in other words, it always errs on the "too late" side of things. =head3 The special problem of time updates Establishing the current time is a costly operation (it usually takes at least one system call): EV therefore updates its idea of the current time only before and after C collects new events, which causes a growing difference between C and C when handling lots of events in one iteration. The relative timeouts are calculated relative to the C time. This is usually the right thing as this timestamp refers to the time of the event triggering whatever timeout you are modifying/starting. If you suspect event processing to be delayed and you I to base the timeout on the current time, use something like the following to adjust for it: ev_timer_set (&timer, after + (ev_time () - ev_now ()), 0.); If the event loop is suspended for a long time, you can also force an update of the time returned by C by calling C, although that will push the event time of all outstanding events further into the future. =head3 The special problem of unsynchronised clocks Modern systems have a variety of clocks - libev itself uses the normal "wall clock" clock and, if available, the monotonic clock (to avoid time jumps). Neither of these clocks is synchronised with each other or any other clock on the system, so C might return a considerably different time than C or C