diff options
-rw-r--r-- | Changes | 4 | ||||
-rw-r--r-- | ev.c | 111 | ||||
-rw-r--r-- | ev.pod | 22 | ||||
-rw-r--r-- | ev_vars.h | 3 | ||||
-rw-r--r-- | ev_wrap.h | 2 | ||||
-rw-r--r-- | libev.m4 | 4 |
6 files changed, 120 insertions, 26 deletions
@@ -1,5 +1,9 @@ Revision history for libev, a high-performance and full-featured event loop. + - added linux eventfd support. + - try to autodetect epoll and inotify support + by libc header version if not using autoconf. + 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. @@ -41,6 +41,7 @@ extern "C" { #endif +/* this big block deduces configuration from config.h */ #ifndef EV_STANDALONE # ifdef EV_CONFIG_H # include EV_CONFIG_H @@ -120,6 +121,14 @@ extern "C" { # endif # endif +# ifndef EV_USE_EVENTFD +# if HAVE_EVENTFD +# define EV_USE_EVENTFD 1 +# else +# define EV_USE_EVENTFD 0 +# endif +# endif + #endif #include <math.h> @@ -154,7 +163,7 @@ extern "C" { # endif #endif -/**/ +/* this block tries to deduce configuration from header-defined symbols and defaults */ #ifndef EV_USE_MONOTONIC # define EV_USE_MONOTONIC 0 @@ -181,7 +190,11 @@ extern "C" { #endif #ifndef EV_USE_EPOLL -# define EV_USE_EPOLL 0 +# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4)) +# define EV_USE_EPOLL 1 +# else +# define EV_USE_EPOLL 0 +# endif #endif #ifndef EV_USE_KQUEUE @@ -193,7 +206,11 @@ extern "C" { #endif #ifndef EV_USE_INOTIFY -# define EV_USE_INOTIFY 0 +# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4)) +# define EV_USE_INOTIFY 1 +# else +# define EV_USE_INOTIFY 0 +# endif #endif #ifndef EV_PID_HASHSIZE @@ -212,7 +229,15 @@ extern "C" { # endif #endif -/**/ +#ifndef EV_USE_EVENTFD +# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7)) +# define EV_USE_EVENTFD 1 +# else +# define EV_USE_EVENTFD 0 +# endif +#endif + +/* this block fixes any misconfiguration where we know we run into trouble otherwise */ #ifndef CLOCK_MONOTONIC # undef EV_USE_MONOTONIC @@ -243,6 +268,11 @@ extern "C" { # include <winsock.h> #endif +#if EV_USE_EVENTFD +/* our minimum requirement is glibc 2.7 which has the stub, but not the header */ +int eventfd (unsigned int initval, int flags); +#endif + /**/ /* @@ -804,13 +834,24 @@ evpipe_init (EV_P) { if (!ev_is_active (&pipeev)) { - while (pipe (evpipe)) - syserr ("(libev) error creating signal/async pipe"); +#if EV_USE_EVENTFD + if ((evfd = eventfd (0, 0)) >= 0) + { + evpipe [0] = -1; + fd_intern (evfd); + ev_io_set (&pipeev, evfd, EV_READ); + } + else +#endif + { + while (pipe (evpipe)) + syserr ("(libev) error creating signal/async pipe"); - fd_intern (evpipe [0]); - fd_intern (evpipe [1]); + fd_intern (evpipe [0]); + fd_intern (evpipe [1]); + ev_io_set (&pipeev, evpipe [0], EV_READ); + } - ev_io_set (&pipeev, evpipe [0], EV_READ); ev_io_start (EV_A_ &pipeev); ev_unref (EV_A); /* watcher should not keep loop alive */ } @@ -824,7 +865,16 @@ evpipe_write (EV_P_ EV_ATOMIC_T *flag) int old_errno = errno; /* save errno because write might clobber it */ *flag = 1; - write (evpipe [1], &old_errno, 1); + +#if EV_USE_EVENTFD + if (evfd >= 0) + { + uint64_t counter = 1; + write (evfd, &counter, sizeof (uint64_t)); + } + else +#endif + write (evpipe [1], &old_errno, 1); errno = old_errno; } @@ -833,10 +883,18 @@ evpipe_write (EV_P_ EV_ATOMIC_T *flag) static void pipecb (EV_P_ ev_io *iow, int revents) { - { - int dummy; - read (evpipe [0], &dummy, 1); - } +#if EV_USE_EVENTFD + if (evfd >= 0) + { + uint64_t counter = 1; + read (evfd, &counter, sizeof (uint64_t)); + } + else +#endif + { + char dummy; + read (evpipe [0], &dummy, 1); + } if (gotsig && ev_is_default_loop (EV_A)) { @@ -1141,8 +1199,16 @@ loop_destroy (EV_P) ev_ref (EV_A); /* signal watcher */ ev_io_stop (EV_A_ &pipeev); - close (evpipe [0]); evpipe [0] = 0; - close (evpipe [1]); evpipe [1] = 0; +#if EV_USE_EVENTFD + if (evfd >= 0) + close (evfd); +#endif + + if (evpipe [0] >= 0) + { + close (evpipe [0]); + close (evpipe [1]); + } } #if EV_USE_INOTIFY @@ -1226,8 +1292,17 @@ loop_fork (EV_P) ev_ref (EV_A); ev_io_stop (EV_A_ &pipeev); - close (evpipe [0]); - close (evpipe [1]); + +#if EV_USE_EVENTFD + if (evfd >= 0) + close (evfd); +#endif + + if (evpipe [0] >= 0) + { + close (evpipe [0]); + close (evpipe [1]); + } evpipe_init (EV_A); /* now iterate over everything, in case we missed something */ @@ -2739,9 +2739,9 @@ For this of course you need the m4 file: =head2 PREPROCESSOR SYMBOLS/MACROS -Libev can be configured via a variety of preprocessor symbols you have to define -before including any of its files. The default is not to build for multiplicity -and only include the select backend. +Libev can be configured via a variety of preprocessor symbols you have to +define before including any of its files. The default in the absense of +autoconf is noted for every option. =over 4 @@ -2777,6 +2777,14 @@ note about libraries in the description of C<EV_USE_MONOTONIC>, though. If defined to be C<1>, libev will assume that C<nanosleep ()> is available and will use it for delays. Otherwise it will use C<select ()>. +=item EV_USE_EVENTFD + +If defined to be C<1>, then libev will assume that C<eventfd ()> is +available and will probe for kernel support at runtime. This will improve +C<ev_signal> and C<ev_async> performance and reduce resource consumption. +If undefined, it will be enabled if the headers indicate GNU/Linux + Glibc +2.7 or newer, otherwise disabled. + =item EV_USE_SELECT If undefined or defined to be C<1>, libev will compile in support for the @@ -2822,8 +2830,9 @@ takes precedence over select. If defined to be C<1>, libev will compile in support for the Linux C<epoll>(7) backend. Its availability will be detected at runtime, -otherwise another method will be used as fallback. This is the -preferred backend for GNU/Linux systems. +otherwise another method will be used as fallback. This is the preferred +backend for GNU/Linux systems. If undefined, it will be enabled if the +headers indicate GNU/Linux + Glibc 2.4 or newer, otherwise disabled. =item EV_USE_KQUEUE @@ -2852,7 +2861,8 @@ reserved for future expansion, works like the USE symbols above. If defined to be C<1>, libev will compile in support for the Linux inotify interface to speed up C<ev_stat> watchers. Its actual availability will -be detected at runtime. +be detected at runtime. If undefined, it will be enabled if the headers +indicate GNU/Linux + Glibc 2.4 or newer, otherwise disabled. =item EV_ATOMIC_T @@ -55,6 +55,9 @@ VARx(ev_tstamp, backend_fudge) /* 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)) +#if EV_USE_EVENTFD || EV_GENWRAP +VARx(int, evfd) +#endif VAR (evpipe, int evpipe [2]) VARx(ev_io, pipeev) @@ -13,6 +13,7 @@ #define backend_fudge ((loop)->backend_fudge) #define backend_modify ((loop)->backend_modify) #define backend_poll ((loop)->backend_poll) +#define evfd ((loop)->evfd) #define evpipe ((loop)->evpipe) #define pipeev ((loop)->pipeev) #define curpid ((loop)->curpid) @@ -84,6 +85,7 @@ #undef backend_fudge #undef backend_modify #undef backend_poll +#undef evfd #undef evpipe #undef pipeev #undef curpid @@ -2,9 +2,9 @@ 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 sys/queue.h port.h poll.h sys/select.h) +AC_CHECK_HEADERS(sys/inotify.h sys/epoll.h sys/event.h sys/queue.h port.h poll.h sys/select.h sys/eventfd.h) -AC_CHECK_FUNCS(inotify_init epoll_ctl kqueue port_create poll select) +AC_CHECK_FUNCS(inotify_init epoll_ctl kqueue port_create poll select eventfd) AC_CHECK_FUNC(clock_gettime, [], [ if test -z "$LIBEV_M4_AVOID_LIBRT"; then |