From 78bf46ae8ca0ebdc4c4ba5c93588638f836e4d9f Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 3 Feb 2011 17:18:09 +0000 Subject: [PATCH 6/6] Use epoll in a backwards-compatible way on Linux < 2.6.27 Bug: https://bugs.freedesktop.org/show_bug.cgi?id=33337 Bug-NB: NB#197191 Bug-NB: NB#225019 --- configure.ac | 3 +++ dbus/dbus-socket-set-epoll.c | 21 ++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletions(-) diff --git a/configure.ac b/configure.ac index d3fba82..2c4a115 100644 --- a/configure.ac +++ b/configure.ac @@ -999,6 +999,9 @@ fi AM_CONDITIONAL(DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX, test x$have_dnotify = xyes) +# For simplicity, we require the userland API for epoll_create1 at +# compile-time (glibc 2.9), but we'll run on kernels that turn out +# not to have it at runtime. AC_ARG_ENABLE([epoll], [AS_HELP_STRING([--enable-epoll],[use epoll(4) on Linux])], [enable_epoll=$enableval], [enable_epoll=auto]) diff --git a/dbus/dbus-socket-set-epoll.c b/dbus/dbus-socket-set-epoll.c index 430a857..4cd9a56 100644 --- a/dbus/dbus-socket-set-epoll.c +++ b/dbus/dbus-socket-set-epoll.c @@ -33,6 +33,7 @@ #endif #include +#include #include #include @@ -81,6 +82,21 @@ _dbus_socket_set_epoll_new (void) if (self->epfd == -1) { + int flags; + + /* the size hint is ignored unless you have a rather old kernel, + * but must be positive on some versions, so just pick something + * arbitrary; it's a hint, not a limit */ + self->epfd = epoll_create (42); + + flags = fcntl (self->epfd, F_GETFD, 0); + + if (flags != -1) + fcntl (self->epfd, F_SETFD, flags | FD_CLOEXEC); + } + + if (self->epfd == -1) + { socket_set_epoll_free ((DBusSocketSet *) self); return NULL; } @@ -252,8 +268,11 @@ socket_set_epoll_remove (DBusSocketSet *set, { DBusSocketSetEpoll *self = socket_set_epoll_cast (set); int err; + /* Kernels < 2.6.9 require a non-NULL struct pointer, even though its + * contents are ignored */ + struct epoll_event dummy = { 0 }; - if (epoll_ctl (self->epfd, EPOLL_CTL_DEL, fd, NULL) == 0) + if (epoll_ctl (self->epfd, EPOLL_CTL_DEL, fd, &dummy) == 0) return; err = errno; -- 1.7.5.4