summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changes4
-rw-r--r--ev.c111
-rw-r--r--ev.pod22
-rw-r--r--ev_vars.h3
-rw-r--r--ev_wrap.h2
-rw-r--r--libev.m44
6 files changed, 120 insertions, 26 deletions
diff --git a/Changes b/Changes
index a698546..544a113 100644
--- a/Changes
+++ b/Changes
@@ -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.
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 */
diff --git a/ev.pod b/ev.pod
index 4fe808a..72cf388 100644
--- a/ev.pod
+++ b/ev.pod
@@ -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
diff --git a/ev_vars.h b/ev_vars.h
index 249aa2f..dbd3aac 100644
--- a/ev_vars.h
+++ b/ev_vars.h
@@ -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)
diff --git a/ev_wrap.h b/ev_wrap.h
index fbfc802..2124af6 100644
--- a/ev_wrap.h
+++ b/ev_wrap.h
@@ -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
diff --git a/libev.m4 b/libev.m4
index 5db99fb..393835e 100644
--- a/libev.m4
+++ b/libev.m4
@@ -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