Commit 78bf46ae authored by Simon McVittie's avatar Simon McVittie

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
parent 0110a3b1
......@@ -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])
......
......@@ -33,6 +33,7 @@
#endif
#include <errno.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <unistd.h>
......@@ -79,6 +80,21 @@ _dbus_socket_set_epoll_new (void)
self->epfd = epoll_create1 (EPOLL_CLOEXEC);
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);
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment