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 | 
