mirror of
				https://github.com/wangyu-/udp2raw.git
				synced 2025-11-04 04:05:35 +08:00 
			
		
		
		
	add libev
This commit is contained in:
		
							
								
								
									
										31
									
								
								libev/CVS/Entries
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								libev/CVS/Entries
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
/Changes/1.315/Wed Jun 21 14:42:30 2017//
 | 
			
		||||
/LICENSE/1.11/Thu Jan 16 11:51:05 2014//
 | 
			
		||||
/Makefile.am/1.9/Wed Dec 21 18:16:08 2011//
 | 
			
		||||
/README/1.21/Fri Mar 30 17:43:55 2012//
 | 
			
		||||
/README.embed/1.29/Sat Nov 24 10:10:26 2007//
 | 
			
		||||
/Symbols.ev/1.14/Tue Jan 11 13:45:28 2011//
 | 
			
		||||
/Symbols.event/1.4/Tue May  8 15:52:13 2012//
 | 
			
		||||
/autogen.sh/1.3/Mon May 30 15:28:54 2011//
 | 
			
		||||
/configure.ac/1.42/Wed Dec 28 04:22:06 2016//
 | 
			
		||||
/ev++.h/1.63/Fri Dec  1 06:37:30 2017//
 | 
			
		||||
/ev.3/1.107/Wed Jun 21 14:42:30 2017//
 | 
			
		||||
/ev.c/1.481/Thu Jun  1 20:25:50 2017//
 | 
			
		||||
/ev.h/1.187/Wed Dec 28 04:22:06 2016//
 | 
			
		||||
/ev.pod/1.441/Thu Jul 13 10:46:52 2017//
 | 
			
		||||
/ev_epoll.c/1.72/Wed Jun 21 14:42:30 2017//
 | 
			
		||||
/ev_kqueue.c/1.56/Thu Feb 18 04:48:05 2016//
 | 
			
		||||
/ev_poll.c/1.40/Thu Feb 18 04:48:05 2016//
 | 
			
		||||
/ev_port.c/1.29/Thu Feb 18 04:48:05 2016//
 | 
			
		||||
/ev_select.c/1.56/Thu Feb 18 04:48:05 2016//
 | 
			
		||||
/ev_vars.h/1.58/Tue Sep  9 21:51:35 2014//
 | 
			
		||||
/ev_win32.c/1.18/Thu Nov 12 07:02:37 2015//
 | 
			
		||||
/ev_wrap.h/1.38/Tue Nov  6 20:56:50 2012//
 | 
			
		||||
/event.c/1.52/Mon Apr  2 23:14:41 2012//
 | 
			
		||||
/event.h/1.26/Mon Apr  2 23:15:27 2012//
 | 
			
		||||
/event_compat.h/1.8/Wed Feb 16 08:02:51 2011//
 | 
			
		||||
/import_libevent/1.29/Tue Apr 15 04:34:07 2008//
 | 
			
		||||
/libev.m4/1.16/Mon Oct 28 12:36:44 2013//
 | 
			
		||||
/update_ev_c/1.2/Wed Jan 18 12:13:14 2012//
 | 
			
		||||
/update_ev_wrap/1.6/Sun May  6 13:09:29 2012//
 | 
			
		||||
/update_symbols/1.1/Wed Dec 19 01:59:29 2007//
 | 
			
		||||
D
 | 
			
		||||
							
								
								
									
										1
									
								
								libev/CVS/Repository
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								libev/CVS/Repository
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
libev
 | 
			
		||||
							
								
								
									
										1
									
								
								libev/CVS/Root
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								libev/CVS/Root
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
:pserver:anonymous@cvs.schmorp.de/schmorpforge
 | 
			
		||||
							
								
								
									
										517
									
								
								libev/Changes
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										517
									
								
								libev/Changes
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,517 @@
 | 
			
		||||
Revision history for libev, a high-performance and full-featured event loop.
 | 
			
		||||
 | 
			
		||||
	- ANDROID => __ANDROID__ (reported by enh@google.com).
 | 
			
		||||
        - disable epoll_create1 on android because it has broken header files
 | 
			
		||||
          and google is unwilling to fix them (reported by enh@google.com).
 | 
			
		||||
 | 
			
		||||
4.24 Wed Dec 28 05:19:55 CET 2016
 | 
			
		||||
	- bump version to 4.24, as the release tarball inexplicably
 | 
			
		||||
          didn't have the right version in ev.h, even though the cvs-tagged
 | 
			
		||||
          version did have the right one (reported by Ales Teska).
 | 
			
		||||
 | 
			
		||||
4.23 Wed Nov 16 18:23:41 CET 2016
 | 
			
		||||
	- move some declarations at the beginning to help certain retarded
 | 
			
		||||
          microsoft compilers, even though their documentation claims
 | 
			
		||||
          otherwise (reported by Ruslan Osmanov).
 | 
			
		||||
 | 
			
		||||
4.22 Sun Dec 20 22:11:50 CET 2015
 | 
			
		||||
	- 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 <io.h> 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 <ev.h>.
 | 
			
		||||
	- 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.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										37
									
								
								libev/LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								libev/LICENSE
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
All files in libev are
 | 
			
		||||
Copyright (c)2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are
 | 
			
		||||
met:
 | 
			
		||||
 | 
			
		||||
    * Redistributions of source code must retain the above copyright
 | 
			
		||||
      notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
    * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
			
		||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
SPECIAL, 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 OTHERWISE) 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 package 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 package 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 in this and the other files of this package. If you do
 | 
			
		||||
not delete the provisions above, a recipient may use your version of this
 | 
			
		||||
file under either the BSD or the GPL.
 | 
			
		||||
							
								
								
									
										20
									
								
								libev/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								libev/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
AUTOMAKE_OPTIONS = foreign
 | 
			
		||||
 | 
			
		||||
VERSION_INFO = 4:0:0
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = LICENSE Changes libev.m4 autogen.sh \
 | 
			
		||||
	     ev_vars.h ev_wrap.h \
 | 
			
		||||
	     ev_epoll.c ev_select.c ev_poll.c ev_kqueue.c ev_port.c ev_win32.c \
 | 
			
		||||
	     ev.3 ev.pod Symbols.ev Symbols.event
 | 
			
		||||
 | 
			
		||||
man_MANS = ev.3
 | 
			
		||||
 | 
			
		||||
include_HEADERS = ev.h ev++.h event.h
 | 
			
		||||
 | 
			
		||||
lib_LTLIBRARIES = libev.la
 | 
			
		||||
 | 
			
		||||
libev_la_SOURCES = ev.c event.c
 | 
			
		||||
libev_la_LDFLAGS = -version-info $(VERSION_INFO)
 | 
			
		||||
 | 
			
		||||
ev.3: ev.pod
 | 
			
		||||
	pod2man -n LIBEV -r "libev-$(VERSION)" -c "libev - high performance full featured event loop" -s3 <$< >$@
 | 
			
		||||
							
								
								
									
										58
									
								
								libev/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								libev/README
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
libev is a high-performance event loop/event model with lots of features.
 | 
			
		||||
(see benchmark at http://libev.schmorp.de/bench.html)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ABOUT
 | 
			
		||||
 | 
			
		||||
   Homepage: http://software.schmorp.de/pkg/libev
 | 
			
		||||
   Mailinglist: libev@lists.schmorp.de
 | 
			
		||||
                http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
 | 
			
		||||
   Library Documentation: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod
 | 
			
		||||
 | 
			
		||||
   Libev is modelled (very losely) after libevent and the Event perl
 | 
			
		||||
   module, but is faster, scales better and is more correct, and also more
 | 
			
		||||
   featureful. And also smaller. Yay.
 | 
			
		||||
 | 
			
		||||
   Some of the specialties of libev not commonly found elsewhere are:
 | 
			
		||||
   
 | 
			
		||||
   - extensive and detailed, readable documentation (not doxygen garbage).
 | 
			
		||||
   - fully supports fork, can detect fork in various ways and automatically
 | 
			
		||||
     re-arms kernel mechanisms that do not support fork.
 | 
			
		||||
   - highly optimised select, poll, epoll, kqueue and event ports backends.
 | 
			
		||||
   - filesystem object (path) watching (with optional linux inotify support).
 | 
			
		||||
   - wallclock-based times (using absolute time, cron-like).
 | 
			
		||||
   - relative timers/timeouts (handle time jumps).
 | 
			
		||||
   - fast intra-thread communication between multiple
 | 
			
		||||
     event loops (with optional fast linux eventfd backend).
 | 
			
		||||
   - extremely easy to embed (fully documented, no dependencies,
 | 
			
		||||
     autoconf supported but optional).
 | 
			
		||||
   - very small codebase, no bloated library, simple code.
 | 
			
		||||
   - fully extensible by being able to plug into the event loop,
 | 
			
		||||
     integrate other event loops, integrate other event loop users.
 | 
			
		||||
   - very little memory use (small watchers, small event loop data).
 | 
			
		||||
   - optional C++ interface allowing method and function callbacks
 | 
			
		||||
     at no extra memory or runtime overhead.
 | 
			
		||||
   - optional Perl interface with similar characteristics (capable
 | 
			
		||||
     of running Glib/Gtk2 on libev).
 | 
			
		||||
   - support for other languages (multiple C++ interfaces, D, Ruby,
 | 
			
		||||
     Python) available from third-parties.
 | 
			
		||||
 | 
			
		||||
   Examples of programs that embed libev: the EV perl module, node.js,
 | 
			
		||||
   auditd, rxvt-unicode, gvpe (GNU Virtual Private Ethernet), the
 | 
			
		||||
   Deliantra MMORPG server (http://www.deliantra.net/), Rubinius (a
 | 
			
		||||
   next-generation Ruby VM), the Ebb web server, the Rev event toolkit.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONTRIBUTORS
 | 
			
		||||
 | 
			
		||||
   libev was written and designed by Marc Lehmann and Emanuele Giaquinta.
 | 
			
		||||
 | 
			
		||||
   The following people sent in patches or made other noteworthy
 | 
			
		||||
   contributions to the design (for minor patches, see the Changes
 | 
			
		||||
   file. If I forgot to include you, please shout at me, it was an
 | 
			
		||||
   accident):
 | 
			
		||||
 | 
			
		||||
   W.C.A. Wijngaards
 | 
			
		||||
   Christopher Layne
 | 
			
		||||
   Chris Brody
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								libev/README.embed
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								libev/README.embed
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
This file is now included in the main libev documentation, see
 | 
			
		||||
 | 
			
		||||
   http://cvs.schmorp.de/libev/ev.html
 | 
			
		||||
							
								
								
									
										73
									
								
								libev/Symbols.ev
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								libev/Symbols.ev
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
ev_async_send
 | 
			
		||||
ev_async_start
 | 
			
		||||
ev_async_stop
 | 
			
		||||
ev_backend
 | 
			
		||||
ev_break
 | 
			
		||||
ev_check_start
 | 
			
		||||
ev_check_stop
 | 
			
		||||
ev_child_start
 | 
			
		||||
ev_child_stop
 | 
			
		||||
ev_cleanup_start
 | 
			
		||||
ev_cleanup_stop
 | 
			
		||||
ev_clear_pending
 | 
			
		||||
ev_default_loop
 | 
			
		||||
ev_default_loop_ptr
 | 
			
		||||
ev_depth
 | 
			
		||||
ev_embed_start
 | 
			
		||||
ev_embed_stop
 | 
			
		||||
ev_embed_sweep
 | 
			
		||||
ev_embeddable_backends
 | 
			
		||||
ev_feed_event
 | 
			
		||||
ev_feed_fd_event
 | 
			
		||||
ev_feed_signal
 | 
			
		||||
ev_feed_signal_event
 | 
			
		||||
ev_fork_start
 | 
			
		||||
ev_fork_stop
 | 
			
		||||
ev_idle_start
 | 
			
		||||
ev_idle_stop
 | 
			
		||||
ev_invoke
 | 
			
		||||
ev_invoke_pending
 | 
			
		||||
ev_io_start
 | 
			
		||||
ev_io_stop
 | 
			
		||||
ev_iteration
 | 
			
		||||
ev_loop_destroy
 | 
			
		||||
ev_loop_fork
 | 
			
		||||
ev_loop_new
 | 
			
		||||
ev_now
 | 
			
		||||
ev_now_update
 | 
			
		||||
ev_once
 | 
			
		||||
ev_pending_count
 | 
			
		||||
ev_periodic_again
 | 
			
		||||
ev_periodic_start
 | 
			
		||||
ev_periodic_stop
 | 
			
		||||
ev_prepare_start
 | 
			
		||||
ev_prepare_stop
 | 
			
		||||
ev_recommended_backends
 | 
			
		||||
ev_ref
 | 
			
		||||
ev_resume
 | 
			
		||||
ev_run
 | 
			
		||||
ev_set_allocator
 | 
			
		||||
ev_set_invoke_pending_cb
 | 
			
		||||
ev_set_io_collect_interval
 | 
			
		||||
ev_set_loop_release_cb
 | 
			
		||||
ev_set_syserr_cb
 | 
			
		||||
ev_set_timeout_collect_interval
 | 
			
		||||
ev_set_userdata
 | 
			
		||||
ev_signal_start
 | 
			
		||||
ev_signal_stop
 | 
			
		||||
ev_sleep
 | 
			
		||||
ev_stat_start
 | 
			
		||||
ev_stat_stat
 | 
			
		||||
ev_stat_stop
 | 
			
		||||
ev_supported_backends
 | 
			
		||||
ev_suspend
 | 
			
		||||
ev_time
 | 
			
		||||
ev_timer_again
 | 
			
		||||
ev_timer_remaining
 | 
			
		||||
ev_timer_start
 | 
			
		||||
ev_timer_stop
 | 
			
		||||
ev_unref
 | 
			
		||||
ev_userdata
 | 
			
		||||
ev_verify
 | 
			
		||||
ev_version_major
 | 
			
		||||
ev_version_minor
 | 
			
		||||
							
								
								
									
										24
									
								
								libev/Symbols.event
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								libev/Symbols.event
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
event_active
 | 
			
		||||
event_add
 | 
			
		||||
event_base_dispatch
 | 
			
		||||
event_base_free
 | 
			
		||||
event_base_get_method
 | 
			
		||||
event_base_loop
 | 
			
		||||
event_base_loopexit
 | 
			
		||||
event_base_new
 | 
			
		||||
event_base_once
 | 
			
		||||
event_base_priority_init
 | 
			
		||||
event_base_set
 | 
			
		||||
event_del
 | 
			
		||||
event_dispatch
 | 
			
		||||
event_get_callback
 | 
			
		||||
event_get_method
 | 
			
		||||
event_get_version
 | 
			
		||||
event_init
 | 
			
		||||
event_loop
 | 
			
		||||
event_loopexit
 | 
			
		||||
event_once
 | 
			
		||||
event_pending
 | 
			
		||||
event_priority_init
 | 
			
		||||
event_priority_set
 | 
			
		||||
event_set
 | 
			
		||||
							
								
								
									
										3
									
								
								libev/autogen.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								libev/autogen.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
autoreconf --install --symlink --force
 | 
			
		||||
							
								
								
									
										27
									
								
								libev/configure.ac
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								libev/configure.ac
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
AC_INIT
 | 
			
		||||
 | 
			
		||||
orig_CFLAGS="$CFLAGS"
 | 
			
		||||
 | 
			
		||||
AC_CONFIG_SRCDIR([ev_epoll.c])
 | 
			
		||||
 | 
			
		||||
dnl also update ev.h!
 | 
			
		||||
AM_INIT_AUTOMAKE(libev,4.24)
 | 
			
		||||
AC_CONFIG_HEADERS([config.h])
 | 
			
		||||
AM_MAINTAINER_MODE
 | 
			
		||||
 | 
			
		||||
AC_PROG_CC
 | 
			
		||||
 | 
			
		||||
dnl Supply default CFLAGS, if not specified
 | 
			
		||||
if test -z "$orig_CFLAGS"; then
 | 
			
		||||
  if test x$GCC = xyes; then
 | 
			
		||||
    CFLAGS="-g -O3"
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
AC_PROG_INSTALL
 | 
			
		||||
AC_PROG_LIBTOOL
 | 
			
		||||
 | 
			
		||||
m4_include([libev.m4])
 | 
			
		||||
 | 
			
		||||
AC_CONFIG_FILES([Makefile])
 | 
			
		||||
AC_OUTPUT
 | 
			
		||||
							
								
								
									
										816
									
								
								libev/ev++.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										816
									
								
								libev/ev++.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,816 @@
 | 
			
		||||
/*
 | 
			
		||||
 * libev simple C++ wrapper classes
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2007,2008,2010 Marc Alexander Lehmann <libev@schmorp.de>
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef EVPP_H__
 | 
			
		||||
#define EVPP_H__
 | 
			
		||||
 | 
			
		||||
#ifdef EV_H
 | 
			
		||||
# include EV_H
 | 
			
		||||
#else
 | 
			
		||||
# include "ev.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EV_USE_STDEXCEPT
 | 
			
		||||
# define EV_USE_STDEXCEPT 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_USE_STDEXCEPT
 | 
			
		||||
# include <stdexcept>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace ev {
 | 
			
		||||
 | 
			
		||||
  typedef ev_tstamp tstamp;
 | 
			
		||||
 | 
			
		||||
  enum {
 | 
			
		||||
    UNDEF    = EV_UNDEF,
 | 
			
		||||
    NONE     = EV_NONE,
 | 
			
		||||
    READ     = EV_READ,
 | 
			
		||||
    WRITE    = EV_WRITE,
 | 
			
		||||
#if EV_COMPAT3
 | 
			
		||||
    TIMEOUT  = EV_TIMEOUT,
 | 
			
		||||
#endif
 | 
			
		||||
    TIMER    = EV_TIMER,
 | 
			
		||||
    PERIODIC = EV_PERIODIC,
 | 
			
		||||
    SIGNAL   = EV_SIGNAL,
 | 
			
		||||
    CHILD    = EV_CHILD,
 | 
			
		||||
    STAT     = EV_STAT,
 | 
			
		||||
    IDLE     = EV_IDLE,
 | 
			
		||||
    CHECK    = EV_CHECK,
 | 
			
		||||
    PREPARE  = EV_PREPARE,
 | 
			
		||||
    FORK     = EV_FORK,
 | 
			
		||||
    ASYNC    = EV_ASYNC,
 | 
			
		||||
    EMBED    = EV_EMBED,
 | 
			
		||||
#   undef ERROR // some systems stupidly #define ERROR
 | 
			
		||||
    ERROR    = EV_ERROR
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  enum
 | 
			
		||||
  {
 | 
			
		||||
    AUTO      = EVFLAG_AUTO,
 | 
			
		||||
    NOENV     = EVFLAG_NOENV,
 | 
			
		||||
    FORKCHECK = EVFLAG_FORKCHECK,
 | 
			
		||||
 | 
			
		||||
    SELECT    = EVBACKEND_SELECT,
 | 
			
		||||
    POLL      = EVBACKEND_POLL,
 | 
			
		||||
    EPOLL     = EVBACKEND_EPOLL,
 | 
			
		||||
    KQUEUE    = EVBACKEND_KQUEUE,
 | 
			
		||||
    DEVPOLL   = EVBACKEND_DEVPOLL,
 | 
			
		||||
    PORT      = EVBACKEND_PORT
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  enum
 | 
			
		||||
  {
 | 
			
		||||
#if EV_COMPAT3
 | 
			
		||||
    NONBLOCK = EVLOOP_NONBLOCK,
 | 
			
		||||
    ONESHOT  = EVLOOP_ONESHOT,
 | 
			
		||||
#endif
 | 
			
		||||
    NOWAIT   = EVRUN_NOWAIT,
 | 
			
		||||
    ONCE     = EVRUN_ONCE
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  enum how_t
 | 
			
		||||
  {
 | 
			
		||||
    ONE = EVBREAK_ONE,
 | 
			
		||||
    ALL = EVBREAK_ALL
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  struct bad_loop
 | 
			
		||||
#if EV_USE_STDEXCEPT
 | 
			
		||||
  : std::runtime_error
 | 
			
		||||
#endif
 | 
			
		||||
  {
 | 
			
		||||
#if EV_USE_STDEXCEPT
 | 
			
		||||
    bad_loop ()
 | 
			
		||||
    : std::runtime_error ("libev event loop cannot be initialized, bad value of LIBEV_FLAGS?")
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
#ifdef EV_AX
 | 
			
		||||
#  undef EV_AX
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EV_AX_
 | 
			
		||||
#  undef EV_AX_
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_MULTIPLICITY
 | 
			
		||||
#  define EV_AX  raw_loop
 | 
			
		||||
#  define EV_AX_ raw_loop,
 | 
			
		||||
#else
 | 
			
		||||
#  define EV_AX
 | 
			
		||||
#  define EV_AX_
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  struct loop_ref
 | 
			
		||||
  {
 | 
			
		||||
    loop_ref (EV_P) throw ()
 | 
			
		||||
#if EV_MULTIPLICITY
 | 
			
		||||
    : EV_AX (EV_A)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool operator == (const loop_ref &other) const throw ()
 | 
			
		||||
    {
 | 
			
		||||
#if EV_MULTIPLICITY
 | 
			
		||||
      return EV_AX == other.EV_AX;
 | 
			
		||||
#else
 | 
			
		||||
      return true;
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool operator != (const loop_ref &other) const throw ()
 | 
			
		||||
    {
 | 
			
		||||
#if EV_MULTIPLICITY
 | 
			
		||||
      return ! (*this == other);
 | 
			
		||||
#else
 | 
			
		||||
      return false;
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if EV_MULTIPLICITY
 | 
			
		||||
    bool operator == (const EV_P) const throw ()
 | 
			
		||||
    {
 | 
			
		||||
      return this->EV_AX == EV_A;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool operator != (const EV_P) const throw ()
 | 
			
		||||
    {
 | 
			
		||||
      return ! (*this == EV_A);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator struct ev_loop * () const throw ()
 | 
			
		||||
    {
 | 
			
		||||
      return EV_AX;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator const struct ev_loop * () const throw ()
 | 
			
		||||
    {
 | 
			
		||||
      return EV_AX;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool is_default () const throw ()
 | 
			
		||||
    {
 | 
			
		||||
      return EV_AX == ev_default_loop (0);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_COMPAT3
 | 
			
		||||
    void loop (int flags = 0)
 | 
			
		||||
    {
 | 
			
		||||
      ev_run (EV_AX_ flags);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void unloop (how_t how = ONE) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      ev_break (EV_AX_ how);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    void run (int flags = 0)
 | 
			
		||||
    {
 | 
			
		||||
      ev_run (EV_AX_ flags);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void break_loop (how_t how = ONE) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      ev_break (EV_AX_ how);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void post_fork () throw ()
 | 
			
		||||
    {
 | 
			
		||||
      ev_loop_fork (EV_AX);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsigned int backend () const throw ()
 | 
			
		||||
    {
 | 
			
		||||
      return ev_backend (EV_AX);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    tstamp now () const throw ()
 | 
			
		||||
    {
 | 
			
		||||
      return ev_now (EV_AX);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ref () throw ()
 | 
			
		||||
    {
 | 
			
		||||
      ev_ref (EV_AX);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void unref () throw ()
 | 
			
		||||
    {
 | 
			
		||||
      ev_unref (EV_AX);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if EV_FEATURE_API
 | 
			
		||||
    unsigned int iteration () const throw ()
 | 
			
		||||
    {
 | 
			
		||||
      return ev_iteration (EV_AX);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsigned int depth () const throw ()
 | 
			
		||||
    {
 | 
			
		||||
      return ev_depth (EV_AX);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void set_io_collect_interval (tstamp interval) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      ev_set_io_collect_interval (EV_AX_ interval);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void set_timeout_collect_interval (tstamp interval) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      ev_set_timeout_collect_interval (EV_AX_ interval);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // function callback
 | 
			
		||||
    void once (int fd, int events, tstamp timeout, void (*cb)(int, void *), void *arg = 0) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      ev_once (EV_AX_ fd, events, timeout, cb, arg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // method callback
 | 
			
		||||
    template<class K, void (K::*method)(int)>
 | 
			
		||||
    void once (int fd, int events, tstamp timeout, K *object) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      once (fd, events, timeout, method_thunk<K, method>, object);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // default method == operator ()
 | 
			
		||||
    template<class K>
 | 
			
		||||
    void once (int fd, int events, tstamp timeout, K *object) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      once (fd, events, timeout, method_thunk<K, &K::operator ()>, object);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class K, void (K::*method)(int)>
 | 
			
		||||
    static void method_thunk (int revents, void *arg)
 | 
			
		||||
    {
 | 
			
		||||
      (static_cast<K *>(arg)->*method)
 | 
			
		||||
        (revents);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // no-argument method callback
 | 
			
		||||
    template<class K, void (K::*method)()>
 | 
			
		||||
    void once (int fd, int events, tstamp timeout, K *object) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      once (fd, events, timeout, method_noargs_thunk<K, method>, object);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class K, void (K::*method)()>
 | 
			
		||||
    static void method_noargs_thunk (int revents, void *arg)
 | 
			
		||||
    {
 | 
			
		||||
      (static_cast<K *>(arg)->*method)
 | 
			
		||||
        ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // simpler function callback
 | 
			
		||||
    template<void (*cb)(int)>
 | 
			
		||||
    void once (int fd, int events, tstamp timeout) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      once (fd, events, timeout, simpler_func_thunk<cb>);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<void (*cb)(int)>
 | 
			
		||||
    static void simpler_func_thunk (int revents, void *arg)
 | 
			
		||||
    {
 | 
			
		||||
      (*cb)
 | 
			
		||||
        (revents);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // simplest function callback
 | 
			
		||||
    template<void (*cb)()>
 | 
			
		||||
    void once (int fd, int events, tstamp timeout) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      once (fd, events, timeout, simplest_func_thunk<cb>);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<void (*cb)()>
 | 
			
		||||
    static void simplest_func_thunk (int revents, void *arg)
 | 
			
		||||
    {
 | 
			
		||||
      (*cb)
 | 
			
		||||
        ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void feed_fd_event (int fd, int revents) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      ev_feed_fd_event (EV_AX_ fd, revents);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void feed_signal_event (int signum) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      ev_feed_signal_event (EV_AX_ signum);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if EV_MULTIPLICITY
 | 
			
		||||
    struct ev_loop* EV_AX;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
#if EV_MULTIPLICITY
 | 
			
		||||
  struct dynamic_loop : loop_ref
 | 
			
		||||
  {
 | 
			
		||||
 | 
			
		||||
    dynamic_loop (unsigned int flags = AUTO) throw (bad_loop)
 | 
			
		||||
    : loop_ref (ev_loop_new (flags))
 | 
			
		||||
    {
 | 
			
		||||
      if (!EV_AX)
 | 
			
		||||
        throw bad_loop ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~dynamic_loop () throw ()
 | 
			
		||||
    {
 | 
			
		||||
      ev_loop_destroy (EV_AX);
 | 
			
		||||
      EV_AX = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
 | 
			
		||||
    dynamic_loop (const dynamic_loop &);
 | 
			
		||||
 | 
			
		||||
    dynamic_loop & operator= (const dynamic_loop &);
 | 
			
		||||
 | 
			
		||||
  };
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  struct default_loop : loop_ref
 | 
			
		||||
  {
 | 
			
		||||
    default_loop (unsigned int flags = AUTO) throw (bad_loop)
 | 
			
		||||
#if EV_MULTIPLICITY
 | 
			
		||||
    : loop_ref (ev_default_loop (flags))
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
      if (
 | 
			
		||||
#if EV_MULTIPLICITY
 | 
			
		||||
          !EV_AX
 | 
			
		||||
#else
 | 
			
		||||
          !ev_default_loop (flags)
 | 
			
		||||
#endif
 | 
			
		||||
      )
 | 
			
		||||
        throw bad_loop ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    default_loop (const default_loop &);
 | 
			
		||||
    default_loop &operator = (const default_loop &);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  inline loop_ref get_default_loop () throw ()
 | 
			
		||||
  {
 | 
			
		||||
#if EV_MULTIPLICITY
 | 
			
		||||
    return ev_default_loop (0);
 | 
			
		||||
#else
 | 
			
		||||
    return loop_ref ();
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#undef EV_AX
 | 
			
		||||
#undef EV_AX_
 | 
			
		||||
 | 
			
		||||
#undef EV_PX
 | 
			
		||||
#undef EV_PX_
 | 
			
		||||
#if EV_MULTIPLICITY
 | 
			
		||||
#  define EV_PX  loop_ref EV_A
 | 
			
		||||
#  define EV_PX_ loop_ref EV_A_
 | 
			
		||||
#else
 | 
			
		||||
#  define EV_PX
 | 
			
		||||
#  define EV_PX_
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  template<class ev_watcher, class watcher>
 | 
			
		||||
  struct base : ev_watcher
 | 
			
		||||
  {
 | 
			
		||||
    #if EV_MULTIPLICITY
 | 
			
		||||
      EV_PX;
 | 
			
		||||
 | 
			
		||||
      // loop set
 | 
			
		||||
      void set (EV_P) throw ()
 | 
			
		||||
      {
 | 
			
		||||
        this->EV_A = EV_A;
 | 
			
		||||
      }
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    base (EV_PX) throw ()
 | 
			
		||||
    #if EV_MULTIPLICITY
 | 
			
		||||
      : EV_A (EV_A)
 | 
			
		||||
    #endif
 | 
			
		||||
    {
 | 
			
		||||
      ev_init (this, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void set_ (const void *data, void (*cb)(EV_P_ ev_watcher *w, int revents)) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      this->data = (void *)data;
 | 
			
		||||
      ev_set_cb (static_cast<ev_watcher *>(this), cb);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // function callback
 | 
			
		||||
    template<void (*function)(watcher &w, int)>
 | 
			
		||||
    void set (void *data = 0) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      set_ (data, function_thunk<function>);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<void (*function)(watcher &w, int)>
 | 
			
		||||
    static void function_thunk (EV_P_ ev_watcher *w, int revents)
 | 
			
		||||
    {
 | 
			
		||||
      function
 | 
			
		||||
        (*static_cast<watcher *>(w), revents);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // method callback
 | 
			
		||||
    template<class K, void (K::*method)(watcher &w, int)>
 | 
			
		||||
    void set (K *object) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      set_ (object, method_thunk<K, method>);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // default method == operator ()
 | 
			
		||||
    template<class K>
 | 
			
		||||
    void set (K *object) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      set_ (object, method_thunk<K, &K::operator ()>);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class K, void (K::*method)(watcher &w, int)>
 | 
			
		||||
    static void method_thunk (EV_P_ ev_watcher *w, int revents)
 | 
			
		||||
    {
 | 
			
		||||
      (static_cast<K *>(w->data)->*method)
 | 
			
		||||
        (*static_cast<watcher *>(w), revents);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // no-argument callback
 | 
			
		||||
    template<class K, void (K::*method)()>
 | 
			
		||||
    void set (K *object) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      set_ (object, method_noargs_thunk<K, method>);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class K, void (K::*method)()>
 | 
			
		||||
    static void method_noargs_thunk (EV_P_ ev_watcher *w, int revents)
 | 
			
		||||
    {
 | 
			
		||||
      (static_cast<K *>(w->data)->*method)
 | 
			
		||||
        ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void operator ()(int events = EV_UNDEF)
 | 
			
		||||
    {
 | 
			
		||||
      return
 | 
			
		||||
        ev_cb (static_cast<ev_watcher *>(this))
 | 
			
		||||
          (static_cast<ev_watcher *>(this), events);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool is_active () const throw ()
 | 
			
		||||
    {
 | 
			
		||||
      return ev_is_active (static_cast<const ev_watcher *>(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool is_pending () const throw ()
 | 
			
		||||
    {
 | 
			
		||||
      return ev_is_pending (static_cast<const ev_watcher *>(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void feed_event (int revents) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      ev_feed_event (EV_A_ static_cast<ev_watcher *>(this), revents);
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  inline tstamp now (EV_P) throw ()
 | 
			
		||||
  {
 | 
			
		||||
    return ev_now (EV_A);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  inline void delay (tstamp interval) throw ()
 | 
			
		||||
  {
 | 
			
		||||
    ev_sleep (interval);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  inline int version_major () throw ()
 | 
			
		||||
  {
 | 
			
		||||
    return ev_version_major ();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  inline int version_minor () throw ()
 | 
			
		||||
  {
 | 
			
		||||
    return ev_version_minor ();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  inline unsigned int supported_backends () throw ()
 | 
			
		||||
  {
 | 
			
		||||
    return ev_supported_backends ();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  inline unsigned int recommended_backends () throw ()
 | 
			
		||||
  {
 | 
			
		||||
    return ev_recommended_backends ();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  inline unsigned int embeddable_backends () throw ()
 | 
			
		||||
  {
 | 
			
		||||
    return ev_embeddable_backends ();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  inline void set_allocator (void *(*cb)(void *ptr, long size) throw ()) throw ()
 | 
			
		||||
  {
 | 
			
		||||
    ev_set_allocator (cb);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  inline void set_syserr_cb (void (*cb)(const char *msg) throw ()) throw ()
 | 
			
		||||
  {
 | 
			
		||||
    ev_set_syserr_cb (cb);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  #if EV_MULTIPLICITY
 | 
			
		||||
    #define EV_CONSTRUCT(cppstem,cstem)	                                                \
 | 
			
		||||
      (EV_PX = get_default_loop ()) throw ()                                            \
 | 
			
		||||
        : base<ev_ ## cstem, cppstem> (EV_A)                                            \
 | 
			
		||||
      {                                                                                 \
 | 
			
		||||
      }
 | 
			
		||||
  #else
 | 
			
		||||
    #define EV_CONSTRUCT(cppstem,cstem)                                                 \
 | 
			
		||||
      () throw ()                                                                       \
 | 
			
		||||
      {                                                                                 \
 | 
			
		||||
      }
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  /* using a template here would require quite a few more lines,
 | 
			
		||||
   * so a macro solution was chosen */
 | 
			
		||||
  #define EV_BEGIN_WATCHER(cppstem,cstem)	                                        \
 | 
			
		||||
                                                                                        \
 | 
			
		||||
  struct cppstem : base<ev_ ## cstem, cppstem>                                          \
 | 
			
		||||
  {                                                                                     \
 | 
			
		||||
    void start () throw ()                                                              \
 | 
			
		||||
    {                                                                                   \
 | 
			
		||||
      ev_ ## cstem ## _start (EV_A_ static_cast<ev_ ## cstem *>(this));                 \
 | 
			
		||||
    }                                                                                   \
 | 
			
		||||
                                                                                        \
 | 
			
		||||
    void stop () throw ()                                                               \
 | 
			
		||||
    {                                                                                   \
 | 
			
		||||
      ev_ ## cstem ## _stop (EV_A_ static_cast<ev_ ## cstem *>(this));                  \
 | 
			
		||||
    }                                                                                   \
 | 
			
		||||
                                                                                        \
 | 
			
		||||
    cppstem EV_CONSTRUCT(cppstem,cstem)                                                 \
 | 
			
		||||
                                                                                        \
 | 
			
		||||
    ~cppstem () throw ()                                                                \
 | 
			
		||||
    {                                                                                   \
 | 
			
		||||
      stop ();                                                                          \
 | 
			
		||||
    }                                                                                   \
 | 
			
		||||
                                                                                        \
 | 
			
		||||
    using base<ev_ ## cstem, cppstem>::set;                                             \
 | 
			
		||||
                                                                                        \
 | 
			
		||||
  private:                                                                              \
 | 
			
		||||
                                                                                        \
 | 
			
		||||
    cppstem (const cppstem &o);                                                         \
 | 
			
		||||
                                                                                        \
 | 
			
		||||
    cppstem &operator =(const cppstem &o);                                              \
 | 
			
		||||
                                                                                        \
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
  #define EV_END_WATCHER(cppstem,cstem)	                                                \
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  EV_BEGIN_WATCHER (io, io)
 | 
			
		||||
    void set (int fd, int events) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      int active = is_active ();
 | 
			
		||||
      if (active) stop ();
 | 
			
		||||
      ev_io_set (static_cast<ev_io *>(this), fd, events);
 | 
			
		||||
      if (active) start ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void set (int events) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      int active = is_active ();
 | 
			
		||||
      if (active) stop ();
 | 
			
		||||
      ev_io_set (static_cast<ev_io *>(this), fd, events);
 | 
			
		||||
      if (active) start ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void start (int fd, int events) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      set (fd, events);
 | 
			
		||||
      start ();
 | 
			
		||||
    }
 | 
			
		||||
  EV_END_WATCHER (io, io)
 | 
			
		||||
 | 
			
		||||
  EV_BEGIN_WATCHER (timer, timer)
 | 
			
		||||
    void set (ev_tstamp after, ev_tstamp repeat = 0.) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      int active = is_active ();
 | 
			
		||||
      if (active) stop ();
 | 
			
		||||
      ev_timer_set (static_cast<ev_timer *>(this), after, repeat);
 | 
			
		||||
      if (active) start ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void start (ev_tstamp after, ev_tstamp repeat = 0.) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      set (after, repeat);
 | 
			
		||||
      start ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void again () throw ()
 | 
			
		||||
    {
 | 
			
		||||
      ev_timer_again (EV_A_ static_cast<ev_timer *>(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ev_tstamp remaining ()
 | 
			
		||||
    {
 | 
			
		||||
      return ev_timer_remaining (EV_A_ static_cast<ev_timer *>(this));
 | 
			
		||||
    }
 | 
			
		||||
  EV_END_WATCHER (timer, timer)
 | 
			
		||||
 | 
			
		||||
  #if EV_PERIODIC_ENABLE
 | 
			
		||||
  EV_BEGIN_WATCHER (periodic, periodic)
 | 
			
		||||
    void set (ev_tstamp at, ev_tstamp interval = 0.) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      int active = is_active ();
 | 
			
		||||
      if (active) stop ();
 | 
			
		||||
      ev_periodic_set (static_cast<ev_periodic *>(this), at, interval, 0);
 | 
			
		||||
      if (active) start ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void start (ev_tstamp at, ev_tstamp interval = 0.) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      set (at, interval);
 | 
			
		||||
      start ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void again () throw ()
 | 
			
		||||
    {
 | 
			
		||||
      ev_periodic_again (EV_A_ static_cast<ev_periodic *>(this));
 | 
			
		||||
    }
 | 
			
		||||
  EV_END_WATCHER (periodic, periodic)
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #if EV_SIGNAL_ENABLE
 | 
			
		||||
  EV_BEGIN_WATCHER (sig, signal)
 | 
			
		||||
    void set (int signum) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      int active = is_active ();
 | 
			
		||||
      if (active) stop ();
 | 
			
		||||
      ev_signal_set (static_cast<ev_signal *>(this), signum);
 | 
			
		||||
      if (active) start ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void start (int signum) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      set (signum);
 | 
			
		||||
      start ();
 | 
			
		||||
    }
 | 
			
		||||
  EV_END_WATCHER (sig, signal)
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #if EV_CHILD_ENABLE
 | 
			
		||||
  EV_BEGIN_WATCHER (child, child)
 | 
			
		||||
    void set (int pid, int trace = 0) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      int active = is_active ();
 | 
			
		||||
      if (active) stop ();
 | 
			
		||||
      ev_child_set (static_cast<ev_child *>(this), pid, trace);
 | 
			
		||||
      if (active) start ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void start (int pid, int trace = 0) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      set (pid, trace);
 | 
			
		||||
      start ();
 | 
			
		||||
    }
 | 
			
		||||
  EV_END_WATCHER (child, child)
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #if EV_STAT_ENABLE
 | 
			
		||||
  EV_BEGIN_WATCHER (stat, stat)
 | 
			
		||||
    void set (const char *path, ev_tstamp interval = 0.) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      int active = is_active ();
 | 
			
		||||
      if (active) stop ();
 | 
			
		||||
      ev_stat_set (static_cast<ev_stat *>(this), path, interval);
 | 
			
		||||
      if (active) start ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void start (const char *path, ev_tstamp interval = 0.) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      stop ();
 | 
			
		||||
      set (path, interval);
 | 
			
		||||
      start ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void update () throw ()
 | 
			
		||||
    {
 | 
			
		||||
      ev_stat_stat (EV_A_ static_cast<ev_stat *>(this));
 | 
			
		||||
    }
 | 
			
		||||
  EV_END_WATCHER (stat, stat)
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #if EV_IDLE_ENABLE
 | 
			
		||||
  EV_BEGIN_WATCHER (idle, idle)
 | 
			
		||||
    void set () throw () { }
 | 
			
		||||
  EV_END_WATCHER (idle, idle)
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #if EV_PREPARE_ENABLE
 | 
			
		||||
  EV_BEGIN_WATCHER (prepare, prepare)
 | 
			
		||||
    void set () throw () { }
 | 
			
		||||
  EV_END_WATCHER (prepare, prepare)
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #if EV_CHECK_ENABLE
 | 
			
		||||
  EV_BEGIN_WATCHER (check, check)
 | 
			
		||||
    void set () throw () { }
 | 
			
		||||
  EV_END_WATCHER (check, check)
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #if EV_EMBED_ENABLE
 | 
			
		||||
  EV_BEGIN_WATCHER (embed, embed)
 | 
			
		||||
    void set_embed (struct ev_loop *embedded_loop) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      int active = is_active ();
 | 
			
		||||
      if (active) stop ();
 | 
			
		||||
      ev_embed_set (static_cast<ev_embed *>(this), embedded_loop);
 | 
			
		||||
      if (active) start ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void start (struct ev_loop *embedded_loop) throw ()
 | 
			
		||||
    {
 | 
			
		||||
      set (embedded_loop);
 | 
			
		||||
      start ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void sweep ()
 | 
			
		||||
    {
 | 
			
		||||
      ev_embed_sweep (EV_A_ static_cast<ev_embed *>(this));
 | 
			
		||||
    }
 | 
			
		||||
  EV_END_WATCHER (embed, embed)
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #if EV_FORK_ENABLE
 | 
			
		||||
  EV_BEGIN_WATCHER (fork, fork)
 | 
			
		||||
    void set () throw () { }
 | 
			
		||||
  EV_END_WATCHER (fork, fork)
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #if EV_ASYNC_ENABLE
 | 
			
		||||
  EV_BEGIN_WATCHER (async, async)
 | 
			
		||||
    void send () throw ()
 | 
			
		||||
    {
 | 
			
		||||
      ev_async_send (EV_A_ static_cast<ev_async *>(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool async_pending () throw ()
 | 
			
		||||
    {
 | 
			
		||||
      return ev_async_pending (static_cast<ev_async *>(this));
 | 
			
		||||
    }
 | 
			
		||||
  EV_END_WATCHER (async, async)
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #undef EV_PX
 | 
			
		||||
  #undef EV_PX_
 | 
			
		||||
  #undef EV_CONSTRUCT
 | 
			
		||||
  #undef EV_BEGIN_WATCHER
 | 
			
		||||
  #undef EV_END_WATCHER
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5647
									
								
								libev/ev.3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5647
									
								
								libev/ev.3
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										5143
									
								
								libev/ev.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5143
									
								
								libev/ev.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										854
									
								
								libev/ev.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										854
									
								
								libev/ev.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,854 @@
 | 
			
		||||
/*
 | 
			
		||||
 * libev native API header
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2007,2008,2009,2010,2011,2012,2015 Marc Alexander Lehmann <libev@schmorp.de>
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef EV_H_
 | 
			
		||||
#define EV_H_
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
# define EV_CPP(x) x
 | 
			
		||||
# if __cplusplus >= 201103L
 | 
			
		||||
#  define EV_THROW noexcept
 | 
			
		||||
# else
 | 
			
		||||
#  define EV_THROW throw ()
 | 
			
		||||
# endif
 | 
			
		||||
#else
 | 
			
		||||
# define EV_CPP(x)
 | 
			
		||||
# define EV_THROW
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
EV_CPP(extern "C" {)
 | 
			
		||||
 | 
			
		||||
/*****************************************************************************/
 | 
			
		||||
 | 
			
		||||
/* pre-4.0 compatibility */
 | 
			
		||||
#ifndef EV_COMPAT3
 | 
			
		||||
# define EV_COMPAT3 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EV_FEATURES
 | 
			
		||||
# if defined __OPTIMIZE_SIZE__
 | 
			
		||||
#  define EV_FEATURES 0x7c
 | 
			
		||||
# else
 | 
			
		||||
#  define EV_FEATURES 0x7f
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define EV_FEATURE_CODE     ((EV_FEATURES) &  1)
 | 
			
		||||
#define EV_FEATURE_DATA     ((EV_FEATURES) &  2)
 | 
			
		||||
#define EV_FEATURE_CONFIG   ((EV_FEATURES) &  4)
 | 
			
		||||
#define EV_FEATURE_API      ((EV_FEATURES) &  8)
 | 
			
		||||
#define EV_FEATURE_WATCHERS ((EV_FEATURES) & 16)
 | 
			
		||||
#define EV_FEATURE_BACKENDS ((EV_FEATURES) & 32)
 | 
			
		||||
#define EV_FEATURE_OS       ((EV_FEATURES) & 64)
 | 
			
		||||
 | 
			
		||||
/* these priorities are inclusive, higher priorities will be invoked earlier */
 | 
			
		||||
#ifndef EV_MINPRI
 | 
			
		||||
# define EV_MINPRI (EV_FEATURE_CONFIG ? -2 : 0)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EV_MAXPRI
 | 
			
		||||
# define EV_MAXPRI (EV_FEATURE_CONFIG ? +2 : 0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EV_MULTIPLICITY
 | 
			
		||||
# define EV_MULTIPLICITY EV_FEATURE_CONFIG
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EV_PERIODIC_ENABLE
 | 
			
		||||
# define EV_PERIODIC_ENABLE EV_FEATURE_WATCHERS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EV_STAT_ENABLE
 | 
			
		||||
# define EV_STAT_ENABLE EV_FEATURE_WATCHERS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EV_PREPARE_ENABLE
 | 
			
		||||
# define EV_PREPARE_ENABLE EV_FEATURE_WATCHERS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EV_CHECK_ENABLE
 | 
			
		||||
# define EV_CHECK_ENABLE EV_FEATURE_WATCHERS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EV_IDLE_ENABLE
 | 
			
		||||
# define EV_IDLE_ENABLE EV_FEATURE_WATCHERS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EV_FORK_ENABLE
 | 
			
		||||
# define EV_FORK_ENABLE EV_FEATURE_WATCHERS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EV_CLEANUP_ENABLE
 | 
			
		||||
# define EV_CLEANUP_ENABLE EV_FEATURE_WATCHERS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EV_SIGNAL_ENABLE
 | 
			
		||||
# define EV_SIGNAL_ENABLE EV_FEATURE_WATCHERS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EV_CHILD_ENABLE
 | 
			
		||||
# ifdef _WIN32
 | 
			
		||||
#  define EV_CHILD_ENABLE 0
 | 
			
		||||
# else
 | 
			
		||||
#  define EV_CHILD_ENABLE EV_FEATURE_WATCHERS
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EV_ASYNC_ENABLE
 | 
			
		||||
# define EV_ASYNC_ENABLE EV_FEATURE_WATCHERS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EV_EMBED_ENABLE
 | 
			
		||||
# define EV_EMBED_ENABLE EV_FEATURE_WATCHERS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EV_WALK_ENABLE
 | 
			
		||||
# define EV_WALK_ENABLE 0 /* not yet */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*****************************************************************************/
 | 
			
		||||
 | 
			
		||||
#if EV_CHILD_ENABLE && !EV_SIGNAL_ENABLE
 | 
			
		||||
# undef EV_SIGNAL_ENABLE
 | 
			
		||||
# define EV_SIGNAL_ENABLE 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*****************************************************************************/
 | 
			
		||||
 | 
			
		||||
typedef double ev_tstamp;
 | 
			
		||||
 | 
			
		||||
#include <string.h> /* for memmove */
 | 
			
		||||
 | 
			
		||||
#ifndef EV_ATOMIC_T
 | 
			
		||||
# include <signal.h>
 | 
			
		||||
# define EV_ATOMIC_T sig_atomic_t volatile
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_STAT_ENABLE
 | 
			
		||||
# ifdef _WIN32
 | 
			
		||||
#  include <time.h>
 | 
			
		||||
#  include <sys/types.h>
 | 
			
		||||
# endif
 | 
			
		||||
# include <sys/stat.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* support multiple event loops? */
 | 
			
		||||
#if EV_MULTIPLICITY
 | 
			
		||||
struct ev_loop;
 | 
			
		||||
# define EV_P  struct ev_loop *loop               /* a loop as sole parameter in a declaration */
 | 
			
		||||
# define EV_P_ EV_P,                              /* a loop as first of multiple parameters */
 | 
			
		||||
# define EV_A  loop                               /* a loop as sole argument to a function call */
 | 
			
		||||
# define EV_A_ EV_A,                              /* a loop as first of multiple arguments */
 | 
			
		||||
# define EV_DEFAULT_UC  ev_default_loop_uc_ ()    /* the default loop, if initialised, as sole arg */
 | 
			
		||||
# define EV_DEFAULT_UC_ EV_DEFAULT_UC,            /* the default loop as first of multiple arguments */
 | 
			
		||||
# define EV_DEFAULT  ev_default_loop (0)          /* the default loop as sole arg */
 | 
			
		||||
# define EV_DEFAULT_ EV_DEFAULT,                  /* the default loop as first of multiple arguments */
 | 
			
		||||
#else
 | 
			
		||||
# define EV_P void
 | 
			
		||||
# define EV_P_
 | 
			
		||||
# define EV_A
 | 
			
		||||
# define EV_A_
 | 
			
		||||
# define EV_DEFAULT
 | 
			
		||||
# define EV_DEFAULT_
 | 
			
		||||
# define EV_DEFAULT_UC
 | 
			
		||||
# define EV_DEFAULT_UC_
 | 
			
		||||
# undef EV_EMBED_ENABLE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* EV_INLINE is used for functions in header files */
 | 
			
		||||
#if __STDC_VERSION__ >= 199901L || __GNUC__ >= 3
 | 
			
		||||
# define EV_INLINE static inline
 | 
			
		||||
#else
 | 
			
		||||
# define EV_INLINE static
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EV_API_STATIC
 | 
			
		||||
# define EV_API_DECL static
 | 
			
		||||
#else
 | 
			
		||||
# define EV_API_DECL extern
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* EV_PROTOTYPES can be used to switch of prototype declarations */
 | 
			
		||||
#ifndef EV_PROTOTYPES
 | 
			
		||||
# define EV_PROTOTYPES 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*****************************************************************************/
 | 
			
		||||
 | 
			
		||||
#define EV_VERSION_MAJOR 4
 | 
			
		||||
#define EV_VERSION_MINOR 24
 | 
			
		||||
 | 
			
		||||
/* eventmask, revents, events... */
 | 
			
		||||
enum {
 | 
			
		||||
  EV_UNDEF    = (int)0xFFFFFFFF, /* guaranteed to be invalid */
 | 
			
		||||
  EV_NONE     =            0x00, /* no events */
 | 
			
		||||
  EV_READ     =            0x01, /* ev_io detected read will not block */
 | 
			
		||||
  EV_WRITE    =            0x02, /* ev_io detected write will not block */
 | 
			
		||||
  EV__IOFDSET =            0x80, /* internal use only */
 | 
			
		||||
  EV_IO       =         EV_READ, /* alias for type-detection */
 | 
			
		||||
  EV_TIMER    =      0x00000100, /* timer timed out */
 | 
			
		||||
#if EV_COMPAT3
 | 
			
		||||
  EV_TIMEOUT  =        EV_TIMER, /* pre 4.0 API compatibility */
 | 
			
		||||
#endif
 | 
			
		||||
  EV_PERIODIC =      0x00000200, /* periodic timer timed out */
 | 
			
		||||
  EV_SIGNAL   =      0x00000400, /* signal was received */
 | 
			
		||||
  EV_CHILD    =      0x00000800, /* child/pid had status change */
 | 
			
		||||
  EV_STAT     =      0x00001000, /* stat data changed */
 | 
			
		||||
  EV_IDLE     =      0x00002000, /* event loop is idling */
 | 
			
		||||
  EV_PREPARE  =      0x00004000, /* event loop about to poll */
 | 
			
		||||
  EV_CHECK    =      0x00008000, /* event loop finished poll */
 | 
			
		||||
  EV_EMBED    =      0x00010000, /* embedded event loop needs sweep */
 | 
			
		||||
  EV_FORK     =      0x00020000, /* event loop resumed in child */
 | 
			
		||||
  EV_CLEANUP  =      0x00040000, /* event loop resumed in child */
 | 
			
		||||
  EV_ASYNC    =      0x00080000, /* async intra-loop signal */
 | 
			
		||||
  EV_CUSTOM   =      0x01000000, /* for use by user code */
 | 
			
		||||
  EV_ERROR    = (int)0x80000000  /* sent when an error occurs */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* can be used to add custom fields to all watchers, while losing binary compatibility */
 | 
			
		||||
#ifndef EV_COMMON
 | 
			
		||||
# define EV_COMMON void *data;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EV_CB_DECLARE
 | 
			
		||||
# define EV_CB_DECLARE(type) void (*cb)(EV_P_ struct type *w, int revents);
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EV_CB_INVOKE
 | 
			
		||||
# define EV_CB_INVOKE(watcher,revents) (watcher)->cb (EV_A_ (watcher), (revents))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* not official, do not use */
 | 
			
		||||
#define EV_CB(type,name) void name (EV_P_ struct ev_ ## type *w, int revents)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * struct member types:
 | 
			
		||||
 * private: you may look at them, but not change them,
 | 
			
		||||
 *          and they might not mean anything to you.
 | 
			
		||||
 * ro: can be read anytime, but only changed when the watcher isn't active.
 | 
			
		||||
 * rw: can be read and modified anytime, even when the watcher is active.
 | 
			
		||||
 *
 | 
			
		||||
 * some internal details that might be helpful for debugging:
 | 
			
		||||
 *
 | 
			
		||||
 * active is either 0, which means the watcher is not active,
 | 
			
		||||
 *           or the array index of the watcher (periodics, timers)
 | 
			
		||||
 *           or the array index + 1 (most other watchers)
 | 
			
		||||
 *           or simply 1 for watchers that aren't in some array.
 | 
			
		||||
 * pending is either 0, in which case the watcher isn't,
 | 
			
		||||
 *           or the array index + 1 in the pendings array.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if EV_MINPRI == EV_MAXPRI
 | 
			
		||||
# define EV_DECL_PRIORITY
 | 
			
		||||
#elif !defined (EV_DECL_PRIORITY)
 | 
			
		||||
# define EV_DECL_PRIORITY int priority;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* shared by all watchers */
 | 
			
		||||
#define EV_WATCHER(type)			\
 | 
			
		||||
  int active; /* private */			\
 | 
			
		||||
  int pending; /* private */			\
 | 
			
		||||
  EV_DECL_PRIORITY /* private */		\
 | 
			
		||||
  EV_COMMON /* rw */				\
 | 
			
		||||
  EV_CB_DECLARE (type) /* private */
 | 
			
		||||
 | 
			
		||||
#define EV_WATCHER_LIST(type)			\
 | 
			
		||||
  EV_WATCHER (type)				\
 | 
			
		||||
  struct ev_watcher_list *next; /* private */
 | 
			
		||||
 | 
			
		||||
#define EV_WATCHER_TIME(type)			\
 | 
			
		||||
  EV_WATCHER (type)				\
 | 
			
		||||
  ev_tstamp at;     /* private */
 | 
			
		||||
 | 
			
		||||
/* base class, nothing to see here unless you subclass */
 | 
			
		||||
typedef struct ev_watcher
 | 
			
		||||
{
 | 
			
		||||
  EV_WATCHER (ev_watcher)
 | 
			
		||||
} ev_watcher;
 | 
			
		||||
 | 
			
		||||
/* base class, nothing to see here unless you subclass */
 | 
			
		||||
typedef struct ev_watcher_list
 | 
			
		||||
{
 | 
			
		||||
  EV_WATCHER_LIST (ev_watcher_list)
 | 
			
		||||
} ev_watcher_list;
 | 
			
		||||
 | 
			
		||||
/* base class, nothing to see here unless you subclass */
 | 
			
		||||
typedef struct ev_watcher_time
 | 
			
		||||
{
 | 
			
		||||
  EV_WATCHER_TIME (ev_watcher_time)
 | 
			
		||||
} ev_watcher_time;
 | 
			
		||||
 | 
			
		||||
/* invoked when fd is either EV_READable or EV_WRITEable */
 | 
			
		||||
/* revent EV_READ, EV_WRITE */
 | 
			
		||||
typedef struct ev_io
 | 
			
		||||
{
 | 
			
		||||
  EV_WATCHER_LIST (ev_io)
 | 
			
		||||
 | 
			
		||||
  int fd;     /* ro */
 | 
			
		||||
  int events; /* ro */
 | 
			
		||||
} ev_io;
 | 
			
		||||
 | 
			
		||||
/* invoked after a specific time, repeatable (based on monotonic clock) */
 | 
			
		||||
/* revent EV_TIMEOUT */
 | 
			
		||||
typedef struct ev_timer
 | 
			
		||||
{
 | 
			
		||||
  EV_WATCHER_TIME (ev_timer)
 | 
			
		||||
 | 
			
		||||
  ev_tstamp repeat; /* rw */
 | 
			
		||||
} ev_timer;
 | 
			
		||||
 | 
			
		||||
/* invoked at some specific time, possibly repeating at regular intervals (based on UTC) */
 | 
			
		||||
/* revent EV_PERIODIC */
 | 
			
		||||
typedef struct ev_periodic
 | 
			
		||||
{
 | 
			
		||||
  EV_WATCHER_TIME (ev_periodic)
 | 
			
		||||
 | 
			
		||||
  ev_tstamp offset; /* rw */
 | 
			
		||||
  ev_tstamp interval; /* rw */
 | 
			
		||||
  ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now) EV_THROW; /* rw */
 | 
			
		||||
} ev_periodic;
 | 
			
		||||
 | 
			
		||||
/* invoked when the given signal has been received */
 | 
			
		||||
/* revent EV_SIGNAL */
 | 
			
		||||
typedef struct ev_signal
 | 
			
		||||
{
 | 
			
		||||
  EV_WATCHER_LIST (ev_signal)
 | 
			
		||||
 | 
			
		||||
  int signum; /* ro */
 | 
			
		||||
} ev_signal;
 | 
			
		||||
 | 
			
		||||
/* invoked when sigchld is received and waitpid indicates the given pid */
 | 
			
		||||
/* revent EV_CHILD */
 | 
			
		||||
/* does not support priorities */
 | 
			
		||||
typedef struct ev_child
 | 
			
		||||
{
 | 
			
		||||
  EV_WATCHER_LIST (ev_child)
 | 
			
		||||
 | 
			
		||||
  int flags;   /* private */
 | 
			
		||||
  int pid;     /* ro */
 | 
			
		||||
  int rpid;    /* rw, holds the received pid */
 | 
			
		||||
  int rstatus; /* rw, holds the exit status, use the macros from sys/wait.h */
 | 
			
		||||
} ev_child;
 | 
			
		||||
 | 
			
		||||
#if EV_STAT_ENABLE
 | 
			
		||||
/* st_nlink = 0 means missing file or other error */
 | 
			
		||||
# ifdef _WIN32
 | 
			
		||||
typedef struct _stati64 ev_statdata;
 | 
			
		||||
# else
 | 
			
		||||
typedef struct stat ev_statdata;
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
/* invoked each time the stat data changes for a given path */
 | 
			
		||||
/* revent EV_STAT */
 | 
			
		||||
typedef struct ev_stat
 | 
			
		||||
{
 | 
			
		||||
  EV_WATCHER_LIST (ev_stat)
 | 
			
		||||
 | 
			
		||||
  ev_timer timer;     /* private */
 | 
			
		||||
  ev_tstamp interval; /* ro */
 | 
			
		||||
  const char *path;   /* ro */
 | 
			
		||||
  ev_statdata prev;   /* ro */
 | 
			
		||||
  ev_statdata attr;   /* ro */
 | 
			
		||||
 | 
			
		||||
  int wd; /* wd for inotify, fd for kqueue */
 | 
			
		||||
} ev_stat;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_IDLE_ENABLE
 | 
			
		||||
/* invoked when the nothing else needs to be done, keeps the process from blocking */
 | 
			
		||||
/* revent EV_IDLE */
 | 
			
		||||
typedef struct ev_idle
 | 
			
		||||
{
 | 
			
		||||
  EV_WATCHER (ev_idle)
 | 
			
		||||
} ev_idle;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* invoked for each run of the mainloop, just before the blocking call */
 | 
			
		||||
/* you can still change events in any way you like */
 | 
			
		||||
/* revent EV_PREPARE */
 | 
			
		||||
typedef struct ev_prepare
 | 
			
		||||
{
 | 
			
		||||
  EV_WATCHER (ev_prepare)
 | 
			
		||||
} ev_prepare;
 | 
			
		||||
 | 
			
		||||
/* invoked for each run of the mainloop, just after the blocking call */
 | 
			
		||||
/* revent EV_CHECK */
 | 
			
		||||
typedef struct ev_check
 | 
			
		||||
{
 | 
			
		||||
  EV_WATCHER (ev_check)
 | 
			
		||||
} ev_check;
 | 
			
		||||
 | 
			
		||||
#if EV_FORK_ENABLE
 | 
			
		||||
/* the callback gets invoked before check in the child process when a fork was detected */
 | 
			
		||||
/* revent EV_FORK */
 | 
			
		||||
typedef struct ev_fork
 | 
			
		||||
{
 | 
			
		||||
  EV_WATCHER (ev_fork)
 | 
			
		||||
} ev_fork;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_CLEANUP_ENABLE
 | 
			
		||||
/* is invoked just before the loop gets destroyed */
 | 
			
		||||
/* revent EV_CLEANUP */
 | 
			
		||||
typedef struct ev_cleanup
 | 
			
		||||
{
 | 
			
		||||
  EV_WATCHER (ev_cleanup)
 | 
			
		||||
} ev_cleanup;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_EMBED_ENABLE
 | 
			
		||||
/* used to embed an event loop inside another */
 | 
			
		||||
/* the callback gets invoked when the event loop has handled events, and can be 0 */
 | 
			
		||||
typedef struct ev_embed
 | 
			
		||||
{
 | 
			
		||||
  EV_WATCHER (ev_embed)
 | 
			
		||||
 | 
			
		||||
  struct ev_loop *other; /* ro */
 | 
			
		||||
  ev_io io;              /* private */
 | 
			
		||||
  ev_prepare prepare;    /* private */
 | 
			
		||||
  ev_check check;        /* unused */
 | 
			
		||||
  ev_timer timer;        /* unused */
 | 
			
		||||
  ev_periodic periodic;  /* unused */
 | 
			
		||||
  ev_idle idle;          /* unused */
 | 
			
		||||
  ev_fork fork;          /* private */
 | 
			
		||||
#if EV_CLEANUP_ENABLE
 | 
			
		||||
  ev_cleanup cleanup;    /* unused */
 | 
			
		||||
#endif
 | 
			
		||||
} ev_embed;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_ASYNC_ENABLE
 | 
			
		||||
/* invoked when somebody calls ev_async_send on the watcher */
 | 
			
		||||
/* revent EV_ASYNC */
 | 
			
		||||
typedef struct ev_async
 | 
			
		||||
{
 | 
			
		||||
  EV_WATCHER (ev_async)
 | 
			
		||||
 | 
			
		||||
  EV_ATOMIC_T sent; /* private */
 | 
			
		||||
} ev_async;
 | 
			
		||||
 | 
			
		||||
# define ev_async_pending(w) (+(w)->sent)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* the presence of this union forces similar struct layout */
 | 
			
		||||
union ev_any_watcher
 | 
			
		||||
{
 | 
			
		||||
  struct ev_watcher w;
 | 
			
		||||
  struct ev_watcher_list wl;
 | 
			
		||||
 | 
			
		||||
  struct ev_io io;
 | 
			
		||||
  struct ev_timer timer;
 | 
			
		||||
  struct ev_periodic periodic;
 | 
			
		||||
  struct ev_signal signal;
 | 
			
		||||
  struct ev_child child;
 | 
			
		||||
#if EV_STAT_ENABLE
 | 
			
		||||
  struct ev_stat stat;
 | 
			
		||||
#endif
 | 
			
		||||
#if EV_IDLE_ENABLE
 | 
			
		||||
  struct ev_idle idle;
 | 
			
		||||
#endif
 | 
			
		||||
  struct ev_prepare prepare;
 | 
			
		||||
  struct ev_check check;
 | 
			
		||||
#if EV_FORK_ENABLE
 | 
			
		||||
  struct ev_fork fork;
 | 
			
		||||
#endif
 | 
			
		||||
#if EV_CLEANUP_ENABLE
 | 
			
		||||
  struct ev_cleanup cleanup;
 | 
			
		||||
#endif
 | 
			
		||||
#if EV_EMBED_ENABLE
 | 
			
		||||
  struct ev_embed embed;
 | 
			
		||||
#endif
 | 
			
		||||
#if EV_ASYNC_ENABLE
 | 
			
		||||
  struct ev_async async;
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* flag bits for ev_default_loop and ev_loop_new */
 | 
			
		||||
enum {
 | 
			
		||||
  /* the default */
 | 
			
		||||
  EVFLAG_AUTO      = 0x00000000U, /* not quite a mask */
 | 
			
		||||
  /* flag bits */
 | 
			
		||||
  EVFLAG_NOENV     = 0x01000000U, /* do NOT consult environment */
 | 
			
		||||
  EVFLAG_FORKCHECK = 0x02000000U, /* check for a fork in each iteration */
 | 
			
		||||
  /* debugging/feature disable */
 | 
			
		||||
  EVFLAG_NOINOTIFY = 0x00100000U, /* do not attempt to use inotify */
 | 
			
		||||
#if EV_COMPAT3
 | 
			
		||||
  EVFLAG_NOSIGFD   = 0, /* compatibility to pre-3.9 */
 | 
			
		||||
#endif
 | 
			
		||||
  EVFLAG_SIGNALFD  = 0x00200000U, /* attempt to use signalfd */
 | 
			
		||||
  EVFLAG_NOSIGMASK = 0x00400000U  /* avoid modifying the signal mask */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* method bits to be ored together */
 | 
			
		||||
enum {
 | 
			
		||||
  EVBACKEND_SELECT  = 0x00000001U, /* available just about anywhere */
 | 
			
		||||
  EVBACKEND_POLL    = 0x00000002U, /* !win, !aix, broken on osx */
 | 
			
		||||
  EVBACKEND_EPOLL   = 0x00000004U, /* linux */
 | 
			
		||||
  EVBACKEND_KQUEUE  = 0x00000008U, /* bsd, broken on osx */
 | 
			
		||||
  EVBACKEND_DEVPOLL = 0x00000010U, /* solaris 8 */ /* NYI */
 | 
			
		||||
  EVBACKEND_PORT    = 0x00000020U, /* solaris 10 */
 | 
			
		||||
  EVBACKEND_ALL     = 0x0000003FU, /* all known backends */
 | 
			
		||||
  EVBACKEND_MASK    = 0x0000FFFFU  /* all future backends */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if EV_PROTOTYPES
 | 
			
		||||
EV_API_DECL int ev_version_major (void) EV_THROW;
 | 
			
		||||
EV_API_DECL int ev_version_minor (void) EV_THROW;
 | 
			
		||||
 | 
			
		||||
EV_API_DECL unsigned int ev_supported_backends (void) EV_THROW;
 | 
			
		||||
EV_API_DECL unsigned int ev_recommended_backends (void) EV_THROW;
 | 
			
		||||
EV_API_DECL unsigned int ev_embeddable_backends (void) EV_THROW;
 | 
			
		||||
 | 
			
		||||
EV_API_DECL ev_tstamp ev_time (void) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_sleep (ev_tstamp delay) EV_THROW; /* sleep for a while */
 | 
			
		||||
 | 
			
		||||
/* Sets the allocation function to use, works like realloc.
 | 
			
		||||
 * It is used to allocate and free memory.
 | 
			
		||||
 * If it returns zero when memory needs to be allocated, the library might abort
 | 
			
		||||
 * or take some potentially destructive action.
 | 
			
		||||
 * The default is your system realloc function.
 | 
			
		||||
 */
 | 
			
		||||
EV_API_DECL void ev_set_allocator (void *(*cb)(void *ptr, long size) EV_THROW) EV_THROW;
 | 
			
		||||
 | 
			
		||||
/* set the callback function to call on a
 | 
			
		||||
 * retryable syscall error
 | 
			
		||||
 * (such as failed select, poll, epoll_wait)
 | 
			
		||||
 */
 | 
			
		||||
EV_API_DECL void ev_set_syserr_cb (void (*cb)(const char *msg) EV_THROW) EV_THROW;
 | 
			
		||||
 | 
			
		||||
#if EV_MULTIPLICITY
 | 
			
		||||
 | 
			
		||||
/* the default loop is the only one that handles signals and child watchers */
 | 
			
		||||
/* you can call this as often as you like */
 | 
			
		||||
EV_API_DECL struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0)) EV_THROW;
 | 
			
		||||
 | 
			
		||||
#ifdef EV_API_STATIC
 | 
			
		||||
EV_API_DECL struct ev_loop *ev_default_loop_ptr;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
EV_INLINE struct ev_loop *
 | 
			
		||||
ev_default_loop_uc_ (void) EV_THROW
 | 
			
		||||
{
 | 
			
		||||
  extern struct ev_loop *ev_default_loop_ptr;
 | 
			
		||||
 | 
			
		||||
  return ev_default_loop_ptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EV_INLINE int
 | 
			
		||||
ev_is_default_loop (EV_P) EV_THROW
 | 
			
		||||
{
 | 
			
		||||
  return EV_A == EV_DEFAULT_UC;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* create and destroy alternative loops that don't handle signals */
 | 
			
		||||
EV_API_DECL struct ev_loop *ev_loop_new (unsigned int flags EV_CPP (= 0)) EV_THROW;
 | 
			
		||||
 | 
			
		||||
EV_API_DECL ev_tstamp ev_now (EV_P) EV_THROW; /* time w.r.t. timers and the eventloop, updated after each poll */
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
EV_API_DECL int ev_default_loop (unsigned int flags EV_CPP (= 0)) EV_THROW; /* returns true when successful */
 | 
			
		||||
 | 
			
		||||
EV_API_DECL ev_tstamp ev_rt_now;
 | 
			
		||||
 | 
			
		||||
EV_INLINE ev_tstamp
 | 
			
		||||
ev_now (void) EV_THROW
 | 
			
		||||
{
 | 
			
		||||
  return ev_rt_now;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* looks weird, but ev_is_default_loop (EV_A) still works if this exists */
 | 
			
		||||
EV_INLINE int
 | 
			
		||||
ev_is_default_loop (void) EV_THROW
 | 
			
		||||
{
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* multiplicity */
 | 
			
		||||
 | 
			
		||||
/* destroy event loops, also works for the default loop */
 | 
			
		||||
EV_API_DECL void ev_loop_destroy (EV_P);
 | 
			
		||||
 | 
			
		||||
/* this needs to be called after fork, to duplicate the loop */
 | 
			
		||||
/* when you want to re-use it in the child */
 | 
			
		||||
/* you can call it in either the parent or the child */
 | 
			
		||||
/* you can actually call it at any time, anywhere :) */
 | 
			
		||||
EV_API_DECL void ev_loop_fork (EV_P) EV_THROW;
 | 
			
		||||
 | 
			
		||||
EV_API_DECL unsigned int ev_backend (EV_P) EV_THROW; /* backend in use by loop */
 | 
			
		||||
 | 
			
		||||
EV_API_DECL void ev_now_update (EV_P) EV_THROW; /* update event loop time */
 | 
			
		||||
 | 
			
		||||
#if EV_WALK_ENABLE
 | 
			
		||||
/* walk (almost) all watchers in the loop of a given type, invoking the */
 | 
			
		||||
/* callback on every such watcher. The callback might stop the watcher, */
 | 
			
		||||
/* but do nothing else with the loop */
 | 
			
		||||
EV_API_DECL void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_THROW;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* prototypes */
 | 
			
		||||
 | 
			
		||||
/* ev_run flags values */
 | 
			
		||||
enum {
 | 
			
		||||
  EVRUN_NOWAIT = 1, /* do not block/wait */
 | 
			
		||||
  EVRUN_ONCE   = 2  /* block *once* only */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* ev_break how values */
 | 
			
		||||
enum {
 | 
			
		||||
  EVBREAK_CANCEL = 0, /* undo unloop */
 | 
			
		||||
  EVBREAK_ONE    = 1, /* unloop once */
 | 
			
		||||
  EVBREAK_ALL    = 2  /* unloop all loops */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if EV_PROTOTYPES
 | 
			
		||||
EV_API_DECL int  ev_run (EV_P_ int flags EV_CPP (= 0));
 | 
			
		||||
EV_API_DECL void ev_break (EV_P_ int how EV_CPP (= EVBREAK_ONE)) EV_THROW; /* break out of the loop */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ref/unref can be used to add or remove a refcount on the mainloop. every watcher
 | 
			
		||||
 * keeps one reference. if you have a long-running watcher you never unregister that
 | 
			
		||||
 * should not keep ev_loop from running, unref() after starting, and ref() before stopping.
 | 
			
		||||
 */
 | 
			
		||||
EV_API_DECL void ev_ref   (EV_P) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_unref (EV_P) EV_THROW;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * convenience function, wait for a single event, without registering an event watcher
 | 
			
		||||
 * if timeout is < 0, do wait indefinitely
 | 
			
		||||
 */
 | 
			
		||||
EV_API_DECL void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg) EV_THROW;
 | 
			
		||||
 | 
			
		||||
# if EV_FEATURE_API
 | 
			
		||||
EV_API_DECL unsigned int ev_iteration (EV_P) EV_THROW; /* number of loop iterations */
 | 
			
		||||
EV_API_DECL unsigned int ev_depth     (EV_P) EV_THROW; /* #ev_loop enters - #ev_loop leaves */
 | 
			
		||||
EV_API_DECL void         ev_verify    (EV_P) EV_THROW; /* abort if loop data corrupted */
 | 
			
		||||
 | 
			
		||||
EV_API_DECL void ev_set_io_collect_interval (EV_P_ ev_tstamp interval) EV_THROW; /* sleep at least this time, default 0 */
 | 
			
		||||
EV_API_DECL void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_THROW; /* sleep at least this time, default 0 */
 | 
			
		||||
 | 
			
		||||
/* advanced stuff for threading etc. support, see docs */
 | 
			
		||||
EV_API_DECL void ev_set_userdata (EV_P_ void *data) EV_THROW;
 | 
			
		||||
EV_API_DECL void *ev_userdata (EV_P) EV_THROW;
 | 
			
		||||
typedef void (*ev_loop_callback)(EV_P);
 | 
			
		||||
EV_API_DECL void ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_THROW;
 | 
			
		||||
/* C++ doesn't allow the use of the ev_loop_callback typedef here, so we need to spell it out */
 | 
			
		||||
EV_API_DECL void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_THROW, void (*acquire)(EV_P) EV_THROW) EV_THROW;
 | 
			
		||||
 | 
			
		||||
EV_API_DECL unsigned int ev_pending_count (EV_P) EV_THROW; /* number of pending events, if any */
 | 
			
		||||
EV_API_DECL void ev_invoke_pending (EV_P); /* invoke all pending watchers */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * stop/start the timer handling.
 | 
			
		||||
 */
 | 
			
		||||
EV_API_DECL void ev_suspend (EV_P) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_resume  (EV_P) EV_THROW;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* these may evaluate ev multiple times, and the other arguments at most once */
 | 
			
		||||
/* either use ev_init + ev_TYPE_set, or the ev_TYPE_init macro, below, to first initialise a watcher */
 | 
			
		||||
#define ev_init(ev,cb_) do {			\
 | 
			
		||||
  ((ev_watcher *)(void *)(ev))->active  =	\
 | 
			
		||||
  ((ev_watcher *)(void *)(ev))->pending = 0;	\
 | 
			
		||||
  ev_set_priority ((ev), 0);			\
 | 
			
		||||
  ev_set_cb ((ev), cb_);			\
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
#define ev_io_set(ev,fd_,events_)            do { (ev)->fd = (fd_); (ev)->events = (events_) | EV__IOFDSET; } while (0)
 | 
			
		||||
#define ev_timer_set(ev,after_,repeat_)      do { ((ev_watcher_time *)(ev))->at = (after_); (ev)->repeat = (repeat_); } while (0)
 | 
			
		||||
#define ev_periodic_set(ev,ofs_,ival_,rcb_)  do { (ev)->offset = (ofs_); (ev)->interval = (ival_); (ev)->reschedule_cb = (rcb_); } while (0)
 | 
			
		||||
#define ev_signal_set(ev,signum_)            do { (ev)->signum = (signum_); } while (0)
 | 
			
		||||
#define ev_child_set(ev,pid_,trace_)         do { (ev)->pid = (pid_); (ev)->flags = !!(trace_); } while (0)
 | 
			
		||||
#define ev_stat_set(ev,path_,interval_)      do { (ev)->path = (path_); (ev)->interval = (interval_); (ev)->wd = -2; } while (0)
 | 
			
		||||
#define ev_idle_set(ev)                      /* nop, yes, this is a serious in-joke */
 | 
			
		||||
#define ev_prepare_set(ev)                   /* nop, yes, this is a serious in-joke */
 | 
			
		||||
#define ev_check_set(ev)                     /* nop, yes, this is a serious in-joke */
 | 
			
		||||
#define ev_embed_set(ev,other_)              do { (ev)->other = (other_); } while (0)
 | 
			
		||||
#define ev_fork_set(ev)                      /* nop, yes, this is a serious in-joke */
 | 
			
		||||
#define ev_cleanup_set(ev)                   /* nop, yes, this is a serious in-joke */
 | 
			
		||||
#define ev_async_set(ev)                     /* nop, yes, this is a serious in-joke */
 | 
			
		||||
 | 
			
		||||
#define ev_io_init(ev,cb,fd,events)          do { ev_init ((ev), (cb)); ev_io_set ((ev),(fd),(events)); } while (0)
 | 
			
		||||
#define ev_timer_init(ev,cb,after,repeat)    do { ev_init ((ev), (cb)); ev_timer_set ((ev),(after),(repeat)); } while (0)
 | 
			
		||||
#define ev_periodic_init(ev,cb,ofs,ival,rcb) do { ev_init ((ev), (cb)); ev_periodic_set ((ev),(ofs),(ival),(rcb)); } while (0)
 | 
			
		||||
#define ev_signal_init(ev,cb,signum)         do { ev_init ((ev), (cb)); ev_signal_set ((ev), (signum)); } while (0)
 | 
			
		||||
#define ev_child_init(ev,cb,pid,trace)       do { ev_init ((ev), (cb)); ev_child_set ((ev),(pid),(trace)); } while (0)
 | 
			
		||||
#define ev_stat_init(ev,cb,path,interval)    do { ev_init ((ev), (cb)); ev_stat_set ((ev),(path),(interval)); } while (0)
 | 
			
		||||
#define ev_idle_init(ev,cb)                  do { ev_init ((ev), (cb)); ev_idle_set ((ev)); } while (0)
 | 
			
		||||
#define ev_prepare_init(ev,cb)               do { ev_init ((ev), (cb)); ev_prepare_set ((ev)); } while (0)
 | 
			
		||||
#define ev_check_init(ev,cb)                 do { ev_init ((ev), (cb)); ev_check_set ((ev)); } while (0)
 | 
			
		||||
#define ev_embed_init(ev,cb,other)           do { ev_init ((ev), (cb)); ev_embed_set ((ev),(other)); } while (0)
 | 
			
		||||
#define ev_fork_init(ev,cb)                  do { ev_init ((ev), (cb)); ev_fork_set ((ev)); } while (0)
 | 
			
		||||
#define ev_cleanup_init(ev,cb)               do { ev_init ((ev), (cb)); ev_cleanup_set ((ev)); } while (0)
 | 
			
		||||
#define ev_async_init(ev,cb)                 do { ev_init ((ev), (cb)); ev_async_set ((ev)); } while (0)
 | 
			
		||||
 | 
			
		||||
#define ev_is_pending(ev)                    (0 + ((ev_watcher *)(void *)(ev))->pending) /* ro, true when watcher is waiting for callback invocation */
 | 
			
		||||
#define ev_is_active(ev)                     (0 + ((ev_watcher *)(void *)(ev))->active) /* ro, true when the watcher has been started */
 | 
			
		||||
 | 
			
		||||
#define ev_cb_(ev)                           (ev)->cb /* rw */
 | 
			
		||||
#define ev_cb(ev)                            (memmove (&ev_cb_ (ev), &((ev_watcher *)(ev))->cb, sizeof (ev_cb_ (ev))), (ev)->cb)
 | 
			
		||||
 | 
			
		||||
#if EV_MINPRI == EV_MAXPRI
 | 
			
		||||
# define ev_priority(ev)                     ((ev), EV_MINPRI)
 | 
			
		||||
# define ev_set_priority(ev,pri)             ((ev), (pri))
 | 
			
		||||
#else
 | 
			
		||||
# define ev_priority(ev)                     (+(((ev_watcher *)(void *)(ev))->priority))
 | 
			
		||||
# define ev_set_priority(ev,pri)             (   (ev_watcher *)(void *)(ev))->priority = (pri)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define ev_periodic_at(ev)                   (+((ev_watcher_time *)(ev))->at)
 | 
			
		||||
 | 
			
		||||
#ifndef ev_set_cb
 | 
			
		||||
# define ev_set_cb(ev,cb_)                   (ev_cb_ (ev) = (cb_), memmove (&((ev_watcher *)(ev))->cb, &ev_cb_ (ev), sizeof (ev_cb_ (ev))))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* stopping (enabling, adding) a watcher does nothing if it is already running */
 | 
			
		||||
/* stopping (disabling, deleting) a watcher does nothing unless it's already running */
 | 
			
		||||
#if EV_PROTOTYPES
 | 
			
		||||
 | 
			
		||||
/* feeds an event into a watcher as if the event actually occurred */
 | 
			
		||||
/* accepts any ev_watcher type */
 | 
			
		||||
EV_API_DECL void ev_feed_event     (EV_P_ void *w, int revents) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_feed_fd_event  (EV_P_ int fd, int revents) EV_THROW;
 | 
			
		||||
#if EV_SIGNAL_ENABLE
 | 
			
		||||
EV_API_DECL void ev_feed_signal    (int signum) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_feed_signal_event (EV_P_ int signum) EV_THROW;
 | 
			
		||||
#endif
 | 
			
		||||
EV_API_DECL void ev_invoke         (EV_P_ void *w, int revents);
 | 
			
		||||
EV_API_DECL int  ev_clear_pending  (EV_P_ void *w) EV_THROW;
 | 
			
		||||
 | 
			
		||||
EV_API_DECL void ev_io_start       (EV_P_ ev_io *w) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_io_stop        (EV_P_ ev_io *w) EV_THROW;
 | 
			
		||||
 | 
			
		||||
EV_API_DECL void ev_timer_start    (EV_P_ ev_timer *w) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_timer_stop     (EV_P_ ev_timer *w) EV_THROW;
 | 
			
		||||
/* stops if active and no repeat, restarts if active and repeating, starts if inactive and repeating */
 | 
			
		||||
EV_API_DECL void ev_timer_again    (EV_P_ ev_timer *w) EV_THROW;
 | 
			
		||||
/* return remaining time */
 | 
			
		||||
EV_API_DECL ev_tstamp ev_timer_remaining (EV_P_ ev_timer *w) EV_THROW;
 | 
			
		||||
 | 
			
		||||
#if EV_PERIODIC_ENABLE
 | 
			
		||||
EV_API_DECL void ev_periodic_start (EV_P_ ev_periodic *w) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_periodic_stop  (EV_P_ ev_periodic *w) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_periodic_again (EV_P_ ev_periodic *w) EV_THROW;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* only supported in the default loop */
 | 
			
		||||
#if EV_SIGNAL_ENABLE
 | 
			
		||||
EV_API_DECL void ev_signal_start   (EV_P_ ev_signal *w) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_signal_stop    (EV_P_ ev_signal *w) EV_THROW;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* only supported in the default loop */
 | 
			
		||||
# if EV_CHILD_ENABLE
 | 
			
		||||
EV_API_DECL void ev_child_start    (EV_P_ ev_child *w) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_child_stop     (EV_P_ ev_child *w) EV_THROW;
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
# if EV_STAT_ENABLE
 | 
			
		||||
EV_API_DECL void ev_stat_start     (EV_P_ ev_stat *w) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_stat_stop      (EV_P_ ev_stat *w) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_stat_stat      (EV_P_ ev_stat *w) EV_THROW;
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
# if EV_IDLE_ENABLE
 | 
			
		||||
EV_API_DECL void ev_idle_start     (EV_P_ ev_idle *w) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_idle_stop      (EV_P_ ev_idle *w) EV_THROW;
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
#if EV_PREPARE_ENABLE
 | 
			
		||||
EV_API_DECL void ev_prepare_start  (EV_P_ ev_prepare *w) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_prepare_stop   (EV_P_ ev_prepare *w) EV_THROW;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_CHECK_ENABLE
 | 
			
		||||
EV_API_DECL void ev_check_start    (EV_P_ ev_check *w) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_check_stop     (EV_P_ ev_check *w) EV_THROW;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
# if EV_FORK_ENABLE
 | 
			
		||||
EV_API_DECL void ev_fork_start     (EV_P_ ev_fork *w) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_fork_stop      (EV_P_ ev_fork *w) EV_THROW;
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
# if EV_CLEANUP_ENABLE
 | 
			
		||||
EV_API_DECL void ev_cleanup_start  (EV_P_ ev_cleanup *w) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_cleanup_stop   (EV_P_ ev_cleanup *w) EV_THROW;
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
# if EV_EMBED_ENABLE
 | 
			
		||||
/* only supported when loop to be embedded is in fact embeddable */
 | 
			
		||||
EV_API_DECL void ev_embed_start    (EV_P_ ev_embed *w) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_embed_stop     (EV_P_ ev_embed *w) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_embed_sweep    (EV_P_ ev_embed *w) EV_THROW;
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
# if EV_ASYNC_ENABLE
 | 
			
		||||
EV_API_DECL void ev_async_start    (EV_P_ ev_async *w) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_async_stop     (EV_P_ ev_async *w) EV_THROW;
 | 
			
		||||
EV_API_DECL void ev_async_send     (EV_P_ ev_async *w) EV_THROW;
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
#if EV_COMPAT3
 | 
			
		||||
  #define EVLOOP_NONBLOCK EVRUN_NOWAIT
 | 
			
		||||
  #define EVLOOP_ONESHOT  EVRUN_ONCE
 | 
			
		||||
  #define EVUNLOOP_CANCEL EVBREAK_CANCEL
 | 
			
		||||
  #define EVUNLOOP_ONE    EVBREAK_ONE
 | 
			
		||||
  #define EVUNLOOP_ALL    EVBREAK_ALL
 | 
			
		||||
  #if EV_PROTOTYPES
 | 
			
		||||
    EV_INLINE void ev_loop   (EV_P_ int flags) { ev_run   (EV_A_ flags); }
 | 
			
		||||
    EV_INLINE void ev_unloop (EV_P_ int how  ) { ev_break (EV_A_ how  ); }
 | 
			
		||||
    EV_INLINE void ev_default_destroy (void) { ev_loop_destroy (EV_DEFAULT); }
 | 
			
		||||
    EV_INLINE void ev_default_fork    (void) { ev_loop_fork    (EV_DEFAULT); }
 | 
			
		||||
    #if EV_FEATURE_API
 | 
			
		||||
      EV_INLINE unsigned int ev_loop_count  (EV_P) { return ev_iteration  (EV_A); }
 | 
			
		||||
      EV_INLINE unsigned int ev_loop_depth  (EV_P) { return ev_depth      (EV_A); }
 | 
			
		||||
      EV_INLINE void         ev_loop_verify (EV_P) {        ev_verify     (EV_A); }
 | 
			
		||||
    #endif
 | 
			
		||||
  #endif
 | 
			
		||||
#else
 | 
			
		||||
  typedef struct ev_loop ev_loop;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
EV_CPP(})
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5570
									
								
								libev/ev.pod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5570
									
								
								libev/ev.pod
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										285
									
								
								libev/ev_epoll.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										285
									
								
								libev/ev_epoll.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,285 @@
 | 
			
		||||
/*
 | 
			
		||||
 * libev epoll fd activity backend
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
 | 
			
		||||
 * 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 <sys/epoll.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline_size
 | 
			
		||||
int
 | 
			
		||||
epoll_init (EV_P_ int flags)
 | 
			
		||||
{
 | 
			
		||||
#if defined EPOLL_CLOEXEC && !defined __ANDROID__
 | 
			
		||||
  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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline_size
 | 
			
		||||
void
 | 
			
		||||
epoll_destroy (EV_P)
 | 
			
		||||
{
 | 
			
		||||
  ev_free (epoll_events);
 | 
			
		||||
  array_free (epoll_eperm, EMPTY);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline_size
 | 
			
		||||
void
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										218
									
								
								libev/ev_kqueue.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								libev/ev_kqueue.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,218 @@
 | 
			
		||||
/*
 | 
			
		||||
 * libev kqueue backend
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann <libev@schmorp.de>
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <sys/event.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
inline_speed
 | 
			
		||||
void
 | 
			
		||||
kqueue_change (EV_P_ int fd, int filter, int flags, int fflags)
 | 
			
		||||
{
 | 
			
		||||
  ++kqueue_changecnt;
 | 
			
		||||
  array_needsize (struct kevent, kqueue_changes, kqueue_changemax, kqueue_changecnt, EMPTY2);
 | 
			
		||||
 | 
			
		||||
  EV_SET (&kqueue_changes [kqueue_changecnt - 1], fd, filter, flags, fflags, 0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* OS X at least needs this */
 | 
			
		||||
#ifndef EV_ENABLE
 | 
			
		||||
# define EV_ENABLE 0
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef NOTE_EOF
 | 
			
		||||
# define NOTE_EOF 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
kqueue_modify (EV_P_ int fd, int oev, int nev)
 | 
			
		||||
{
 | 
			
		||||
  if (oev != nev)
 | 
			
		||||
    {
 | 
			
		||||
      if (oev & EV_READ)
 | 
			
		||||
        kqueue_change (EV_A_ fd, EVFILT_READ , EV_DELETE, 0);
 | 
			
		||||
 | 
			
		||||
      if (oev & EV_WRITE)
 | 
			
		||||
        kqueue_change (EV_A_ fd, EVFILT_WRITE, EV_DELETE, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* to detect close/reopen reliably, we have to re-add */
 | 
			
		||||
  /* event requests even when oev == nev */
 | 
			
		||||
 | 
			
		||||
  if (nev & EV_READ)
 | 
			
		||||
    kqueue_change (EV_A_ fd, EVFILT_READ , EV_ADD | EV_ENABLE, NOTE_EOF);
 | 
			
		||||
 | 
			
		||||
  if (nev & EV_WRITE)
 | 
			
		||||
    kqueue_change (EV_A_ fd, EVFILT_WRITE, EV_ADD | EV_ENABLE, NOTE_EOF);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
kqueue_poll (EV_P_ ev_tstamp timeout)
 | 
			
		||||
{
 | 
			
		||||
  int res, i;
 | 
			
		||||
  struct timespec ts;
 | 
			
		||||
 | 
			
		||||
  /* need to resize so there is enough space for errors */
 | 
			
		||||
  if (kqueue_changecnt > kqueue_eventmax)
 | 
			
		||||
    {
 | 
			
		||||
      ev_free (kqueue_events);
 | 
			
		||||
      kqueue_eventmax = array_nextsize (sizeof (struct kevent), kqueue_eventmax, kqueue_changecnt);
 | 
			
		||||
      kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  EV_RELEASE_CB;
 | 
			
		||||
  EV_TS_SET (ts, timeout);
 | 
			
		||||
  res = kevent (backend_fd, kqueue_changes, kqueue_changecnt, kqueue_events, kqueue_eventmax, &ts);
 | 
			
		||||
  EV_ACQUIRE_CB;
 | 
			
		||||
  kqueue_changecnt = 0;
 | 
			
		||||
 | 
			
		||||
  if (expect_false (res < 0))
 | 
			
		||||
    {
 | 
			
		||||
      if (errno != EINTR)
 | 
			
		||||
        ev_syserr ("(libev) kevent");
 | 
			
		||||
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < res; ++i)
 | 
			
		||||
    {
 | 
			
		||||
      int fd = kqueue_events [i].ident;
 | 
			
		||||
 | 
			
		||||
      if (expect_false (kqueue_events [i].flags & EV_ERROR))
 | 
			
		||||
        {
 | 
			
		||||
          int err = kqueue_events [i].data;
 | 
			
		||||
 | 
			
		||||
          /* we are only interested in errors for fds that we are interested in :) */
 | 
			
		||||
          if (anfds [fd].events)
 | 
			
		||||
            {
 | 
			
		||||
              if (err == ENOENT) /* resubmit changes on ENOENT */
 | 
			
		||||
                kqueue_modify (EV_A_ fd, 0, anfds [fd].events);
 | 
			
		||||
              else if (err == EBADF) /* on EBADF, we re-check the fd */
 | 
			
		||||
                {
 | 
			
		||||
                  if (fd_valid (fd))
 | 
			
		||||
                    kqueue_modify (EV_A_ fd, 0, anfds [fd].events);
 | 
			
		||||
                  else
 | 
			
		||||
                    fd_kill (EV_A_ fd);
 | 
			
		||||
                }
 | 
			
		||||
              else /* on all other errors, we error out on the fd */
 | 
			
		||||
                fd_kill (EV_A_ fd);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        fd_event (
 | 
			
		||||
          EV_A_
 | 
			
		||||
          fd,
 | 
			
		||||
          kqueue_events [i].filter == EVFILT_READ ? EV_READ
 | 
			
		||||
          : kqueue_events [i].filter == EVFILT_WRITE ? EV_WRITE
 | 
			
		||||
          : 0
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (expect_false (res == kqueue_eventmax))
 | 
			
		||||
    {
 | 
			
		||||
      ev_free (kqueue_events);
 | 
			
		||||
      kqueue_eventmax = array_nextsize (sizeof (struct kevent), kqueue_eventmax, kqueue_eventmax + 1);
 | 
			
		||||
      kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline_size
 | 
			
		||||
int
 | 
			
		||||
kqueue_init (EV_P_ int flags)
 | 
			
		||||
{
 | 
			
		||||
  /* initialize the kernel queue */
 | 
			
		||||
  kqueue_fd_pid = getpid ();
 | 
			
		||||
  if ((backend_fd = kqueue ()) < 0)
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */
 | 
			
		||||
 | 
			
		||||
  backend_mintime = 1e-9; /* apparently, they did the right thing in freebsd */
 | 
			
		||||
  backend_modify  = kqueue_modify;
 | 
			
		||||
  backend_poll    = kqueue_poll;
 | 
			
		||||
 | 
			
		||||
  kqueue_eventmax = 64; /* initial number of events receivable per poll */
 | 
			
		||||
  kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax);
 | 
			
		||||
 | 
			
		||||
  kqueue_changes   = 0;
 | 
			
		||||
  kqueue_changemax = 0;
 | 
			
		||||
  kqueue_changecnt = 0;
 | 
			
		||||
 | 
			
		||||
  return EVBACKEND_KQUEUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline_size
 | 
			
		||||
void
 | 
			
		||||
kqueue_destroy (EV_P)
 | 
			
		||||
{
 | 
			
		||||
  ev_free (kqueue_events);
 | 
			
		||||
  ev_free (kqueue_changes);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline_size
 | 
			
		||||
void
 | 
			
		||||
kqueue_fork (EV_P)
 | 
			
		||||
{
 | 
			
		||||
  /* some BSD kernels don't just destroy the kqueue itself,
 | 
			
		||||
   * but also close the fd, which isn't documented, and
 | 
			
		||||
   * impossible to support properly.
 | 
			
		||||
   * we remember the pid of the kqueue call and only close
 | 
			
		||||
   * the fd if the pid is still the same.
 | 
			
		||||
   * this leaks fds on sane kernels, but BSD interfaces are
 | 
			
		||||
   * notoriously buggy and rarely get fixed.
 | 
			
		||||
   */
 | 
			
		||||
  pid_t newpid = getpid ();
 | 
			
		||||
 | 
			
		||||
  if (newpid == kqueue_fd_pid)
 | 
			
		||||
    close (backend_fd);
 | 
			
		||||
 | 
			
		||||
  kqueue_fd_pid = newpid;
 | 
			
		||||
  while ((backend_fd = kqueue ()) < 0)
 | 
			
		||||
    ev_syserr ("(libev) kqueue");
 | 
			
		||||
 | 
			
		||||
  fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
 | 
			
		||||
 | 
			
		||||
  /* re-register interest in fds */
 | 
			
		||||
  fd_rearm_all (EV_A);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* sys/event.h defines EV_ERROR */
 | 
			
		||||
#undef EV_ERROR
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										151
									
								
								libev/ev_poll.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								libev/ev_poll.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,151 @@
 | 
			
		||||
/*
 | 
			
		||||
 * libev poll fd activity backend
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <poll.h>
 | 
			
		||||
 | 
			
		||||
inline_size
 | 
			
		||||
void
 | 
			
		||||
pollidx_init (int *base, int count)
 | 
			
		||||
{
 | 
			
		||||
  /* consider using memset (.., -1, ...), which is practically guaranteed
 | 
			
		||||
   * to work on all systems implementing poll */
 | 
			
		||||
  while (count--)
 | 
			
		||||
    *base++ = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
poll_modify (EV_P_ int fd, int oev, int nev)
 | 
			
		||||
{
 | 
			
		||||
  int idx;
 | 
			
		||||
 | 
			
		||||
  if (oev == nev)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  array_needsize (int, pollidxs, pollidxmax, fd + 1, pollidx_init);
 | 
			
		||||
 | 
			
		||||
  idx = pollidxs [fd];
 | 
			
		||||
 | 
			
		||||
  if (idx < 0) /* need to allocate a new pollfd */
 | 
			
		||||
    {
 | 
			
		||||
      pollidxs [fd] = idx = pollcnt++;
 | 
			
		||||
      array_needsize (struct pollfd, polls, pollmax, pollcnt, EMPTY2);
 | 
			
		||||
      polls [idx].fd = fd;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  assert (polls [idx].fd == fd);
 | 
			
		||||
 | 
			
		||||
  if (nev)
 | 
			
		||||
    polls [idx].events =
 | 
			
		||||
        (nev & EV_READ ? POLLIN : 0)
 | 
			
		||||
        | (nev & EV_WRITE ? POLLOUT : 0);
 | 
			
		||||
  else /* remove pollfd */
 | 
			
		||||
    {
 | 
			
		||||
      pollidxs [fd] = -1;
 | 
			
		||||
 | 
			
		||||
      if (expect_true (idx < --pollcnt))
 | 
			
		||||
        {
 | 
			
		||||
          polls [idx] = polls [pollcnt];
 | 
			
		||||
          pollidxs [polls [idx].fd] = idx;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
poll_poll (EV_P_ ev_tstamp timeout)
 | 
			
		||||
{
 | 
			
		||||
  struct pollfd *p;
 | 
			
		||||
  int res;
 | 
			
		||||
  
 | 
			
		||||
  EV_RELEASE_CB;
 | 
			
		||||
  res = poll (polls, pollcnt, timeout * 1e3);
 | 
			
		||||
  EV_ACQUIRE_CB;
 | 
			
		||||
 | 
			
		||||
  if (expect_false (res < 0))
 | 
			
		||||
    {
 | 
			
		||||
      if (errno == EBADF)
 | 
			
		||||
        fd_ebadf (EV_A);
 | 
			
		||||
      else if (errno == ENOMEM && !syserr_cb)
 | 
			
		||||
        fd_enomem (EV_A);
 | 
			
		||||
      else if (errno != EINTR)
 | 
			
		||||
        ev_syserr ("(libev) poll");
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    for (p = polls; res; ++p)
 | 
			
		||||
      {
 | 
			
		||||
        assert (("libev: poll() returned illegal result, broken BSD kernel?", p < polls + pollcnt));
 | 
			
		||||
 | 
			
		||||
        if (expect_false (p->revents)) /* this expect is debatable */
 | 
			
		||||
          {
 | 
			
		||||
            --res;
 | 
			
		||||
 | 
			
		||||
            if (expect_false (p->revents & POLLNVAL))
 | 
			
		||||
              fd_kill (EV_A_ p->fd);
 | 
			
		||||
            else
 | 
			
		||||
              fd_event (
 | 
			
		||||
                EV_A_
 | 
			
		||||
                p->fd,
 | 
			
		||||
                (p->revents & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
 | 
			
		||||
                | (p->revents & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0)
 | 
			
		||||
              );
 | 
			
		||||
          }
 | 
			
		||||
      }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline_size
 | 
			
		||||
int
 | 
			
		||||
poll_init (EV_P_ int flags)
 | 
			
		||||
{
 | 
			
		||||
  backend_mintime = 1e-3;
 | 
			
		||||
  backend_modify  = poll_modify;
 | 
			
		||||
  backend_poll    = poll_poll;
 | 
			
		||||
 | 
			
		||||
  pollidxs = 0; pollidxmax = 0;
 | 
			
		||||
  polls    = 0; pollmax    = 0; pollcnt = 0;
 | 
			
		||||
 | 
			
		||||
  return EVBACKEND_POLL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline_size
 | 
			
		||||
void
 | 
			
		||||
poll_destroy (EV_P)
 | 
			
		||||
{
 | 
			
		||||
  ev_free (pollidxs);
 | 
			
		||||
  ev_free (polls);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										189
									
								
								libev/ev_port.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								libev/ev_port.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,189 @@
 | 
			
		||||
/*
 | 
			
		||||
 * libev solaris event port backend
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
 | 
			
		||||
 * 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 <sys/types.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <poll.h>
 | 
			
		||||
#include <port.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
inline_speed
 | 
			
		||||
void
 | 
			
		||||
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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline_size
 | 
			
		||||
int
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline_size
 | 
			
		||||
void
 | 
			
		||||
port_destroy (EV_P)
 | 
			
		||||
{
 | 
			
		||||
  ev_free (port_events);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline_size
 | 
			
		||||
void
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										316
									
								
								libev/ev_select.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										316
									
								
								libev/ev_select.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,316 @@
 | 
			
		||||
/*
 | 
			
		||||
 * libev select fd activity backend
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _WIN32
 | 
			
		||||
/* for unix systems */
 | 
			
		||||
# include <inttypes.h>
 | 
			
		||||
# ifndef __hpux
 | 
			
		||||
/* for REAL unix systems */
 | 
			
		||||
#  include <sys/select.h>
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EV_SELECT_USE_FD_SET
 | 
			
		||||
# ifdef NFDBITS
 | 
			
		||||
#  define EV_SELECT_USE_FD_SET 0
 | 
			
		||||
# else
 | 
			
		||||
#  define EV_SELECT_USE_FD_SET 1
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_SELECT_IS_WINSOCKET
 | 
			
		||||
# undef EV_SELECT_USE_FD_SET
 | 
			
		||||
# define EV_SELECT_USE_FD_SET 1
 | 
			
		||||
# undef NFDBITS
 | 
			
		||||
# define NFDBITS 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !EV_SELECT_USE_FD_SET
 | 
			
		||||
# define NFDBYTES (NFDBITS / 8)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
select_modify (EV_P_ int fd, int oev, int nev)
 | 
			
		||||
{
 | 
			
		||||
  if (oev == nev)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
#if EV_SELECT_USE_FD_SET
 | 
			
		||||
 | 
			
		||||
    #if EV_SELECT_IS_WINSOCKET
 | 
			
		||||
    SOCKET handle = anfds [fd].handle;
 | 
			
		||||
    #else
 | 
			
		||||
    int handle = fd;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    assert (("libev: fd >= FD_SETSIZE passed to fd_set-based select backend", fd < FD_SETSIZE));
 | 
			
		||||
 | 
			
		||||
    /* FD_SET is broken on windows (it adds the fd to a set twice or more,
 | 
			
		||||
     * which eventually leads to overflows). Need to call it only on changes.
 | 
			
		||||
     */
 | 
			
		||||
    #if EV_SELECT_IS_WINSOCKET
 | 
			
		||||
    if ((oev ^ nev) & EV_READ)
 | 
			
		||||
    #endif
 | 
			
		||||
      if (nev & EV_READ)
 | 
			
		||||
        FD_SET (handle, (fd_set *)vec_ri);
 | 
			
		||||
      else
 | 
			
		||||
        FD_CLR (handle, (fd_set *)vec_ri);
 | 
			
		||||
 | 
			
		||||
    #if EV_SELECT_IS_WINSOCKET
 | 
			
		||||
    if ((oev ^ nev) & EV_WRITE)
 | 
			
		||||
    #endif
 | 
			
		||||
      if (nev & EV_WRITE)
 | 
			
		||||
        FD_SET (handle, (fd_set *)vec_wi);
 | 
			
		||||
      else
 | 
			
		||||
        FD_CLR (handle, (fd_set *)vec_wi);
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    int     word = fd / NFDBITS;
 | 
			
		||||
    fd_mask mask = 1UL << (fd % NFDBITS);
 | 
			
		||||
 | 
			
		||||
    if (expect_false (vec_max <= word))
 | 
			
		||||
      {
 | 
			
		||||
        int new_max = word + 1;
 | 
			
		||||
 | 
			
		||||
        vec_ri = ev_realloc (vec_ri, new_max * NFDBYTES);
 | 
			
		||||
        vec_ro = ev_realloc (vec_ro, new_max * NFDBYTES); /* could free/malloc */
 | 
			
		||||
        vec_wi = ev_realloc (vec_wi, new_max * NFDBYTES);
 | 
			
		||||
        vec_wo = ev_realloc (vec_wo, new_max * NFDBYTES); /* could free/malloc */
 | 
			
		||||
        #ifdef _WIN32
 | 
			
		||||
        vec_eo = ev_realloc (vec_eo, new_max * NFDBYTES); /* could free/malloc */
 | 
			
		||||
        #endif
 | 
			
		||||
 | 
			
		||||
        for (; vec_max < new_max; ++vec_max)
 | 
			
		||||
          ((fd_mask *)vec_ri) [vec_max] =
 | 
			
		||||
          ((fd_mask *)vec_wi) [vec_max] = 0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    ((fd_mask *)vec_ri) [word] |= mask;
 | 
			
		||||
    if (!(nev & EV_READ))
 | 
			
		||||
      ((fd_mask *)vec_ri) [word] &= ~mask;
 | 
			
		||||
 | 
			
		||||
    ((fd_mask *)vec_wi) [word] |= mask;
 | 
			
		||||
    if (!(nev & EV_WRITE))
 | 
			
		||||
      ((fd_mask *)vec_wi) [word] &= ~mask;
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
select_poll (EV_P_ ev_tstamp timeout)
 | 
			
		||||
{
 | 
			
		||||
  struct timeval tv;
 | 
			
		||||
  int res;
 | 
			
		||||
  int fd_setsize;
 | 
			
		||||
 | 
			
		||||
  EV_RELEASE_CB;
 | 
			
		||||
  EV_TV_SET (tv, timeout);
 | 
			
		||||
 | 
			
		||||
#if EV_SELECT_USE_FD_SET
 | 
			
		||||
  fd_setsize = sizeof (fd_set);
 | 
			
		||||
#else
 | 
			
		||||
  fd_setsize = vec_max * NFDBYTES;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  memcpy (vec_ro, vec_ri, fd_setsize);
 | 
			
		||||
  memcpy (vec_wo, vec_wi, fd_setsize);
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
  /* pass in the write set as except set.
 | 
			
		||||
   * the idea behind this is to work around a windows bug that causes
 | 
			
		||||
   * errors to be reported as an exception and not by setting
 | 
			
		||||
   * the writable bit. this is so uncontrollably lame.
 | 
			
		||||
   */
 | 
			
		||||
  memcpy (vec_eo, vec_wi, fd_setsize);
 | 
			
		||||
  res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, (fd_set *)vec_eo, &tv);
 | 
			
		||||
#elif EV_SELECT_USE_FD_SET
 | 
			
		||||
  fd_setsize = anfdmax < FD_SETSIZE ? anfdmax : FD_SETSIZE;
 | 
			
		||||
  res = select (fd_setsize, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);
 | 
			
		||||
#else
 | 
			
		||||
  res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);
 | 
			
		||||
#endif
 | 
			
		||||
  EV_ACQUIRE_CB;
 | 
			
		||||
 | 
			
		||||
  if (expect_false (res < 0))
 | 
			
		||||
    {
 | 
			
		||||
      #if EV_SELECT_IS_WINSOCKET
 | 
			
		||||
      errno = WSAGetLastError ();
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef WSABASEERR
 | 
			
		||||
      /* on windows, select returns incompatible error codes, fix this */
 | 
			
		||||
      if (errno >= WSABASEERR && errno < WSABASEERR + 1000)
 | 
			
		||||
        if (errno == WSAENOTSOCK)
 | 
			
		||||
          errno = EBADF;
 | 
			
		||||
        else
 | 
			
		||||
          errno -= WSABASEERR;
 | 
			
		||||
      #endif
 | 
			
		||||
 | 
			
		||||
      #ifdef _WIN32
 | 
			
		||||
      /* select on windows erroneously returns EINVAL when no fd sets have been
 | 
			
		||||
       * provided (this is documented). what microsoft doesn't tell you that this bug
 | 
			
		||||
       * exists even when the fd sets _are_ provided, so we have to check for this bug
 | 
			
		||||
       * here and emulate by sleeping manually.
 | 
			
		||||
       * we also get EINVAL when the timeout is invalid, but we ignore this case here
 | 
			
		||||
       * and assume that EINVAL always means: you have to wait manually.
 | 
			
		||||
       */
 | 
			
		||||
      if (errno == EINVAL)
 | 
			
		||||
        {
 | 
			
		||||
          if (timeout)
 | 
			
		||||
            {
 | 
			
		||||
              unsigned long ms = timeout * 1e3;
 | 
			
		||||
              Sleep (ms ? ms : 1);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
      #endif
 | 
			
		||||
 | 
			
		||||
      if (errno == EBADF)
 | 
			
		||||
        fd_ebadf (EV_A);
 | 
			
		||||
      else if (errno == ENOMEM && !syserr_cb)
 | 
			
		||||
        fd_enomem (EV_A);
 | 
			
		||||
      else if (errno != EINTR)
 | 
			
		||||
        ev_syserr ("(libev) select");
 | 
			
		||||
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if EV_SELECT_USE_FD_SET
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    int fd;
 | 
			
		||||
 | 
			
		||||
    for (fd = 0; fd < anfdmax; ++fd)
 | 
			
		||||
      if (anfds [fd].events)
 | 
			
		||||
        {
 | 
			
		||||
          int events = 0;
 | 
			
		||||
          #if EV_SELECT_IS_WINSOCKET
 | 
			
		||||
          SOCKET handle = anfds [fd].handle;
 | 
			
		||||
          #else
 | 
			
		||||
          int handle = fd;
 | 
			
		||||
          #endif
 | 
			
		||||
 | 
			
		||||
          if (FD_ISSET (handle, (fd_set *)vec_ro)) events |= EV_READ;
 | 
			
		||||
          if (FD_ISSET (handle, (fd_set *)vec_wo)) events |= EV_WRITE;
 | 
			
		||||
          #ifdef _WIN32
 | 
			
		||||
          if (FD_ISSET (handle, (fd_set *)vec_eo)) events |= EV_WRITE;
 | 
			
		||||
          #endif
 | 
			
		||||
 | 
			
		||||
          if (expect_true (events))
 | 
			
		||||
            fd_event (EV_A_ fd, events);
 | 
			
		||||
        }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    int word, bit;
 | 
			
		||||
    for (word = vec_max; word--; )
 | 
			
		||||
      {
 | 
			
		||||
        fd_mask word_r = ((fd_mask *)vec_ro) [word];
 | 
			
		||||
        fd_mask word_w = ((fd_mask *)vec_wo) [word];
 | 
			
		||||
        #ifdef _WIN32
 | 
			
		||||
        word_w |= ((fd_mask *)vec_eo) [word];
 | 
			
		||||
        #endif
 | 
			
		||||
 | 
			
		||||
        if (word_r || word_w)
 | 
			
		||||
          for (bit = NFDBITS; bit--; )
 | 
			
		||||
            {
 | 
			
		||||
              fd_mask mask = 1UL << bit;
 | 
			
		||||
              int events = 0;
 | 
			
		||||
 | 
			
		||||
              events |= word_r & mask ? EV_READ  : 0;
 | 
			
		||||
              events |= word_w & mask ? EV_WRITE : 0;
 | 
			
		||||
 | 
			
		||||
              if (expect_true (events))
 | 
			
		||||
                fd_event (EV_A_ word * NFDBITS + bit, events);
 | 
			
		||||
            }
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline_size
 | 
			
		||||
int
 | 
			
		||||
select_init (EV_P_ int flags)
 | 
			
		||||
{
 | 
			
		||||
  backend_mintime = 1e-6;
 | 
			
		||||
  backend_modify  = select_modify;
 | 
			
		||||
  backend_poll    = select_poll;
 | 
			
		||||
 | 
			
		||||
#if EV_SELECT_USE_FD_SET
 | 
			
		||||
  vec_ri  = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_ri);
 | 
			
		||||
  vec_ro  = ev_malloc (sizeof (fd_set));
 | 
			
		||||
  vec_wi  = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_wi);
 | 
			
		||||
  vec_wo  = ev_malloc (sizeof (fd_set));
 | 
			
		||||
  #ifdef _WIN32
 | 
			
		||||
  vec_eo  = ev_malloc (sizeof (fd_set));
 | 
			
		||||
  #endif
 | 
			
		||||
#else
 | 
			
		||||
  vec_max = 0;
 | 
			
		||||
  vec_ri  = 0;
 | 
			
		||||
  vec_ro  = 0;
 | 
			
		||||
  vec_wi  = 0;
 | 
			
		||||
  vec_wo  = 0;
 | 
			
		||||
  #ifdef _WIN32
 | 
			
		||||
  vec_eo  = 0;
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  return EVBACKEND_SELECT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline_size
 | 
			
		||||
void
 | 
			
		||||
select_destroy (EV_P)
 | 
			
		||||
{
 | 
			
		||||
  ev_free (vec_ri);
 | 
			
		||||
  ev_free (vec_ro);
 | 
			
		||||
  ev_free (vec_wi);
 | 
			
		||||
  ev_free (vec_wo);
 | 
			
		||||
  #ifdef _WIN32
 | 
			
		||||
  ev_free (vec_eo);
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										204
									
								
								libev/ev_vars.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								libev/ev_vars.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,204 @@
 | 
			
		||||
/*
 | 
			
		||||
 * loop member variable declarations
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann <libev@schmorp.de>
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define VARx(type,name) VAR(name, type name)
 | 
			
		||||
 | 
			
		||||
VARx(ev_tstamp, now_floor) /* last time we refreshed rt_time */
 | 
			
		||||
VARx(ev_tstamp, mn_now)    /* monotonic clock "now" */
 | 
			
		||||
VARx(ev_tstamp, rtmn_diff) /* difference realtime - monotonic time */
 | 
			
		||||
 | 
			
		||||
/* for reverse feeding of events */
 | 
			
		||||
VARx(W *, rfeeds)
 | 
			
		||||
VARx(int, rfeedmax)
 | 
			
		||||
VARx(int, rfeedcnt)
 | 
			
		||||
 | 
			
		||||
VAR (pendings, ANPENDING *pendings [NUMPRI])
 | 
			
		||||
VAR (pendingmax, int pendingmax [NUMPRI])
 | 
			
		||||
VAR (pendingcnt, int pendingcnt [NUMPRI])
 | 
			
		||||
VARx(int, pendingpri) /* highest priority currently pending */
 | 
			
		||||
VARx(ev_prepare, pending_w) /* dummy pending watcher */
 | 
			
		||||
 | 
			
		||||
VARx(ev_tstamp, io_blocktime)
 | 
			
		||||
VARx(ev_tstamp, timeout_blocktime)
 | 
			
		||||
 | 
			
		||||
VARx(int, backend)
 | 
			
		||||
VARx(int, activecnt) /* total number of active events ("refcount") */
 | 
			
		||||
VARx(EV_ATOMIC_T, loop_done)  /* signal by ev_break */
 | 
			
		||||
 | 
			
		||||
VARx(int, backend_fd)
 | 
			
		||||
VARx(ev_tstamp, backend_mintime) /* assumed typical timer resolution */
 | 
			
		||||
VAR (backend_modify, void (*backend_modify)(EV_P_ int fd, int oev, int nev))
 | 
			
		||||
VAR (backend_poll  , void (*backend_poll)(EV_P_ ev_tstamp timeout))
 | 
			
		||||
 | 
			
		||||
VARx(ANFD *, anfds)
 | 
			
		||||
VARx(int, anfdmax)
 | 
			
		||||
 | 
			
		||||
VAR (evpipe, int evpipe [2])
 | 
			
		||||
VARx(ev_io, pipe_w)
 | 
			
		||||
VARx(EV_ATOMIC_T, pipe_write_wanted)
 | 
			
		||||
VARx(EV_ATOMIC_T, pipe_write_skipped)
 | 
			
		||||
 | 
			
		||||
#if !defined(_WIN32) || EV_GENWRAP
 | 
			
		||||
VARx(pid_t, curpid)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
VARx(char, postfork)  /* true if we need to recreate kernel state after fork */
 | 
			
		||||
 | 
			
		||||
#if EV_USE_SELECT || EV_GENWRAP
 | 
			
		||||
VARx(void *, vec_ri)
 | 
			
		||||
VARx(void *, vec_ro)
 | 
			
		||||
VARx(void *, vec_wi)
 | 
			
		||||
VARx(void *, vec_wo)
 | 
			
		||||
#if defined(_WIN32) || EV_GENWRAP
 | 
			
		||||
VARx(void *, vec_eo)
 | 
			
		||||
#endif
 | 
			
		||||
VARx(int, vec_max)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_USE_POLL || EV_GENWRAP
 | 
			
		||||
VARx(struct pollfd *, polls)
 | 
			
		||||
VARx(int, pollmax)
 | 
			
		||||
VARx(int, pollcnt)
 | 
			
		||||
VARx(int *, pollidxs) /* maps fds into structure indices */
 | 
			
		||||
VARx(int, pollidxmax)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_USE_EPOLL || EV_GENWRAP
 | 
			
		||||
VARx(struct epoll_event *, epoll_events)
 | 
			
		||||
VARx(int, epoll_eventmax)
 | 
			
		||||
VARx(int *, epoll_eperms)
 | 
			
		||||
VARx(int, epoll_epermcnt)
 | 
			
		||||
VARx(int, epoll_epermmax)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_USE_KQUEUE || EV_GENWRAP
 | 
			
		||||
VARx(pid_t, kqueue_fd_pid)
 | 
			
		||||
VARx(struct kevent *, kqueue_changes)
 | 
			
		||||
VARx(int, kqueue_changemax)
 | 
			
		||||
VARx(int, kqueue_changecnt)
 | 
			
		||||
VARx(struct kevent *, kqueue_events)
 | 
			
		||||
VARx(int, kqueue_eventmax)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_USE_PORT || EV_GENWRAP
 | 
			
		||||
VARx(struct port_event *, port_events)
 | 
			
		||||
VARx(int, port_eventmax)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_USE_IOCP || EV_GENWRAP
 | 
			
		||||
VARx(HANDLE, iocp)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
VARx(int *, fdchanges)
 | 
			
		||||
VARx(int, fdchangemax)
 | 
			
		||||
VARx(int, fdchangecnt)
 | 
			
		||||
 | 
			
		||||
VARx(ANHE *, timers)
 | 
			
		||||
VARx(int, timermax)
 | 
			
		||||
VARx(int, timercnt)
 | 
			
		||||
 | 
			
		||||
#if EV_PERIODIC_ENABLE || EV_GENWRAP
 | 
			
		||||
VARx(ANHE *, periodics)
 | 
			
		||||
VARx(int, periodicmax)
 | 
			
		||||
VARx(int, periodiccnt)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_IDLE_ENABLE || EV_GENWRAP
 | 
			
		||||
VAR (idles, ev_idle **idles [NUMPRI])
 | 
			
		||||
VAR (idlemax, int idlemax [NUMPRI])
 | 
			
		||||
VAR (idlecnt, int idlecnt [NUMPRI])
 | 
			
		||||
#endif
 | 
			
		||||
VARx(int, idleall) /* total number */
 | 
			
		||||
 | 
			
		||||
VARx(struct ev_prepare **, prepares)
 | 
			
		||||
VARx(int, preparemax)
 | 
			
		||||
VARx(int, preparecnt)
 | 
			
		||||
 | 
			
		||||
VARx(struct ev_check **, checks)
 | 
			
		||||
VARx(int, checkmax)
 | 
			
		||||
VARx(int, checkcnt)
 | 
			
		||||
 | 
			
		||||
#if EV_FORK_ENABLE || EV_GENWRAP
 | 
			
		||||
VARx(struct ev_fork **, forks)
 | 
			
		||||
VARx(int, forkmax)
 | 
			
		||||
VARx(int, forkcnt)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_CLEANUP_ENABLE || EV_GENWRAP
 | 
			
		||||
VARx(struct ev_cleanup **, cleanups)
 | 
			
		||||
VARx(int, cleanupmax)
 | 
			
		||||
VARx(int, cleanupcnt)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_ASYNC_ENABLE || EV_GENWRAP
 | 
			
		||||
VARx(EV_ATOMIC_T, async_pending)
 | 
			
		||||
VARx(struct ev_async **, asyncs)
 | 
			
		||||
VARx(int, asyncmax)
 | 
			
		||||
VARx(int, asynccnt)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_USE_INOTIFY || EV_GENWRAP
 | 
			
		||||
VARx(int, fs_fd)
 | 
			
		||||
VARx(ev_io, fs_w)
 | 
			
		||||
VARx(char, fs_2625) /* whether we are running in linux 2.6.25 or newer */
 | 
			
		||||
VAR (fs_hash, ANFS fs_hash [EV_INOTIFY_HASHSIZE])
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
VARx(EV_ATOMIC_T, sig_pending)
 | 
			
		||||
#if EV_USE_SIGNALFD || EV_GENWRAP
 | 
			
		||||
VARx(int, sigfd)
 | 
			
		||||
VARx(ev_io, sigfd_w)
 | 
			
		||||
VARx(sigset_t, sigfd_set)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
VARx(unsigned int, origflags) /* original loop flags */
 | 
			
		||||
 | 
			
		||||
#if EV_FEATURE_API || EV_GENWRAP
 | 
			
		||||
VARx(unsigned int, loop_count) /* total number of loop iterations/blocks */
 | 
			
		||||
VARx(unsigned int, loop_depth) /* #ev_run enters - #ev_run leaves */
 | 
			
		||||
 | 
			
		||||
VARx(void *, userdata)
 | 
			
		||||
/* C++ doesn't support the ev_loop_callback typedef here. stinks. */
 | 
			
		||||
VAR (release_cb, void (*release_cb)(EV_P) EV_THROW)
 | 
			
		||||
VAR (acquire_cb, void (*acquire_cb)(EV_P) EV_THROW)
 | 
			
		||||
VAR (invoke_cb , ev_loop_callback invoke_cb)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#undef VARx
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										162
									
								
								libev/ev_win32.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								libev/ev_win32.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,162 @@
 | 
			
		||||
/*
 | 
			
		||||
 * libev win32 compatibility cruft (_not_ a backend)
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2007,2008,2009 Marc Alexander Lehmann <libev@schmorp.de>
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
 | 
			
		||||
/* note: the comment below could not be substantiated, but what would I care */
 | 
			
		||||
/* MSDN says this is required to handle SIGFPE */
 | 
			
		||||
/* my wild guess would be that using something floating-pointy is required */
 | 
			
		||||
/* for the crt to do something about it */
 | 
			
		||||
volatile double SIGFPE_REQ = 0.0f;
 | 
			
		||||
 | 
			
		||||
static SOCKET
 | 
			
		||||
ev_tcp_socket (void)
 | 
			
		||||
{
 | 
			
		||||
#if EV_USE_WSASOCKET
 | 
			
		||||
  return WSASocket (AF_INET, SOCK_STREAM, 0, 0, 0, 0);
 | 
			
		||||
#else
 | 
			
		||||
  return socket (AF_INET, SOCK_STREAM, 0);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* oh, the humanity! */
 | 
			
		||||
static int
 | 
			
		||||
ev_pipe (int filedes [2])
 | 
			
		||||
{
 | 
			
		||||
  struct sockaddr_in addr = { 0 };
 | 
			
		||||
  int addr_size = sizeof (addr);
 | 
			
		||||
  struct sockaddr_in adr2;
 | 
			
		||||
  int adr2_size = sizeof (adr2);
 | 
			
		||||
  SOCKET listener;
 | 
			
		||||
  SOCKET sock [2] = { -1, -1 };
 | 
			
		||||
 | 
			
		||||
  if ((listener = ev_tcp_socket ()) == INVALID_SOCKET)
 | 
			
		||||
    return -1;
 | 
			
		||||
 | 
			
		||||
  addr.sin_family = AF_INET;
 | 
			
		||||
  addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
 | 
			
		||||
  addr.sin_port = 0;
 | 
			
		||||
 | 
			
		||||
  if (bind (listener, (struct sockaddr *)&addr, addr_size))
 | 
			
		||||
    goto fail;
 | 
			
		||||
 | 
			
		||||
  if (getsockname (listener, (struct sockaddr *)&addr, &addr_size))
 | 
			
		||||
    goto fail;
 | 
			
		||||
 | 
			
		||||
  if (listen (listener, 1))
 | 
			
		||||
    goto fail;
 | 
			
		||||
 | 
			
		||||
  if ((sock [0] = ev_tcp_socket ()) == INVALID_SOCKET)
 | 
			
		||||
    goto fail;
 | 
			
		||||
 | 
			
		||||
  if (connect (sock [0], (struct sockaddr *)&addr, addr_size))
 | 
			
		||||
    goto fail;
 | 
			
		||||
 | 
			
		||||
  /* TODO: returns INVALID_SOCKET on winsock accept, not < 0. fix it */
 | 
			
		||||
  /* when convenient, probably by just removing error checking altogether? */
 | 
			
		||||
  if ((sock [1] = accept (listener, 0, 0)) < 0)
 | 
			
		||||
    goto fail;
 | 
			
		||||
 | 
			
		||||
  /* windows vista returns fantasy port numbers for sockets:
 | 
			
		||||
   * example for two interconnected tcp sockets:
 | 
			
		||||
   *
 | 
			
		||||
   * (Socket::unpack_sockaddr_in getsockname $sock0)[0] == 53364
 | 
			
		||||
   * (Socket::unpack_sockaddr_in getpeername $sock0)[0] == 53363
 | 
			
		||||
   * (Socket::unpack_sockaddr_in getsockname $sock1)[0] == 53363
 | 
			
		||||
   * (Socket::unpack_sockaddr_in getpeername $sock1)[0] == 53365
 | 
			
		||||
   *
 | 
			
		||||
   * wow! tridirectional sockets!
 | 
			
		||||
   *
 | 
			
		||||
   * this way of checking ports seems to work:
 | 
			
		||||
   */
 | 
			
		||||
  if (getpeername (sock [0], (struct sockaddr *)&addr, &addr_size))
 | 
			
		||||
    goto fail;
 | 
			
		||||
 | 
			
		||||
  if (getsockname (sock [1], (struct sockaddr *)&adr2, &adr2_size))
 | 
			
		||||
    goto fail;
 | 
			
		||||
 | 
			
		||||
  errno = WSAEINVAL;
 | 
			
		||||
  if (addr_size != adr2_size
 | 
			
		||||
      || addr.sin_addr.s_addr != adr2.sin_addr.s_addr /* just to be sure, I mean, it's windows */
 | 
			
		||||
      || addr.sin_port        != adr2.sin_port)
 | 
			
		||||
    goto fail;
 | 
			
		||||
 | 
			
		||||
  closesocket (listener);
 | 
			
		||||
 | 
			
		||||
#if EV_SELECT_IS_WINSOCKET
 | 
			
		||||
  filedes [0] = EV_WIN32_HANDLE_TO_FD (sock [0]);
 | 
			
		||||
  filedes [1] = EV_WIN32_HANDLE_TO_FD (sock [1]);
 | 
			
		||||
#else
 | 
			
		||||
  /* when select isn't winsocket, we also expect socket, connect, accept etc.
 | 
			
		||||
   * to work on fds */
 | 
			
		||||
  filedes [0] = sock [0];
 | 
			
		||||
  filedes [1] = sock [1];
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
  closesocket (listener);
 | 
			
		||||
 | 
			
		||||
  if (sock [0] != INVALID_SOCKET) closesocket (sock [0]);
 | 
			
		||||
  if (sock [1] != INVALID_SOCKET) closesocket (sock [1]);
 | 
			
		||||
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#undef pipe
 | 
			
		||||
#define pipe(filedes) ev_pipe (filedes)
 | 
			
		||||
 | 
			
		||||
#define EV_HAVE_EV_TIME 1
 | 
			
		||||
ev_tstamp
 | 
			
		||||
ev_time (void)
 | 
			
		||||
{
 | 
			
		||||
  FILETIME ft;
 | 
			
		||||
  ULARGE_INTEGER ui;
 | 
			
		||||
 | 
			
		||||
  GetSystemTimeAsFileTime (&ft);
 | 
			
		||||
  ui.u.LowPart  = ft.dwLowDateTime;
 | 
			
		||||
  ui.u.HighPart = ft.dwHighDateTime;
 | 
			
		||||
 | 
			
		||||
  /* msvc cannot convert ulonglong to double... yes, it is that sucky */
 | 
			
		||||
  return (LONGLONG)(ui.QuadPart - 116444736000000000) * 1e-7;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										200
									
								
								libev/ev_wrap.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								libev/ev_wrap.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,200 @@
 | 
			
		||||
/* DO NOT EDIT, automatically generated by update_ev_wrap */
 | 
			
		||||
#ifndef EV_WRAP_H
 | 
			
		||||
#define EV_WRAP_H
 | 
			
		||||
#define acquire_cb ((loop)->acquire_cb)
 | 
			
		||||
#define activecnt ((loop)->activecnt)
 | 
			
		||||
#define anfdmax ((loop)->anfdmax)
 | 
			
		||||
#define anfds ((loop)->anfds)
 | 
			
		||||
#define async_pending ((loop)->async_pending)
 | 
			
		||||
#define asynccnt ((loop)->asynccnt)
 | 
			
		||||
#define asyncmax ((loop)->asyncmax)
 | 
			
		||||
#define asyncs ((loop)->asyncs)
 | 
			
		||||
#define backend ((loop)->backend)
 | 
			
		||||
#define backend_fd ((loop)->backend_fd)
 | 
			
		||||
#define backend_mintime ((loop)->backend_mintime)
 | 
			
		||||
#define backend_modify ((loop)->backend_modify)
 | 
			
		||||
#define backend_poll ((loop)->backend_poll)
 | 
			
		||||
#define checkcnt ((loop)->checkcnt)
 | 
			
		||||
#define checkmax ((loop)->checkmax)
 | 
			
		||||
#define checks ((loop)->checks)
 | 
			
		||||
#define cleanupcnt ((loop)->cleanupcnt)
 | 
			
		||||
#define cleanupmax ((loop)->cleanupmax)
 | 
			
		||||
#define cleanups ((loop)->cleanups)
 | 
			
		||||
#define curpid ((loop)->curpid)
 | 
			
		||||
#define epoll_epermcnt ((loop)->epoll_epermcnt)
 | 
			
		||||
#define epoll_epermmax ((loop)->epoll_epermmax)
 | 
			
		||||
#define epoll_eperms ((loop)->epoll_eperms)
 | 
			
		||||
#define epoll_eventmax ((loop)->epoll_eventmax)
 | 
			
		||||
#define epoll_events ((loop)->epoll_events)
 | 
			
		||||
#define evpipe ((loop)->evpipe)
 | 
			
		||||
#define fdchangecnt ((loop)->fdchangecnt)
 | 
			
		||||
#define fdchangemax ((loop)->fdchangemax)
 | 
			
		||||
#define fdchanges ((loop)->fdchanges)
 | 
			
		||||
#define forkcnt ((loop)->forkcnt)
 | 
			
		||||
#define forkmax ((loop)->forkmax)
 | 
			
		||||
#define forks ((loop)->forks)
 | 
			
		||||
#define fs_2625 ((loop)->fs_2625)
 | 
			
		||||
#define fs_fd ((loop)->fs_fd)
 | 
			
		||||
#define fs_hash ((loop)->fs_hash)
 | 
			
		||||
#define fs_w ((loop)->fs_w)
 | 
			
		||||
#define idleall ((loop)->idleall)
 | 
			
		||||
#define idlecnt ((loop)->idlecnt)
 | 
			
		||||
#define idlemax ((loop)->idlemax)
 | 
			
		||||
#define idles ((loop)->idles)
 | 
			
		||||
#define invoke_cb ((loop)->invoke_cb)
 | 
			
		||||
#define io_blocktime ((loop)->io_blocktime)
 | 
			
		||||
#define iocp ((loop)->iocp)
 | 
			
		||||
#define kqueue_changecnt ((loop)->kqueue_changecnt)
 | 
			
		||||
#define kqueue_changemax ((loop)->kqueue_changemax)
 | 
			
		||||
#define kqueue_changes ((loop)->kqueue_changes)
 | 
			
		||||
#define kqueue_eventmax ((loop)->kqueue_eventmax)
 | 
			
		||||
#define kqueue_events ((loop)->kqueue_events)
 | 
			
		||||
#define kqueue_fd_pid ((loop)->kqueue_fd_pid)
 | 
			
		||||
#define loop_count ((loop)->loop_count)
 | 
			
		||||
#define loop_depth ((loop)->loop_depth)
 | 
			
		||||
#define loop_done ((loop)->loop_done)
 | 
			
		||||
#define mn_now ((loop)->mn_now)
 | 
			
		||||
#define now_floor ((loop)->now_floor)
 | 
			
		||||
#define origflags ((loop)->origflags)
 | 
			
		||||
#define pending_w ((loop)->pending_w)
 | 
			
		||||
#define pendingcnt ((loop)->pendingcnt)
 | 
			
		||||
#define pendingmax ((loop)->pendingmax)
 | 
			
		||||
#define pendingpri ((loop)->pendingpri)
 | 
			
		||||
#define pendings ((loop)->pendings)
 | 
			
		||||
#define periodiccnt ((loop)->periodiccnt)
 | 
			
		||||
#define periodicmax ((loop)->periodicmax)
 | 
			
		||||
#define periodics ((loop)->periodics)
 | 
			
		||||
#define pipe_w ((loop)->pipe_w)
 | 
			
		||||
#define pipe_write_skipped ((loop)->pipe_write_skipped)
 | 
			
		||||
#define pipe_write_wanted ((loop)->pipe_write_wanted)
 | 
			
		||||
#define pollcnt ((loop)->pollcnt)
 | 
			
		||||
#define pollidxmax ((loop)->pollidxmax)
 | 
			
		||||
#define pollidxs ((loop)->pollidxs)
 | 
			
		||||
#define pollmax ((loop)->pollmax)
 | 
			
		||||
#define polls ((loop)->polls)
 | 
			
		||||
#define port_eventmax ((loop)->port_eventmax)
 | 
			
		||||
#define port_events ((loop)->port_events)
 | 
			
		||||
#define postfork ((loop)->postfork)
 | 
			
		||||
#define preparecnt ((loop)->preparecnt)
 | 
			
		||||
#define preparemax ((loop)->preparemax)
 | 
			
		||||
#define prepares ((loop)->prepares)
 | 
			
		||||
#define release_cb ((loop)->release_cb)
 | 
			
		||||
#define rfeedcnt ((loop)->rfeedcnt)
 | 
			
		||||
#define rfeedmax ((loop)->rfeedmax)
 | 
			
		||||
#define rfeeds ((loop)->rfeeds)
 | 
			
		||||
#define rtmn_diff ((loop)->rtmn_diff)
 | 
			
		||||
#define sig_pending ((loop)->sig_pending)
 | 
			
		||||
#define sigfd ((loop)->sigfd)
 | 
			
		||||
#define sigfd_set ((loop)->sigfd_set)
 | 
			
		||||
#define sigfd_w ((loop)->sigfd_w)
 | 
			
		||||
#define timeout_blocktime ((loop)->timeout_blocktime)
 | 
			
		||||
#define timercnt ((loop)->timercnt)
 | 
			
		||||
#define timermax ((loop)->timermax)
 | 
			
		||||
#define timers ((loop)->timers)
 | 
			
		||||
#define userdata ((loop)->userdata)
 | 
			
		||||
#define vec_eo ((loop)->vec_eo)
 | 
			
		||||
#define vec_max ((loop)->vec_max)
 | 
			
		||||
#define vec_ri ((loop)->vec_ri)
 | 
			
		||||
#define vec_ro ((loop)->vec_ro)
 | 
			
		||||
#define vec_wi ((loop)->vec_wi)
 | 
			
		||||
#define vec_wo ((loop)->vec_wo)
 | 
			
		||||
#else
 | 
			
		||||
#undef EV_WRAP_H
 | 
			
		||||
#undef acquire_cb
 | 
			
		||||
#undef activecnt
 | 
			
		||||
#undef anfdmax
 | 
			
		||||
#undef anfds
 | 
			
		||||
#undef async_pending
 | 
			
		||||
#undef asynccnt
 | 
			
		||||
#undef asyncmax
 | 
			
		||||
#undef asyncs
 | 
			
		||||
#undef backend
 | 
			
		||||
#undef backend_fd
 | 
			
		||||
#undef backend_mintime
 | 
			
		||||
#undef backend_modify
 | 
			
		||||
#undef backend_poll
 | 
			
		||||
#undef checkcnt
 | 
			
		||||
#undef checkmax
 | 
			
		||||
#undef checks
 | 
			
		||||
#undef cleanupcnt
 | 
			
		||||
#undef cleanupmax
 | 
			
		||||
#undef cleanups
 | 
			
		||||
#undef curpid
 | 
			
		||||
#undef epoll_epermcnt
 | 
			
		||||
#undef epoll_epermmax
 | 
			
		||||
#undef epoll_eperms
 | 
			
		||||
#undef epoll_eventmax
 | 
			
		||||
#undef epoll_events
 | 
			
		||||
#undef evpipe
 | 
			
		||||
#undef fdchangecnt
 | 
			
		||||
#undef fdchangemax
 | 
			
		||||
#undef fdchanges
 | 
			
		||||
#undef forkcnt
 | 
			
		||||
#undef forkmax
 | 
			
		||||
#undef forks
 | 
			
		||||
#undef fs_2625
 | 
			
		||||
#undef fs_fd
 | 
			
		||||
#undef fs_hash
 | 
			
		||||
#undef fs_w
 | 
			
		||||
#undef idleall
 | 
			
		||||
#undef idlecnt
 | 
			
		||||
#undef idlemax
 | 
			
		||||
#undef idles
 | 
			
		||||
#undef invoke_cb
 | 
			
		||||
#undef io_blocktime
 | 
			
		||||
#undef iocp
 | 
			
		||||
#undef kqueue_changecnt
 | 
			
		||||
#undef kqueue_changemax
 | 
			
		||||
#undef kqueue_changes
 | 
			
		||||
#undef kqueue_eventmax
 | 
			
		||||
#undef kqueue_events
 | 
			
		||||
#undef kqueue_fd_pid
 | 
			
		||||
#undef loop_count
 | 
			
		||||
#undef loop_depth
 | 
			
		||||
#undef loop_done
 | 
			
		||||
#undef mn_now
 | 
			
		||||
#undef now_floor
 | 
			
		||||
#undef origflags
 | 
			
		||||
#undef pending_w
 | 
			
		||||
#undef pendingcnt
 | 
			
		||||
#undef pendingmax
 | 
			
		||||
#undef pendingpri
 | 
			
		||||
#undef pendings
 | 
			
		||||
#undef periodiccnt
 | 
			
		||||
#undef periodicmax
 | 
			
		||||
#undef periodics
 | 
			
		||||
#undef pipe_w
 | 
			
		||||
#undef pipe_write_skipped
 | 
			
		||||
#undef pipe_write_wanted
 | 
			
		||||
#undef pollcnt
 | 
			
		||||
#undef pollidxmax
 | 
			
		||||
#undef pollidxs
 | 
			
		||||
#undef pollmax
 | 
			
		||||
#undef polls
 | 
			
		||||
#undef port_eventmax
 | 
			
		||||
#undef port_events
 | 
			
		||||
#undef postfork
 | 
			
		||||
#undef preparecnt
 | 
			
		||||
#undef preparemax
 | 
			
		||||
#undef prepares
 | 
			
		||||
#undef release_cb
 | 
			
		||||
#undef rfeedcnt
 | 
			
		||||
#undef rfeedmax
 | 
			
		||||
#undef rfeeds
 | 
			
		||||
#undef rtmn_diff
 | 
			
		||||
#undef sig_pending
 | 
			
		||||
#undef sigfd
 | 
			
		||||
#undef sigfd_set
 | 
			
		||||
#undef sigfd_w
 | 
			
		||||
#undef timeout_blocktime
 | 
			
		||||
#undef timercnt
 | 
			
		||||
#undef timermax
 | 
			
		||||
#undef timers
 | 
			
		||||
#undef userdata
 | 
			
		||||
#undef vec_eo
 | 
			
		||||
#undef vec_max
 | 
			
		||||
#undef vec_ri
 | 
			
		||||
#undef vec_ro
 | 
			
		||||
#undef vec_wi
 | 
			
		||||
#undef vec_wo
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										425
									
								
								libev/event.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										425
									
								
								libev/event.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,425 @@
 | 
			
		||||
/*
 | 
			
		||||
 * libevent compatibility layer
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2007,2008,2009,2010,2012 Marc Alexander Lehmann <libev@schmorp.de>
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#ifdef EV_EVENT_H
 | 
			
		||||
# include EV_EVENT_H
 | 
			
		||||
#else
 | 
			
		||||
# include "event.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EV_MULTIPLICITY
 | 
			
		||||
# define dLOOPev struct ev_loop *loop = (struct ev_loop *)ev->ev_base
 | 
			
		||||
# define dLOOPbase struct ev_loop *loop = (struct ev_loop *)base
 | 
			
		||||
#else
 | 
			
		||||
# define dLOOPev
 | 
			
		||||
# define dLOOPbase
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* never accessed, will always be cast from/to ev_loop */
 | 
			
		||||
struct event_base
 | 
			
		||||
{
 | 
			
		||||
  int dummy;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct event_base *ev_x_cur;
 | 
			
		||||
 | 
			
		||||
static ev_tstamp
 | 
			
		||||
ev_tv_get (struct timeval *tv)
 | 
			
		||||
{
 | 
			
		||||
  if (tv)
 | 
			
		||||
    {
 | 
			
		||||
      ev_tstamp after = tv->tv_sec + tv->tv_usec * 1e-6;
 | 
			
		||||
      return after ? after : 1e-6;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    return -1.;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define EVENT_STRINGIFY(s) # s
 | 
			
		||||
#define EVENT_VERSION(a,b) EVENT_STRINGIFY (a) "." EVENT_STRINGIFY (b)
 | 
			
		||||
 | 
			
		||||
const char *
 | 
			
		||||
event_get_version (void)
 | 
			
		||||
{
 | 
			
		||||
  /* returns ABI, not API or library, version */
 | 
			
		||||
  return EVENT_VERSION (EV_VERSION_MAJOR, EV_VERSION_MINOR);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *
 | 
			
		||||
event_get_method (void)
 | 
			
		||||
{
 | 
			
		||||
  return "libev";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *event_init (void)
 | 
			
		||||
{
 | 
			
		||||
#if EV_MULTIPLICITY
 | 
			
		||||
  if (ev_x_cur)
 | 
			
		||||
    ev_x_cur = (struct event_base *)ev_loop_new (EVFLAG_AUTO);
 | 
			
		||||
  else
 | 
			
		||||
    ev_x_cur = (struct event_base *)ev_default_loop (EVFLAG_AUTO);
 | 
			
		||||
#else
 | 
			
		||||
  assert (("libev: multiple event bases not supported when not compiled with EV_MULTIPLICITY", !ev_x_cur));
 | 
			
		||||
 | 
			
		||||
  ev_x_cur = (struct event_base *)(long)ev_default_loop (EVFLAG_AUTO);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  return ev_x_cur;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *
 | 
			
		||||
event_base_get_method (const struct event_base *base)
 | 
			
		||||
{
 | 
			
		||||
  return "libev";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct event_base *
 | 
			
		||||
event_base_new (void)
 | 
			
		||||
{
 | 
			
		||||
#if EV_MULTIPLICITY
 | 
			
		||||
  return (struct event_base *)ev_loop_new (EVFLAG_AUTO);
 | 
			
		||||
#else
 | 
			
		||||
  assert (("libev: multiple event bases not supported when not compiled with EV_MULTIPLICITY"));
 | 
			
		||||
  return NULL;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void event_base_free (struct event_base *base)
 | 
			
		||||
{
 | 
			
		||||
  dLOOPbase;
 | 
			
		||||
 | 
			
		||||
#if EV_MULTIPLICITY
 | 
			
		||||
  if (!ev_is_default_loop (loop))
 | 
			
		||||
    ev_loop_destroy (loop);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int event_dispatch (void)
 | 
			
		||||
{
 | 
			
		||||
  return event_base_dispatch (ev_x_cur);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef EV_STANDALONE
 | 
			
		||||
void event_set_log_callback (event_log_cb cb)
 | 
			
		||||
{
 | 
			
		||||
  /* nop */
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int event_loop (int flags)
 | 
			
		||||
{
 | 
			
		||||
  return event_base_loop (ev_x_cur, flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int event_loopexit (struct timeval *tv)
 | 
			
		||||
{
 | 
			
		||||
  return event_base_loopexit (ev_x_cur, tv);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
event_callback_fn event_get_callback
 | 
			
		||||
(const struct event *ev)
 | 
			
		||||
{
 | 
			
		||||
  return ev->ev_callback;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
ev_x_cb (struct event *ev, int revents)
 | 
			
		||||
{
 | 
			
		||||
  revents &= EV_READ | EV_WRITE | EV_TIMER | EV_SIGNAL;
 | 
			
		||||
 | 
			
		||||
  ev->ev_res = revents;
 | 
			
		||||
  ev->ev_callback (ev->ev_fd, (short)revents, ev->ev_arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
ev_x_cb_sig (EV_P_ struct ev_signal *w, int revents)
 | 
			
		||||
{
 | 
			
		||||
  struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, iosig.sig));
 | 
			
		||||
 | 
			
		||||
  if (revents & EV_ERROR)
 | 
			
		||||
    event_del (ev);
 | 
			
		||||
 | 
			
		||||
  ev_x_cb (ev, revents);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
ev_x_cb_io (EV_P_ struct ev_io *w, int revents)
 | 
			
		||||
{
 | 
			
		||||
  struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, iosig.io));
 | 
			
		||||
 | 
			
		||||
  if ((revents & EV_ERROR) || !(ev->ev_events & EV_PERSIST))
 | 
			
		||||
    event_del (ev);
 | 
			
		||||
 | 
			
		||||
  ev_x_cb (ev, revents);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
ev_x_cb_to (EV_P_ struct ev_timer *w, int revents)
 | 
			
		||||
{
 | 
			
		||||
  struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, to));
 | 
			
		||||
 | 
			
		||||
  event_del (ev);
 | 
			
		||||
 | 
			
		||||
  ev_x_cb (ev, revents);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void event_set (struct event *ev, int fd, short events, void (*cb)(int, short, void *), void *arg)
 | 
			
		||||
{
 | 
			
		||||
  if (events & EV_SIGNAL)
 | 
			
		||||
    ev_init (&ev->iosig.sig, ev_x_cb_sig);
 | 
			
		||||
  else
 | 
			
		||||
    ev_init (&ev->iosig.io, ev_x_cb_io);
 | 
			
		||||
 | 
			
		||||
  ev_init (&ev->to, ev_x_cb_to);
 | 
			
		||||
 | 
			
		||||
  ev->ev_base     = ev_x_cur; /* not threadsafe, but it's how libevent works */
 | 
			
		||||
  ev->ev_fd       = fd;
 | 
			
		||||
  ev->ev_events   = events;
 | 
			
		||||
  ev->ev_pri      = 0;
 | 
			
		||||
  ev->ev_callback = cb;
 | 
			
		||||
  ev->ev_arg      = arg;
 | 
			
		||||
  ev->ev_res      = 0;
 | 
			
		||||
  ev->ev_flags    = EVLIST_INIT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int event_once (int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv)
 | 
			
		||||
{
 | 
			
		||||
  return event_base_once (ev_x_cur, fd, events, cb, arg, tv);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int event_add (struct event *ev, struct timeval *tv)
 | 
			
		||||
{
 | 
			
		||||
  dLOOPev;
 | 
			
		||||
 | 
			
		||||
  if (ev->ev_events & EV_SIGNAL)
 | 
			
		||||
    {
 | 
			
		||||
      if (!ev_is_active (&ev->iosig.sig))
 | 
			
		||||
        {
 | 
			
		||||
          ev_signal_set (&ev->iosig.sig, ev->ev_fd);
 | 
			
		||||
          ev_signal_start (EV_A_ &ev->iosig.sig);
 | 
			
		||||
 | 
			
		||||
          ev->ev_flags |= EVLIST_SIGNAL;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else if (ev->ev_events & (EV_READ | EV_WRITE))
 | 
			
		||||
    {
 | 
			
		||||
      if (!ev_is_active (&ev->iosig.io))
 | 
			
		||||
        {
 | 
			
		||||
          ev_io_set (&ev->iosig.io, ev->ev_fd, ev->ev_events & (EV_READ | EV_WRITE));
 | 
			
		||||
          ev_io_start (EV_A_ &ev->iosig.io);
 | 
			
		||||
 | 
			
		||||
          ev->ev_flags |= EVLIST_INSERTED;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (tv)
 | 
			
		||||
    {
 | 
			
		||||
      ev->to.repeat = ev_tv_get (tv);
 | 
			
		||||
      ev_timer_again (EV_A_ &ev->to);
 | 
			
		||||
      ev->ev_flags |= EVLIST_TIMEOUT;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      ev_timer_stop (EV_A_ &ev->to);
 | 
			
		||||
      ev->ev_flags &= ~EVLIST_TIMEOUT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  ev->ev_flags |= EVLIST_ACTIVE;
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int event_del (struct event *ev)
 | 
			
		||||
{
 | 
			
		||||
  dLOOPev;
 | 
			
		||||
 | 
			
		||||
  if (ev->ev_events & EV_SIGNAL)
 | 
			
		||||
    ev_signal_stop (EV_A_ &ev->iosig.sig);
 | 
			
		||||
  else if (ev->ev_events & (EV_READ | EV_WRITE))
 | 
			
		||||
    ev_io_stop (EV_A_ &ev->iosig.io);
 | 
			
		||||
 | 
			
		||||
  if (ev_is_active (&ev->to))
 | 
			
		||||
    ev_timer_stop (EV_A_ &ev->to);
 | 
			
		||||
 | 
			
		||||
  ev->ev_flags = EVLIST_INIT;
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void event_active (struct event *ev, int res, short ncalls)
 | 
			
		||||
{
 | 
			
		||||
  dLOOPev;
 | 
			
		||||
 | 
			
		||||
  if (res & EV_TIMEOUT)
 | 
			
		||||
    ev_feed_event (EV_A_ &ev->to, res & EV_TIMEOUT);
 | 
			
		||||
 | 
			
		||||
  if (res & EV_SIGNAL)
 | 
			
		||||
    ev_feed_event (EV_A_ &ev->iosig.sig, res & EV_SIGNAL);
 | 
			
		||||
 | 
			
		||||
  if (res & (EV_READ | EV_WRITE))
 | 
			
		||||
    ev_feed_event (EV_A_ &ev->iosig.io, res & (EV_READ | EV_WRITE));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int event_pending (struct event *ev, short events, struct timeval *tv)
 | 
			
		||||
{
 | 
			
		||||
  short revents = 0;
 | 
			
		||||
  dLOOPev;
 | 
			
		||||
 | 
			
		||||
  if (ev->ev_events & EV_SIGNAL)
 | 
			
		||||
    {
 | 
			
		||||
      /* sig */
 | 
			
		||||
      if (ev_is_active (&ev->iosig.sig) || ev_is_pending (&ev->iosig.sig))
 | 
			
		||||
        revents |= EV_SIGNAL;
 | 
			
		||||
    }
 | 
			
		||||
  else if (ev->ev_events & (EV_READ | EV_WRITE))
 | 
			
		||||
    {
 | 
			
		||||
      /* io */
 | 
			
		||||
      if (ev_is_active (&ev->iosig.io) || ev_is_pending (&ev->iosig.io))
 | 
			
		||||
        revents |= ev->ev_events & (EV_READ | EV_WRITE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (ev->ev_events & EV_TIMEOUT || ev_is_active (&ev->to) || ev_is_pending (&ev->to))
 | 
			
		||||
    {
 | 
			
		||||
      revents |= EV_TIMEOUT;
 | 
			
		||||
 | 
			
		||||
      if (tv)
 | 
			
		||||
        {
 | 
			
		||||
          ev_tstamp at = ev_now (EV_A);
 | 
			
		||||
 | 
			
		||||
          tv->tv_sec  = (long)at;
 | 
			
		||||
          tv->tv_usec = (long)((at - (ev_tstamp)tv->tv_sec) * 1e6);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return events & revents;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int event_priority_init (int npri)
 | 
			
		||||
{
 | 
			
		||||
  return event_base_priority_init (ev_x_cur, npri);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int event_priority_set (struct event *ev, int pri)
 | 
			
		||||
{
 | 
			
		||||
  ev->ev_pri = pri;
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int event_base_set (struct event_base *base, struct event *ev)
 | 
			
		||||
{
 | 
			
		||||
  ev->ev_base = base;
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int event_base_loop (struct event_base *base, int flags)
 | 
			
		||||
{
 | 
			
		||||
  dLOOPbase;
 | 
			
		||||
 | 
			
		||||
  return !ev_run (EV_A_ flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int event_base_dispatch (struct event_base *base)
 | 
			
		||||
{
 | 
			
		||||
  return event_base_loop (base, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
ev_x_loopexit_cb (int revents, void *base)
 | 
			
		||||
{
 | 
			
		||||
  dLOOPbase;
 | 
			
		||||
 | 
			
		||||
  ev_break (EV_A_ EVBREAK_ONE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int event_base_loopexit (struct event_base *base, struct timeval *tv)
 | 
			
		||||
{
 | 
			
		||||
  ev_tstamp after = ev_tv_get (tv);
 | 
			
		||||
  dLOOPbase;
 | 
			
		||||
 | 
			
		||||
  ev_once (EV_A_ -1, 0, after >= 0. ? after : 0., ev_x_loopexit_cb, (void *)base);
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct ev_x_once
 | 
			
		||||
{
 | 
			
		||||
  int fd;
 | 
			
		||||
  void (*cb)(int, short, void *);
 | 
			
		||||
  void *arg;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
ev_x_once_cb (int revents, void *arg)
 | 
			
		||||
{
 | 
			
		||||
  struct ev_x_once *once = (struct ev_x_once *)arg;
 | 
			
		||||
 | 
			
		||||
  once->cb (once->fd, (short)revents, once->arg);
 | 
			
		||||
  free (once);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int event_base_once (struct event_base *base, int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv)
 | 
			
		||||
{
 | 
			
		||||
  struct ev_x_once *once = (struct ev_x_once *)malloc (sizeof (struct ev_x_once));
 | 
			
		||||
  dLOOPbase;
 | 
			
		||||
 | 
			
		||||
  if (!once)
 | 
			
		||||
    return -1;
 | 
			
		||||
 | 
			
		||||
  once->fd  = fd;
 | 
			
		||||
  once->cb  = cb;
 | 
			
		||||
  once->arg = arg;
 | 
			
		||||
 | 
			
		||||
  ev_once (EV_A_ fd, events & (EV_READ | EV_WRITE), ev_tv_get (tv), ev_x_once_cb, (void *)once);
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int event_base_priority_init (struct event_base *base, int npri)
 | 
			
		||||
{
 | 
			
		||||
  /*dLOOPbase;*/
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										177
									
								
								libev/event.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								libev/event.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,177 @@
 | 
			
		||||
/*
 | 
			
		||||
 * libevent compatibility header, only core events supported
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2007,2008,2010,2012 Marc Alexander Lehmann <libev@schmorp.de>
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef EVENT_H_
 | 
			
		||||
#define EVENT_H_
 | 
			
		||||
 | 
			
		||||
#ifdef EV_H
 | 
			
		||||
# include EV_H
 | 
			
		||||
#else
 | 
			
		||||
# include "ev.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EVLOOP_NONBLOCK
 | 
			
		||||
# define EVLOOP_NONBLOCK EVRUN_NOWAIT
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EVLOOP_ONESHOT
 | 
			
		||||
# define EVLOOP_ONESHOT EVRUN_ONCE
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EV_TIMEOUT
 | 
			
		||||
# define EV_TIMEOUT EV_TIMER
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* we need sys/time.h for struct timeval only */
 | 
			
		||||
#if !defined (WIN32) || defined (__MINGW32__)
 | 
			
		||||
# include <time.h> /* mingw seems to need this, for whatever reason */
 | 
			
		||||
# include <sys/time.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct event_base;
 | 
			
		||||
 | 
			
		||||
#define EVLIST_TIMEOUT  0x01
 | 
			
		||||
#define EVLIST_INSERTED 0x02
 | 
			
		||||
#define EVLIST_SIGNAL   0x04
 | 
			
		||||
#define EVLIST_ACTIVE   0x08
 | 
			
		||||
#define EVLIST_INTERNAL 0x10
 | 
			
		||||
#define EVLIST_INIT     0x80
 | 
			
		||||
 | 
			
		||||
typedef void (*event_callback_fn)(int, short, void *);
 | 
			
		||||
 | 
			
		||||
struct event
 | 
			
		||||
{
 | 
			
		||||
  /* libev watchers we map onto */
 | 
			
		||||
  union {
 | 
			
		||||
    struct ev_io io;
 | 
			
		||||
    struct ev_signal sig;
 | 
			
		||||
  } iosig;
 | 
			
		||||
  struct ev_timer to;
 | 
			
		||||
 | 
			
		||||
  /* compatibility slots */
 | 
			
		||||
  struct event_base *ev_base;
 | 
			
		||||
  event_callback_fn ev_callback;
 | 
			
		||||
  void *ev_arg;
 | 
			
		||||
  int ev_fd;
 | 
			
		||||
  int ev_pri;
 | 
			
		||||
  int ev_res;
 | 
			
		||||
  int ev_flags;
 | 
			
		||||
  short ev_events;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
event_callback_fn event_get_callback (const struct event *ev);
 | 
			
		||||
 | 
			
		||||
#define EV_READ                    EV_READ
 | 
			
		||||
#define EV_WRITE                   EV_WRITE
 | 
			
		||||
#define EV_PERSIST                 0x10
 | 
			
		||||
#define EV_ET                      0x20 /* nop */
 | 
			
		||||
 | 
			
		||||
#define EVENT_SIGNAL(ev)           ((int) (ev)->ev_fd)
 | 
			
		||||
#define EVENT_FD(ev)               ((int) (ev)->ev_fd)
 | 
			
		||||
 | 
			
		||||
#define event_initialized(ev)      ((ev)->ev_flags & EVLIST_INIT)
 | 
			
		||||
 | 
			
		||||
#define evtimer_add(ev,tv)         event_add (ev, tv)
 | 
			
		||||
#define evtimer_set(ev,cb,data)    event_set (ev, -1, 0, cb, data)
 | 
			
		||||
#define evtimer_del(ev)            event_del (ev)
 | 
			
		||||
#define evtimer_pending(ev,tv)     event_pending (ev, EV_TIMEOUT, tv)
 | 
			
		||||
#define evtimer_initialized(ev)    event_initialized (ev)
 | 
			
		||||
 | 
			
		||||
#define timeout_add(ev,tv)         evtimer_add (ev, tv)
 | 
			
		||||
#define timeout_set(ev,cb,data)    evtimer_set (ev, cb, data)
 | 
			
		||||
#define timeout_del(ev)            evtimer_del (ev)
 | 
			
		||||
#define timeout_pending(ev,tv)     evtimer_pending (ev, tv)
 | 
			
		||||
#define timeout_initialized(ev)    evtimer_initialized (ev)
 | 
			
		||||
 | 
			
		||||
#define signal_add(ev,tv)          event_add (ev, tv)
 | 
			
		||||
#define signal_set(ev,sig,cb,data) event_set (ev, sig, EV_SIGNAL | EV_PERSIST, cb, data)
 | 
			
		||||
#define signal_del(ev)             event_del (ev)
 | 
			
		||||
#define signal_pending(ev,tv)      event_pending (ev, EV_SIGNAL, tv)
 | 
			
		||||
#define signal_initialized(ev)     event_initialized (ev)
 | 
			
		||||
 | 
			
		||||
const char *event_get_version (void);
 | 
			
		||||
const char *event_get_method (void);
 | 
			
		||||
 | 
			
		||||
void *event_init (void);
 | 
			
		||||
void event_base_free (struct event_base *base);
 | 
			
		||||
 | 
			
		||||
#define EVLOOP_ONCE      EVLOOP_ONESHOT
 | 
			
		||||
int event_loop (int);
 | 
			
		||||
int event_loopexit (struct timeval *tv);
 | 
			
		||||
int event_dispatch (void);
 | 
			
		||||
 | 
			
		||||
#define _EVENT_LOG_DEBUG 0
 | 
			
		||||
#define _EVENT_LOG_MSG   1
 | 
			
		||||
#define _EVENT_LOG_WARN  2
 | 
			
		||||
#define _EVENT_LOG_ERR   3
 | 
			
		||||
typedef void (*event_log_cb)(int severity, const char *msg);
 | 
			
		||||
void event_set_log_callback(event_log_cb cb);
 | 
			
		||||
 | 
			
		||||
void event_set (struct event *ev, int fd, short events, void (*cb)(int, short, void *), void *arg);
 | 
			
		||||
int event_once (int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv);
 | 
			
		||||
 | 
			
		||||
int event_add (struct event *ev, struct timeval *tv);
 | 
			
		||||
int event_del (struct event *ev);
 | 
			
		||||
void event_active (struct event *ev, int res, short ncalls); /* ncalls is being ignored */
 | 
			
		||||
 | 
			
		||||
int event_pending (struct event *ev, short, struct timeval *tv);
 | 
			
		||||
 | 
			
		||||
int event_priority_init (int npri);
 | 
			
		||||
int event_priority_set (struct event *ev, int pri);
 | 
			
		||||
 | 
			
		||||
struct event_base *event_base_new (void);
 | 
			
		||||
const char *event_base_get_method (const struct event_base *);
 | 
			
		||||
int event_base_set (struct event_base *base, struct event *ev);
 | 
			
		||||
int event_base_loop (struct event_base *base, int);
 | 
			
		||||
int event_base_loopexit (struct event_base *base, struct timeval *tv);
 | 
			
		||||
int event_base_dispatch (struct event_base *base);
 | 
			
		||||
int event_base_once (struct event_base *base, int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv);
 | 
			
		||||
int event_base_priority_init (struct event_base *base, int fd);
 | 
			
		||||
 | 
			
		||||
/* next line is different in the libevent+libev version */
 | 
			
		||||
/*libevent-include*/
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										226
									
								
								libev/event_compat.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										226
									
								
								libev/event_compat.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,226 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2000-2004 Niels Provos <provos@citi.umich.edu>
 | 
			
		||||
 * Copyright (c) 2008      Marc Alexander Lehmann <libev@schmorp.de>
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, 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.
 | 
			
		||||
 * 3. The name of the author may not be used to endorse or promote products
 | 
			
		||||
 *    derived from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 | 
			
		||||
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | 
			
		||||
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 | 
			
		||||
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
 * INCIDENTAL, SPECIAL, 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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 | 
			
		||||
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
# define WIN32_LEAN_AND_MEAN
 | 
			
		||||
# include <windows.h>
 | 
			
		||||
# undef WIN32_LEAN_AND_MEAN
 | 
			
		||||
typedef unsigned char u_char;
 | 
			
		||||
typedef unsigned short u_short;
 | 
			
		||||
#else
 | 
			
		||||
# include <sys/types.h>
 | 
			
		||||
# include <sys/time.h>
 | 
			
		||||
# include <inttypes.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
 | 
			
		||||
/* Fix so that ppl dont have to run with <sys/queue.h> */
 | 
			
		||||
#ifndef TAILQ_ENTRY
 | 
			
		||||
#define _EVENT_DEFINED_TQENTRY
 | 
			
		||||
#define TAILQ_ENTRY(type)						\
 | 
			
		||||
struct {								\
 | 
			
		||||
	struct type *tqe_next;	/* next element */			\
 | 
			
		||||
	struct type **tqe_prev;	/* address of previous next element */	\
 | 
			
		||||
}
 | 
			
		||||
#endif /* !TAILQ_ENTRY */
 | 
			
		||||
#ifndef RB_ENTRY
 | 
			
		||||
#define _EVENT_DEFINED_RBENTRY
 | 
			
		||||
#define RB_ENTRY(type)							\
 | 
			
		||||
struct {								\
 | 
			
		||||
	struct type *rbe_left;		/* left element */		\
 | 
			
		||||
	struct type *rbe_right;		/* right element */		\
 | 
			
		||||
	struct type *rbe_parent;	/* parent element */		\
 | 
			
		||||
	int rbe_color;			/* node color */		\
 | 
			
		||||
}
 | 
			
		||||
#endif /* !RB_ENTRY */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Key-Value pairs.  Can be used for HTTP headers but also for
 | 
			
		||||
 * query argument parsing.
 | 
			
		||||
 */
 | 
			
		||||
struct evkeyval {
 | 
			
		||||
	TAILQ_ENTRY(evkeyval) next;
 | 
			
		||||
 | 
			
		||||
	char *key;
 | 
			
		||||
	char *value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef _EVENT_DEFINED_TQENTRY
 | 
			
		||||
#undef TAILQ_ENTRY
 | 
			
		||||
struct event_list;
 | 
			
		||||
struct evkeyvalq;
 | 
			
		||||
#undef _EVENT_DEFINED_TQENTRY
 | 
			
		||||
#else
 | 
			
		||||
TAILQ_HEAD (event_list, event);
 | 
			
		||||
TAILQ_HEAD (evkeyvalq, evkeyval);
 | 
			
		||||
#endif /* _EVENT_DEFINED_TQENTRY */
 | 
			
		||||
#ifdef _EVENT_DEFINED_RBENTRY
 | 
			
		||||
#undef RB_ENTRY
 | 
			
		||||
#undef _EVENT_DEFINED_RBENTRY
 | 
			
		||||
#endif /* _EVENT_DEFINED_RBENTRY */
 | 
			
		||||
 | 
			
		||||
struct eventop {
 | 
			
		||||
	char *name;
 | 
			
		||||
	void *(*init)(struct event_base *);
 | 
			
		||||
	int (*add)(void *, struct event *);
 | 
			
		||||
	int (*del)(void *, struct event *);
 | 
			
		||||
	int (*recalc)(struct event_base *, void *, int);
 | 
			
		||||
	int (*dispatch)(struct event_base *, void *, struct timeval *);
 | 
			
		||||
	void (*dealloc)(struct event_base *, void *);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* These functions deal with buffering input and output */
 | 
			
		||||
 | 
			
		||||
struct evbuffer {
 | 
			
		||||
	u_char *buffer;
 | 
			
		||||
	u_char *orig_buffer;
 | 
			
		||||
 | 
			
		||||
	size_t misalign;
 | 
			
		||||
	size_t totallen;
 | 
			
		||||
	size_t off;
 | 
			
		||||
 | 
			
		||||
	void (*cb)(struct evbuffer *, size_t, size_t, void *);
 | 
			
		||||
	void *cbarg;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Just for error reporting - use other constants otherwise */
 | 
			
		||||
#define EVBUFFER_READ		0x01
 | 
			
		||||
#define EVBUFFER_WRITE		0x02
 | 
			
		||||
#define EVBUFFER_EOF		0x10
 | 
			
		||||
#define EVBUFFER_ERROR		0x20
 | 
			
		||||
#define EVBUFFER_TIMEOUT	0x40
 | 
			
		||||
 | 
			
		||||
struct bufferevent;
 | 
			
		||||
typedef void (*evbuffercb)(struct bufferevent *, void *);
 | 
			
		||||
typedef void (*everrorcb)(struct bufferevent *, short what, void *);
 | 
			
		||||
 | 
			
		||||
struct event_watermark {
 | 
			
		||||
	size_t low;
 | 
			
		||||
	size_t high;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct bufferevent {
 | 
			
		||||
	struct event ev_read;
 | 
			
		||||
	struct event ev_write;
 | 
			
		||||
 | 
			
		||||
	struct evbuffer *input;
 | 
			
		||||
	struct evbuffer *output;
 | 
			
		||||
 | 
			
		||||
	struct event_watermark wm_read;
 | 
			
		||||
	struct event_watermark wm_write;
 | 
			
		||||
 | 
			
		||||
	evbuffercb readcb;
 | 
			
		||||
	evbuffercb writecb;
 | 
			
		||||
	everrorcb errorcb;
 | 
			
		||||
	void *cbarg;
 | 
			
		||||
 | 
			
		||||
	int timeout_read;	/* in seconds */
 | 
			
		||||
	int timeout_write;	/* in seconds */
 | 
			
		||||
 | 
			
		||||
	short enabled;	/* events that are currently enabled */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct bufferevent *bufferevent_new(int fd,
 | 
			
		||||
    evbuffercb readcb, evbuffercb writecb, everrorcb errorcb, void *cbarg);
 | 
			
		||||
int bufferevent_base_set(struct event_base *base, struct bufferevent *bufev);
 | 
			
		||||
int bufferevent_priority_set(struct bufferevent *bufev, int pri);
 | 
			
		||||
void bufferevent_free(struct bufferevent *bufev);
 | 
			
		||||
int bufferevent_write(struct bufferevent *bufev, const void *data, size_t size);
 | 
			
		||||
int bufferevent_write_buffer(struct bufferevent *bufev, struct evbuffer *buf);
 | 
			
		||||
size_t bufferevent_read(struct bufferevent *bufev, void *data, size_t size);
 | 
			
		||||
int bufferevent_enable(struct bufferevent *bufev, short event);
 | 
			
		||||
int bufferevent_disable(struct bufferevent *bufev, short event);
 | 
			
		||||
void bufferevent_settimeout(struct bufferevent *bufev,
 | 
			
		||||
    int timeout_read, int timeout_write);
 | 
			
		||||
 | 
			
		||||
#define EVBUFFER_LENGTH(x)	(x)->off
 | 
			
		||||
#define EVBUFFER_DATA(x)	(x)->buffer
 | 
			
		||||
#define EVBUFFER_INPUT(x)	(x)->input
 | 
			
		||||
#define EVBUFFER_OUTPUT(x)	(x)->output
 | 
			
		||||
 | 
			
		||||
struct evbuffer *evbuffer_new(void);
 | 
			
		||||
void evbuffer_free(struct evbuffer *);
 | 
			
		||||
int evbuffer_expand(struct evbuffer *, size_t);
 | 
			
		||||
int evbuffer_add(struct evbuffer *, const void *, size_t);
 | 
			
		||||
int evbuffer_remove(struct evbuffer *, void *, size_t);
 | 
			
		||||
char *evbuffer_readline(struct evbuffer *);
 | 
			
		||||
int evbuffer_add_buffer(struct evbuffer *, struct evbuffer *);
 | 
			
		||||
int evbuffer_add_printf(struct evbuffer *, const char *fmt, ...);
 | 
			
		||||
int evbuffer_add_vprintf(struct evbuffer *, const char *fmt, va_list ap);
 | 
			
		||||
void evbuffer_drain(struct evbuffer *, size_t);
 | 
			
		||||
int evbuffer_write(struct evbuffer *, int);
 | 
			
		||||
int evbuffer_read(struct evbuffer *, int, int);
 | 
			
		||||
u_char *evbuffer_find(struct evbuffer *, const u_char *, size_t);
 | 
			
		||||
void evbuffer_setcb(struct evbuffer *, void (*)(struct evbuffer *, size_t, size_t, void *), void *);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Marshaling tagged data - We assume that all tags are inserted in their
 | 
			
		||||
 * numeric order - so that unknown tags will always be higher than the
 | 
			
		||||
 * known ones - and we can just ignore the end of an event buffer.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
void evtag_init(void);
 | 
			
		||||
 | 
			
		||||
void evtag_marshal(struct evbuffer *evbuf, uint32_t tag, const void *data,
 | 
			
		||||
    uint32_t len);
 | 
			
		||||
 | 
			
		||||
void encode_int(struct evbuffer *evbuf, uint32_t number);
 | 
			
		||||
 | 
			
		||||
void evtag_marshal_int(struct evbuffer *evbuf, uint32_t tag, uint32_t integer);
 | 
			
		||||
 | 
			
		||||
void evtag_marshal_string(struct evbuffer *buf, uint32_t tag,
 | 
			
		||||
    const char *string);
 | 
			
		||||
 | 
			
		||||
void evtag_marshal_timeval(struct evbuffer *evbuf, uint32_t tag,
 | 
			
		||||
    struct timeval *tv);
 | 
			
		||||
 | 
			
		||||
int evtag_unmarshal(struct evbuffer *src, uint32_t *ptag, struct evbuffer *dst);
 | 
			
		||||
int evtag_peek(struct evbuffer *evbuf, uint32_t *ptag);
 | 
			
		||||
int evtag_peek_length(struct evbuffer *evbuf, uint32_t *plength);
 | 
			
		||||
int evtag_payload_length(struct evbuffer *evbuf, uint32_t *plength);
 | 
			
		||||
int evtag_consume(struct evbuffer *evbuf);
 | 
			
		||||
 | 
			
		||||
int evtag_unmarshal_int(struct evbuffer *evbuf, uint32_t need_tag,
 | 
			
		||||
    uint32_t *pinteger);
 | 
			
		||||
 | 
			
		||||
int evtag_unmarshal_fixed(struct evbuffer *src, uint32_t need_tag, void *data,
 | 
			
		||||
    size_t len);
 | 
			
		||||
 | 
			
		||||
int evtag_unmarshal_string(struct evbuffer *evbuf, uint32_t need_tag,
 | 
			
		||||
    char **pstring);
 | 
			
		||||
 | 
			
		||||
int evtag_unmarshal_timeval(struct evbuffer *evbuf, uint32_t need_tag,
 | 
			
		||||
    struct timeval *ptv);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										131
									
								
								libev/import_libevent
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										131
									
								
								libev/import_libevent
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,131 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
LE=../libevent-1.4.3-stable
 | 
			
		||||
 | 
			
		||||
if ! [ -e evbuffer.c ]; then
 | 
			
		||||
   echo do not run this programm unless you know what you are doing
 | 
			
		||||
   exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# this program combines libev and libevent into a single package
 | 
			
		||||
 | 
			
		||||
cvs update -AdP libev
 | 
			
		||||
rsync -avP libev/. . --exclude CVS
 | 
			
		||||
 | 
			
		||||
rm -f configure.ac
 | 
			
		||||
 | 
			
		||||
cp $LE/evdns.h .
 | 
			
		||||
 | 
			
		||||
perl -i -pe 's%^/.libevent-include./%#include "event_compat.h"%' event.h
 | 
			
		||||
 | 
			
		||||
perl -ne '
 | 
			
		||||
   s/\s+char buf\[64\];/\tchar buf[96];/;
 | 
			
		||||
   if (/#include "event.h"/) {
 | 
			
		||||
      print "#ifndef EV_STANDALONE\n$_#endif\n";
 | 
			
		||||
      next;
 | 
			
		||||
   }
 | 
			
		||||
   if (/#include "misc.h"/) {
 | 
			
		||||
      print "#ifndef EV_STANDALONE\n$_#endif\n";
 | 
			
		||||
      next;
 | 
			
		||||
   }
 | 
			
		||||
   if (/#include "(unistd.h|sys\/time.h)"/) {
 | 
			
		||||
      print "#ifndef WIN32\n$_#endif\n";
 | 
			
		||||
      next;
 | 
			
		||||
   }
 | 
			
		||||
   next if /#include "log.h"/;
 | 
			
		||||
 | 
			
		||||
   print;
 | 
			
		||||
' <$LE/evdns.c >evdns.c
 | 
			
		||||
 | 
			
		||||
cp $LE/autogen.sh .
 | 
			
		||||
cp $LE/epoll_sub.c .
 | 
			
		||||
cp $LE/evbuffer.c .
 | 
			
		||||
cp $LE/buffer.c .
 | 
			
		||||
cp $LE/evhttp.h .
 | 
			
		||||
cp $LE/evutil.h .
 | 
			
		||||
cp $LE/evutil.c .
 | 
			
		||||
cp $LE/event-config.h .
 | 
			
		||||
cp $LE/event-internal.h .
 | 
			
		||||
cp $LE/evrpc.h .
 | 
			
		||||
cp $LE/evrpc.c .
 | 
			
		||||
cp $LE/evrpc-internal.h .
 | 
			
		||||
cp $LE/http.c .
 | 
			
		||||
cp $LE/event_tagging.c .
 | 
			
		||||
cp $LE/http-internal.h .
 | 
			
		||||
cp $LE/strlcpy-internal.h .
 | 
			
		||||
cp $LE/log.c .
 | 
			
		||||
cp $LE/log.h .
 | 
			
		||||
cp $LE/strlcpy.c .
 | 
			
		||||
rsync -a $LE/WIN32* $LE/sample $LE/test $LE/compat . --del
 | 
			
		||||
#rename 's/libevent/libev/' WIN32-Prj/lib*
 | 
			
		||||
cp $LE/aclocal.m4 .
 | 
			
		||||
#cp $LE/acconfig.h .
 | 
			
		||||
cp $LE/config.h.in .
 | 
			
		||||
cp $LE/event_rpcgen.py .
 | 
			
		||||
cp $LE/*.3 .
 | 
			
		||||
 | 
			
		||||
#perl -i -pe 's/libevent/libev/g' sample/Makefile.am
 | 
			
		||||
#perl -i -pe 's/libevent/libev/g' test/Makefile.am
 | 
			
		||||
 | 
			
		||||
perl -i -pe 's/#include <event.h>$/#include "event.h"/' test/*.c
 | 
			
		||||
 | 
			
		||||
perl -i -ne '
 | 
			
		||||
   next if /"event-internal.h"/;
 | 
			
		||||
   s/base\d?->sig.ev_signal_added/0/;
 | 
			
		||||
   s/base\d?->sig.ev_signal_pair\[0\]/-1/;
 | 
			
		||||
   s/base->sig.evsignal_caught/0/;
 | 
			
		||||
   next if /^\ttest_signal_(dealloc|pipeloss|switchbase|assert|restore)\(\)/;
 | 
			
		||||
   next if /^\ttest_simplesignal\(\)/; # non-default-loop
 | 
			
		||||
   next if /^\ttest_immediatesignal\(\)/; # non-default-loop
 | 
			
		||||
   next if /test_priorities\(\d\)/;
 | 
			
		||||
   print;
 | 
			
		||||
' test/regress.c
 | 
			
		||||
 | 
			
		||||
perl -ne '
 | 
			
		||||
   s/\bmin_heap.h\b//g;
 | 
			
		||||
   s/\bsignal.c\b//g;
 | 
			
		||||
   s/\bevport.c\b//g;
 | 
			
		||||
   s/\bkqueue.c\b//g;
 | 
			
		||||
   s/\bdevpoll.c\b//g;
 | 
			
		||||
   s/\brtsig.c\b//g;
 | 
			
		||||
   s/\bselect.c\b//g;
 | 
			
		||||
   s/\bpoll.c\b//g;
 | 
			
		||||
   s/\bepoll.c\b//g;
 | 
			
		||||
   s/\bepoll_sub.c\b//g;
 | 
			
		||||
   s/\bevent-internal.h\b//g;
 | 
			
		||||
   s/\bevsignal.h\b//g;
 | 
			
		||||
   s/^(man_MANS\s*=)/$1 ev.3 /;
 | 
			
		||||
   s/^(EXTRA_DIST\s*=)/$1 libev.m4 ev.h ev_vars.h ev_wrap.h event_compat.h ev++.h ev_epoll.c ev_select.c ev_poll.c ev_kqueue.c ev_port.c ev_win32.c ev.3 ev.pod /;
 | 
			
		||||
   s/^(include_HEADERS\s*=)/$1 ev.h event_compat.h ev++.h /;
 | 
			
		||||
   s/^(CORE_SRC\s*=)/$1 ev.c /;
 | 
			
		||||
   s/^(SYS_LIBS\s*=)/$1 -lm /;
 | 
			
		||||
   #s/libevent/libev/g;
 | 
			
		||||
   print;
 | 
			
		||||
' <$LE/Makefile.am >Makefile.am
 | 
			
		||||
 | 
			
		||||
perl -ne '
 | 
			
		||||
   #s/-Wall/-Wall -Wno-comment -Wunused-function -Wno-unused-value/;
 | 
			
		||||
   s/-Wall//g;
 | 
			
		||||
   #s/libevent/libev/g;
 | 
			
		||||
   #VERSION
 | 
			
		||||
   s/AM_INIT_AUTOMAKE\s*\(.*,(.*)\)/AM_INIT_AUTOMAKE(libevent-$1+libev,3.1)/;
 | 
			
		||||
   s/AC_LIBOBJ\(select\)/: ;/g;
 | 
			
		||||
   s/AC_LIBOBJ\(poll\)/: ;/g;
 | 
			
		||||
   s/AC_LIBOBJ\(kqueue\)/: ;/g;
 | 
			
		||||
   s/AC_LIBOBJ\(epoll\)/: ;/g;
 | 
			
		||||
   s/AC_LIBOBJ\(devpoll\)/: ;/g;
 | 
			
		||||
   s/AC_LIBOBJ\(evport\)/: ;/g;
 | 
			
		||||
   s/AC_LIBOBJ\(signal\)/: ;/g;
 | 
			
		||||
   s/AC_LIBOBJ\(rtsig\)/: ;/g;
 | 
			
		||||
   print "m4_include([libev.m4])\n" if /^AC_OUTPUT/;
 | 
			
		||||
   print;
 | 
			
		||||
' <$LE/configure.in >configure.in
 | 
			
		||||
 | 
			
		||||
aclocal-1.7
 | 
			
		||||
automake-1.7 --add-missing
 | 
			
		||||
autoconf
 | 
			
		||||
autoheader
 | 
			
		||||
libtoolize
 | 
			
		||||
CC="ccache gcc" ./configure --prefix=/opt/libev --disable-shared "$@"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										42
									
								
								libev/libev.m4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								libev/libev.m4
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
dnl this file is part of libev, do not make local modifications
 | 
			
		||||
dnl http://software.schmorp.de/pkg/libev
 | 
			
		||||
 | 
			
		||||
dnl libev support
 | 
			
		||||
AC_CHECK_HEADERS(sys/inotify.h sys/epoll.h sys/event.h port.h poll.h sys/select.h sys/eventfd.h sys/signalfd.h)
 | 
			
		||||
 
 | 
			
		||||
AC_CHECK_FUNCS(inotify_init epoll_ctl kqueue port_create poll select eventfd signalfd)
 | 
			
		||||
 
 | 
			
		||||
AC_CHECK_FUNCS(clock_gettime, [], [
 | 
			
		||||
   dnl on linux, try syscall wrapper first
 | 
			
		||||
   if test $(uname) = Linux; then
 | 
			
		||||
      AC_MSG_CHECKING(for clock_gettime syscall)
 | 
			
		||||
      AC_LINK_IFELSE([AC_LANG_PROGRAM(
 | 
			
		||||
                      [#include <unistd.h>
 | 
			
		||||
                       #include <sys/syscall.h>
 | 
			
		||||
                       #include <time.h>],
 | 
			
		||||
                      [struct timespec ts; int status = syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts)])],
 | 
			
		||||
                     [ac_have_clock_syscall=1
 | 
			
		||||
                      AC_DEFINE(HAVE_CLOCK_SYSCALL, 1, Define to 1 to use the syscall interface for clock_gettime)
 | 
			
		||||
                      AC_MSG_RESULT(yes)],
 | 
			
		||||
                     [AC_MSG_RESULT(no)])
 | 
			
		||||
   fi
 | 
			
		||||
   if test -z "$LIBEV_M4_AVOID_LIBRT" && test -z "$ac_have_clock_syscall"; then
 | 
			
		||||
      AC_CHECK_LIB(rt, clock_gettime)
 | 
			
		||||
      unset ac_cv_func_clock_gettime
 | 
			
		||||
      AC_CHECK_FUNCS(clock_gettime)
 | 
			
		||||
   fi
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
AC_CHECK_FUNCS(nanosleep, [], [
 | 
			
		||||
   if test -z "$LIBEV_M4_AVOID_LIBRT"; then
 | 
			
		||||
      AC_CHECK_LIB(rt, nanosleep)
 | 
			
		||||
      unset ac_cv_func_nanosleep
 | 
			
		||||
      AC_CHECK_FUNCS(nanosleep)
 | 
			
		||||
   fi
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
if test -z "$LIBEV_M4_AVOID_LIBM"; then
 | 
			
		||||
   LIBM=m
 | 
			
		||||
fi
 | 
			
		||||
AC_SEARCH_LIBS(floor, $LIBM, [AC_DEFINE(HAVE_FLOOR, 1, Define to 1 if the floor function is available)])
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										8
									
								
								libev/update_ev_c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										8
									
								
								libev/update_ev_c
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
#!/bin/sh -e
 | 
			
		||||
 | 
			
		||||
(
 | 
			
		||||
   sed -ne '1,\%/\* ECB.H BEGIN \*/%p' ev.c
 | 
			
		||||
   cat ~/src/libecb/ecb.h
 | 
			
		||||
   sed -ne '\%/\* ECB.H END \*/%,$p' ev.c
 | 
			
		||||
) >ev.c~ && mv ev.c~ ev.c
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								libev/update_ev_wrap
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										19
									
								
								libev/update_ev_wrap
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
(
 | 
			
		||||
   echo '#define VAR(name,decl) name'
 | 
			
		||||
   echo '#define EV_GENWRAP 1'
 | 
			
		||||
   cat ev_vars.h
 | 
			
		||||
) | cc -E -o - - | perl -ne '
 | 
			
		||||
   while (<>) {
 | 
			
		||||
      push @syms, $1 if /(^\w+)/;
 | 
			
		||||
   }
 | 
			
		||||
   print "/* DO NOT EDIT, automatically generated by update_ev_wrap */\n",
 | 
			
		||||
         "#ifndef EV_WRAP_H\n",
 | 
			
		||||
         "#define EV_WRAP_H\n",
 | 
			
		||||
         (map "#define $_ ((loop)->$_)\n", sort @syms),
 | 
			
		||||
         "#else\n",
 | 
			
		||||
         "#undef EV_WRAP_H\n",
 | 
			
		||||
         (map "#undef $_\n", sort @syms),
 | 
			
		||||
         "#endif\n";
 | 
			
		||||
' >ev_wrap.h
 | 
			
		||||
							
								
								
									
										7
									
								
								libev/update_symbols
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										7
									
								
								libev/update_symbols
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
make ev.o event.o || exit
 | 
			
		||||
 | 
			
		||||
nm ev.o           | perl -ne 'print "$1\n" if /\S+ [A-Z] (\S+)/' > Symbols.ev
 | 
			
		||||
nm event.o        | perl -ne 'print "$1\n" if /\S+ [A-Z] (\S+)/' > Symbols.event
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user