diff options
Diffstat (limited to 'ev.c')
-rw-r--r-- | ev.c | 111 |
1 files changed, 93 insertions, 18 deletions
@@ -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 */ |