summaryrefslogtreecommitdiff
path: root/ev.c
diff options
context:
space:
mode:
Diffstat (limited to 'ev.c')
-rw-r--r--ev.c111
1 files changed, 93 insertions, 18 deletions
diff --git a/ev.c b/ev.c
index 4475386..3c4d5b4 100644
--- a/ev.c
+++ b/ev.c
@@ -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 */