]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
eloop: Just use ppoll(2)
authorRoy Marples <roy@marples.name>
Wed, 3 Jun 2020 22:30:08 +0000 (23:30 +0100)
committerRoy Marples <roy@marples.name>
Wed, 3 Jun 2020 22:30:08 +0000 (23:30 +0100)
epoll and kqueue are really too heavy weight.
With privsep, we now favour more processes for BPF and per address sockets.
As such, the number of fds to monitor will always be quite small.

All modern OS now have ppoll(2) (NetBSD has pollts, which is the same)
which works perfectly for us.
If neither are present, the a wrapper around pselect(2) is provided,
which can be found on all POSIX systems.

This makes the code a lot smaller and easier to follow.
The reduced binary size and memory usage is a nice win here.

BUILDING.md
configure
src/dhcpcd.c
src/eloop.c
src/eloop.h
src/privsep-root.c
src/privsep.c

index 3540557dbbf587097e3092a669ac118577d4ace0..f672724a6680bd6459e1b0bcd22b5b4bcadc6d3f 100644 (file)
@@ -129,18 +129,6 @@ You can disable this with `--without-dev`, or `without-udev`.
 NOTE: in Gentoo at least, `sys-fs/udev` as provided by systemd leaks memory
 `sys-fs/eudev`, the fork of udev does not and as such is recommended.
 
-## select
-dhcpcd uses eloop.c, which is a portable main event loop with timeouts and
-signal handling. Unlike libevent and similar, it can be transplanted directly
-within the application - the only caveat outside of POSIX calls is that
-you provide queue.h based on a recent BSD (glibc sys/queue.h is not enough).
-eloop supports the following polling mechanisms, listed in order of preference:
-       kqueue, epoll, pollts, ppoll and pselect.
-If signal handling is disabled (ie in RTEMS or other single process
-OS's) then eloop can use poll.
-You can decide which polling mechanism dhcpcd will select in eloop like so
-`./configure --with-poll=[kqueue|epoll|pselect|pollts|ppoll]`
-
 
 ## Importing into another source control system
 To import the full sources, use the import target.
@@ -153,8 +141,7 @@ Example: `make DESTDIR=/usr/src/contrib/dhcpcd import-src`
 
 ## Hooks
 Not all the hooks in dhcpcd-hooks are installed by default.
-By default we install `01-test`, `02-dump`, `10-mtu`, `20-resolv.conf`
-and `30-hostname`.
+By default we install `01-test`, `20-resolv.conf`and `30-hostname`.
 The other hooks, `10-wpa_supplicant`, `15-timezone` and `29-lookup-hostname`
 are installed to `$(datadir)/dhcpcd/hooks` by default and need to be
 copied to `$(libexecdir)/dhcpcd-hooks` for use.
index e82be8782e5ed8ae7c47359ed0cde1ecb6bce52e..b2532680652c4fbae46faccc6353528b94244b4b 100755 (executable)
--- a/configure
+++ b/configure
@@ -1211,65 +1211,42 @@ fi
 echo "#define  HAVE_REALLOCARRAY" >>$CONFIG_H
 
 if [ -z "$POLL" ]; then
-       printf "Testing for kqueue1 ... "
-       cat <<EOF >_kqueue.c
-#include <sys/types.h>
-#include <sys/event.h>
+       printf "Testing for ppoll ... "
+       cat <<EOF >_ppoll.c
+#include <poll.h>
+#include <stddef.h>
 int main(void) {
-       return kqueue1(0);
+       struct pollfd fds;
+       return ppoll(&fds, 1, NULL, NULL);
 }
 EOF
-       if $XCC _kqueue.c -o _kqueue 2>&3; then
-               POLL=kqueue1
-               echo "yes"
-       else
-               echo "no"
-       fi
-       rm -f _kqueue.c _kqueue
+       if $XCC _ppoll.c -o _ppoll 2>&3; then
+               POLL=ppoll
+               echo "#define   HAVE_PPOLL" >>$CONFIG_MK
+               echo "yes"
+       else
+               echo "no"
+       fi
+       rm -f _ppoll.c _ppoll
 fi
 if [ -z "$POLL" ]; then
-       printf "Testing for kqueue ... "
-       cat <<EOF >_kqueue.c
-#include <sys/types.h>
-#include <sys/event.h>
+       printf "Testing for pollts ... "
+       cat <<EOF >_pollts.c
+#include <poll.h>
+#include <stddef.h>
 int main(void) {
-       return kqueue();
+       struct pollfd fds;
+       return pollts(&fds, 1, NULL, NULL);
 }
 EOF
-       if $XCC _kqueue.c -o _kqueue 2>&3; then
-               POLL=kqueue
-               echo "yes"
-       else
-               echo "no"
-       fi
-       rm -f _kqueue.c _kqueue
-fi
-if [ -z "$POLL" ]; then
-       printf "Testing for epoll ... "
-       cat <<EOF >_epoll.c
-#ifdef __linux__
-#include <linux/version.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
-#error kernel has buggy epoll_wait timeout
-#endif
-#endif
-
-#include <sys/epoll.h>
-#include <unistd.h>
-int main(void) {
-       epoll_create1(EPOLL_CLOEXEC);
-       epoll_pwait(-1, NULL, 0, 0, NULL);
-       return 0;
-}
-EOF
-       if $XCC _epoll.c -o _epoll 2>&3; then
-               POLL=epoll
-               echo "#define   HAVE_EPOLL" >>$CONFIG_MK
+       if $XCC _pollts.c -o _pollts 2>&3; then
+               POLL=pollts
+               echo "#define   HAVE_PPOLL" >>$CONFIG_MK
                echo "yes"
        else
                echo "no"
        fi
-       rm -f _epoll.c _epoll
+       rm -f _pollts.c _pollts
 fi
 if [ -z "$POLL" ]; then
        printf "Testing for pselect ... "
@@ -1290,22 +1267,12 @@ EOF
        rm -f _pselect.c _pselect
 fi
 case "$POLL" in
-kqueue1)
-       echo "#define   HAVE_KQUEUE" >>$CONFIG_H
-       echo "#define   HAVE_KQUEUE1" >>$CONFIG_H
-       ;;
-kqueue)
-       echo "#define   HAVE_KQUEUE" >>$CONFIG_H
-       ;;
-epoll)
-       echo "#define   HAVE_EPOLL" >>$CONFIG_H
+ppoll)
+       echo "#define   HAVE_PPOLL" >>$CONFIG_H
        ;;
 pollts)
        echo "#define   HAVE_POLLTS" >>$CONFIG_H
        ;;
-ppoll)
-       echo "#define   HAVE_PPOLL" >>$CONFIG_H
-       ;;
 pselect)
        echo "#define   HAVE_PSELECT" >>$CONFIG_H
        ;;
index 015b439e2516cd54f61fe71f0e963da8b7a98278..0c759ca37e168d6bf1c545f71a54f92a01accdcd 100644 (file)
@@ -2039,13 +2039,9 @@ printpidfile:
                signal(dhcpcd_signals_ignore[si], SIG_IGN);
 
        /* Save signal mask, block and redirect signals to our handler */
-       if (eloop_signal_set_cb(ctx.eloop,
+       eloop_signal_set_cb(ctx.eloop,
            dhcpcd_signals, dhcpcd_signals_len,
-           dhcpcd_signal_cb, &ctx) == -1)
-       {
-               logerr("%s: eloop_signal_set_cb", __func__);
-               goto exit_failure;
-       }
+           dhcpcd_signal_cb, &ctx);
        if (eloop_signal_mask(ctx.eloop, &ctx.sigset) == -1) {
                logerr("%s: eloop_signal_mask", __func__);
                goto exit_failure;
@@ -2211,7 +2207,6 @@ printpidfile:
                        logerr("fork");
                        goto exit_failure;
                case 0:
-                       eloop_requeue(ctx.eloop);
                        break;
                default:
                        ctx.options |= DHCPCD_FORKED; /* A lie */
index 2a67982ef1db9d6fc17c5ce1cf17c5883cf5967b..39c43d9d8bf9e12e7f75086177de4092c3da3eeb 100644 (file)
  * SUCH DAMAGE.
  */
 
-#if (defined(__unix__) || defined(unix)) && !defined(USG)
-#include <sys/param.h>
-#endif
 #include <sys/time.h>
 
 #include <assert.h>
 #include <errno.h>
 #include <limits.h>
+#include <poll.h>
 #include <signal.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
-/* config.h should define HAVE_KQUEUE, HAVE_EPOLL, etc. */
+/* config.h should define HAVE_PPOLL, etc. */
 #if defined(HAVE_CONFIG_H) && !defined(NO_CONFIG_H)
 #include "config.h"
 #endif
 
-/* Attempt to autodetect kqueue or epoll.
- * Failing that, fall back to pselect. */
-#if !defined(HAVE_KQUEUE) && !defined(HAVE_EPOLL) && !defined(HAVE_PSELECT) && \
-    !defined(HAVE_POLLTS) && !defined(HAVE_PPOLL)
-#if defined(BSD)
-/* Assume BSD has a working sys/queue.h and kqueue(2) interface. */
-#define HAVE_SYS_QUEUE_H
-#define HAVE_KQUEUE
-#define WARN_SELECT
-#elif defined(__linux__) || defined(__sun)
-/* Assume Linux and Solaris have a working epoll(3) interface. */
-#define HAVE_EPOLL
-#define WARN_SELECT
-#else
-/* pselect(2) is a POSIX standard. */
+#if defined(HAVE_PPOLL)
+#elif defined(HAVE_POLLTS)
+#define ppoll pollts
+#elif !defined(HAVE_PSELECT)
+#pragma message("Compiling eloop with pselect(2) support.")
 #define HAVE_PSELECT
-#define WARN_SELECT
-#endif
-#endif
-
-/* pollts and ppoll require poll.
- * pselect is wrapped in a pollts/ppoll style interface
- * and as such require poll as well. */
-#if defined(HAVE_PSELECT) || defined(HAVE_POLLTS) || defined(HAVE_PPOLL)
-#ifndef HAVE_POLL
-#define HAVE_POLL
-#endif
-#if defined(HAVE_POLLTS)
-#define POLLTS pollts
-#elif defined(HAVE_PPOLL)
-#define POLLTS ppoll
-#else
-#define POLLTS eloop_pollts
-#define ELOOP_NEED_POLLTS
-#endif
+#define ppoll eloop_ppoll
 #endif
 
 #include "eloop.h"
 #endif
 #endif
 
-#if defined(HAVE_KQUEUE)
-#include <sys/event.h>
-#include <fcntl.h>
-#ifdef __NetBSD__
-/* udata is void * except on NetBSD.
- * lengths are int except on NetBSD. */
-#define UPTR(x)        ((intptr_t)(x))
-#define LENC(x)        (x)
-#else
-#define UPTR(x)        (x)
-#define LENC(x)        ((int)(x))
-#endif
-#elif defined(HAVE_EPOLL)
-#include <sys/epoll.h>
-#elif defined(HAVE_POLL)
-#if defined(HAVE_PSELECT)
+#ifdef HAVE_PSELECT
 #include <sys/select.h>
 #endif
-#include <poll.h>
-#endif
-
-#ifdef WARN_SELECT
-#if defined(HAVE_KQUEUE)
-#pragma message("Compiling eloop with kqueue(2) support.")
-#elif defined(HAVE_EPOLL)
-#pragma message("Compiling eloop with epoll(7) support.")
-#elif defined(HAVE_PSELECT)
-#pragma message("Compiling eloop with pselect(2) support.")
-#elif defined(HAVE_PPOLL)
-#pragma message("Compiling eloop with ppoll(2) support.")
-#elif defined(HAVE_POLLTS)
-#pragma message("Compiling eloop with pollts(2) support.")
-#else
-#error Unknown select mechanism for eloop
-#endif
-#endif
 
 /* Our structures require TAILQ macros, which really every libc should
  * ship as they are useful beyond belief.
@@ -171,6 +108,7 @@ struct eloop_event {
        void *read_cb_arg;
        void (*write_cb)(void *);
        void *write_cb_arg;
+       struct pollfd *pollfd;
 };
 
 struct eloop_timeout {
@@ -183,11 +121,9 @@ struct eloop_timeout {
 };
 
 struct eloop {
-       size_t events_len;
        TAILQ_HEAD (event_head, eloop_event) events;
+       size_t nevents;
        struct event_head free_events;
-       int events_maxfd;
-       struct eloop_event **event_fds;
 
        struct timespec now;
        TAILQ_HEAD (timeout_head, eloop_timeout) timeouts;
@@ -200,12 +136,8 @@ struct eloop {
        void (*signal_cb)(int, void *);
        void *signal_cb_ctx;
 
-#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
-       int poll_fd;
-#elif defined(HAVE_POLL)
        struct pollfd *fds;
-       size_t fds_len;
-#endif
+       size_t nfds;
 
        int exitnow;
        int exitcode;
@@ -229,30 +161,10 @@ eloop_realloca(void *ptr, size_t n, size_t size)
 }
 #endif
 
-#ifdef HAVE_POLL
-static void
-eloop_event_setup_fds(struct eloop *eloop)
-{
-       struct eloop_event *e;
-       size_t i;
-
-       i = 0;
-       TAILQ_FOREACH(e, &eloop->events, next) {
-               eloop->fds[i].fd = e->fd;
-               eloop->fds[i].events = 0;
-               if (e->read_cb)
-                       eloop->fds[i].events |= POLLIN;
-               if (e->write_cb)
-                       eloop->fds[i].events |= POLLOUT;
-               eloop->fds[i].revents = 0;
-               i++;
-       }
-}
-
-#ifdef ELOOP_NEED_POLLTS
-/* Wrapper around pselect, to imitate the NetBSD pollts call. */
+#ifdef HAVE_PSELECT
+/* Wrapper around pselect, to imitate the ppoll call. */
 static int
-eloop_pollts(struct pollfd * fds, nfds_t nfds,
+eloop_ppoll(struct pollfd * fds, nfds_t nfds,
     const struct timespec *ts, const sigset_t *sigmask)
 {
        fd_set read_fds, write_fds;
@@ -287,10 +199,7 @@ eloop_pollts(struct pollfd * fds, nfds_t nfds,
 
        return r;
 }
-#endif /* pollts */
-#else /* !HAVE_POLL */
-#define eloop_event_setup_fds(a) {}
-#endif /* HAVE_POLL */
+#endif
 
 unsigned long long
 eloop_timespec_diff(const struct timespec *tsp, const struct timespec *usp,
@@ -360,19 +269,33 @@ eloop_reduce_timers(struct eloop *eloop)
        eloop->now = now;
 }
 
+static void
+eloop_event_setup_fds(struct eloop *eloop)
+{
+       struct eloop_event *e;
+       struct pollfd *pfd;
+
+       pfd = eloop->fds;
+       TAILQ_FOREACH(e, &eloop->events, next) {
+               e->pollfd = pfd;
+               pfd->fd = e->fd;
+               pfd->events = 0;
+               if (e->read_cb != NULL)
+                       pfd->events |= POLLIN;
+               if (e->write_cb != NULL)
+                       pfd->events |= POLLOUT;
+               pfd->revents = 0;
+               pfd++;
+       }
+}
+
 int
 eloop_event_add_rw(struct eloop *eloop, int fd,
     void (*read_cb)(void *), void *read_cb_arg,
     void (*write_cb)(void *), void *write_cb_arg)
 {
        struct eloop_event *e;
-#if defined(HAVE_KQUEUE)
-       struct kevent ke[2];
-#elif defined(HAVE_EPOLL)
-       struct epoll_event epe;
-#elif defined(HAVE_POLL)
-       struct pollfd *nfds;
-#endif
+       struct pollfd *pfd;
 
        assert(eloop != NULL);
        assert(read_cb != NULL || write_cb != NULL);
@@ -381,122 +304,41 @@ eloop_event_add_rw(struct eloop *eloop, int fd,
                return -1;
        }
 
-#ifdef HAVE_EPOLL
-       memset(&epe, 0, sizeof(epe));
-       epe.data.fd = fd;
-       epe.events = EPOLLIN;
-       if (write_cb)
-               epe.events |= EPOLLOUT;
-#endif
-
-       /* We should only have one callback monitoring the fd. */
-       if (fd <= eloop->events_maxfd) {
-               if ((e = eloop->event_fds[fd]) != NULL) {
-                       int error;
-
-#if defined(HAVE_KQUEUE)
-                       EV_SET(&ke[0], (uintptr_t)fd, EVFILT_READ, EV_ADD,
-                           0, 0, UPTR(e));
-                       if (write_cb)
-                               EV_SET(&ke[1], (uintptr_t)fd, EVFILT_WRITE,
-                                   EV_ADD, 0, 0, UPTR(e));
-                       else if (e->write_cb)
-                               EV_SET(&ke[1], (uintptr_t)fd, EVFILT_WRITE,
-                                   EV_DELETE, 0, 0, UPTR(e));
-                       error = kevent(eloop->poll_fd, ke,
-                           e->write_cb || write_cb ? 2 : 1, NULL, 0, NULL);
-#elif defined(HAVE_EPOLL)
-                       epe.data.ptr = e;
-                       error = epoll_ctl(eloop->poll_fd, EPOLL_CTL_MOD,
-                           fd, &epe);
-#else
-                       error = 0;
-#endif
-                       if (read_cb) {
-                               e->read_cb = read_cb;
-                               e->read_cb_arg = read_cb_arg;
-                       }
-                       if (write_cb) {
-                               e->write_cb = write_cb;
-                               e->write_cb_arg = write_cb_arg;
-                       }
-                       eloop_event_setup_fds(eloop);
-                       return error;
-               }
-       } else {
-               struct eloop_event **new_fds;
-               int maxfd, i;
-
-               /* Reserve ourself and 4 more. */
-               maxfd = fd + 4;
-               new_fds = eloop_realloca(eloop->event_fds,
-                   ((size_t)maxfd + 1), sizeof(*eloop->event_fds));
-               if (new_fds == NULL)
-                       return -1;
-
-               /* set new entries NULL as the fd's may not be contiguous. */
-               for (i = maxfd; i > eloop->events_maxfd; i--)
-                       new_fds[i] = NULL;
-
-               eloop->event_fds = new_fds;
-               eloop->events_maxfd = maxfd;
+       TAILQ_FOREACH(e, &eloop->events, next) {
+               if (e->fd == fd)
+                       break;
        }
 
-       /* Allocate a new event if no free ones already allocated. */
-       if ((e = TAILQ_FIRST(&eloop->free_events))) {
-               TAILQ_REMOVE(&eloop->free_events, e, next);
-       } else {
-               e = malloc(sizeof(*e));
-               if (e == NULL)
-                       goto err;
-       }
+       if (e == NULL) {
+               if (eloop->nevents + 1 > eloop->nfds) {
+                       pfd = eloop_realloca(eloop->fds, eloop->nevents + 1,
+                           sizeof(*pfd));
+                       if (pfd == NULL)
+                               return -1;
+                       eloop->fds = pfd;
+                       eloop->nfds++;
+               }
 
-       /* Ensure we can actually listen to it. */
-       eloop->events_len++;
-#ifdef HAVE_POLL
-       if (eloop->events_len > eloop->fds_len) {
-               nfds = eloop_realloca(eloop->fds,
-                   (eloop->fds_len + 5), sizeof(*eloop->fds));
-               if (nfds == NULL)
-                       goto err;
-               eloop->fds_len += 5;
-               eloop->fds = nfds;
+               e = TAILQ_FIRST(&eloop->free_events);
+               if (e != NULL)
+                       TAILQ_REMOVE(&eloop->free_events, e, next);
+               else {
+                       e = malloc(sizeof(*e));
+                       if (e == NULL)
+                               return -1;
+                       TAILQ_INSERT_HEAD(&eloop->events, e, next);
+               }
+               e->fd = fd;
+               eloop->nevents++;
        }
-#endif
 
-       /* Now populate the structure and add it to the list. */
-       e->fd = fd;
        e->read_cb = read_cb;
        e->read_cb_arg = read_cb_arg;
        e->write_cb = write_cb;
        e->write_cb_arg = write_cb_arg;
 
-#if defined(HAVE_KQUEUE)
-       if (read_cb != NULL)
-               EV_SET(&ke[0], (uintptr_t)fd, EVFILT_READ,
-                   EV_ADD, 0, 0, UPTR(e));
-       if (write_cb != NULL)
-               EV_SET(&ke[1], (uintptr_t)fd, EVFILT_WRITE,
-                   EV_ADD, 0, 0, UPTR(e));
-       if (kevent(eloop->poll_fd, ke, write_cb ? 2 : 1, NULL, 0, NULL) == -1)
-               goto err;
-#elif defined(HAVE_EPOLL)
-       epe.data.ptr = e;
-       if (epoll_ctl(eloop->poll_fd, EPOLL_CTL_ADD, fd, &epe) == -1)
-               goto err;
-#endif
-
-       TAILQ_INSERT_HEAD(&eloop->events, e, next);
-       eloop->event_fds[e->fd] = e;
        eloop_event_setup_fds(eloop);
        return 0;
-
-err:
-       if (e) {
-               eloop->events_len--;
-               TAILQ_INSERT_TAIL(&eloop->free_events, e, next);
-       }
-       return -1;
 }
 
 int
@@ -519,17 +361,14 @@ int
 eloop_event_delete_write(struct eloop *eloop, int fd, int write_only)
 {
        struct eloop_event *e;
-#if defined(HAVE_KQUEUE)
-       struct kevent ke[2];
-#elif defined(HAVE_EPOLL)
-       struct epoll_event epe;
-#endif
 
        assert(eloop != NULL);
 
-       if (fd > eloop->events_maxfd ||
-           (e = eloop->event_fds[fd]) == NULL)
-       {
+       TAILQ_FOREACH(e, &eloop->events, next) {
+               if (e->fd == fd)
+                       break;
+       }
+       if (e == NULL) {
                errno = ENOENT;
                return -1;
        }
@@ -541,41 +380,15 @@ eloop_event_delete_write(struct eloop *eloop, int fd, int write_only)
                        goto remove;
                e->write_cb = NULL;
                e->write_cb_arg = NULL;
-#if defined(HAVE_KQUEUE)
-               EV_SET(&ke[0], (uintptr_t)e->fd,
-                   EVFILT_WRITE, EV_DELETE, 0, 0, UPTR(NULL));
-               kevent(eloop->poll_fd, ke, 1, NULL, 0, NULL);
-#elif defined(HAVE_EPOLL)
-               memset(&epe, 0, sizeof(epe));
-               epe.data.fd = e->fd;
-               epe.data.ptr = e;
-               epe.events = EPOLLIN;
-               epoll_ctl(eloop->poll_fd, EPOLL_CTL_MOD, fd, &epe);
-#endif
-               eloop_event_setup_fds(eloop);
-               return 1;
+               goto done;
        }
 
 remove:
        TAILQ_REMOVE(&eloop->events, e, next);
-       eloop->event_fds[e->fd] = NULL;
        TAILQ_INSERT_TAIL(&eloop->free_events, e, next);
-       eloop->events_len--;
-
-#if defined(HAVE_KQUEUE)
-       EV_SET(&ke[0], (uintptr_t)fd, EVFILT_READ,
-           EV_DELETE, 0, 0, UPTR(NULL));
-       if (e->write_cb)
-               EV_SET(&ke[1], (uintptr_t)fd,
-                   EVFILT_WRITE, EV_DELETE, 0, 0, UPTR(NULL));
-       kevent(eloop->poll_fd, ke, e->write_cb ? 2 : 1, NULL, 0, NULL);
-#elif defined(HAVE_EPOLL)
-       /* NULL event is safe because we
-        * rely on epoll_pwait which as added
-        * after the delete without event was fixed. */
-       epoll_ctl(eloop->poll_fd, EPOLL_CTL_DEL, fd, NULL);
-#endif
+       eloop->nevents--;
 
+done:
        eloop_event_setup_fds(eloop);
        return 1;
 }
@@ -681,7 +494,6 @@ eloop_q_timeout_add_msec(struct eloop *eloop, int queue, unsigned long when,
                (unsigned int)seconds, (unsigned int)nseconds, callback, arg);
 }
 
-#if !defined(HAVE_KQUEUE)
 static int
 eloop_timeout_add_now(struct eloop *eloop,
     void (*callback)(void *), void *arg)
@@ -692,7 +504,6 @@ eloop_timeout_add_now(struct eloop *eloop,
        eloop->timeout0_arg = arg;
        return 0;
 }
-#endif
 
 int
 eloop_q_timeout_delete(struct eloop *eloop, int queue,
@@ -734,106 +545,7 @@ eloop_enter(struct eloop *eloop)
        eloop->exitnow = 0;
 }
 
-#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
-static int
-eloop_open(struct eloop *eloop)
-{
-
-#if defined(HAVE_KQUEUE1)
-       return (eloop->poll_fd = kqueue1(O_CLOEXEC));
-#elif defined(HAVE_KQUEUE)
-       int i;
-
-       if ((eloop->poll_fd = kqueue()) == -1)
-               return -1;
-       if ((i = fcntl(eloop->poll_fd, F_GETFD, 0)) == -1 ||
-           fcntl(eloop->poll_fd, F_SETFD, i | FD_CLOEXEC) == -1)
-       {
-               close(eloop->poll_fd);
-               eloop->poll_fd = -1;
-       }
-
-       return eloop->poll_fd;
-#elif defined (HAVE_EPOLL)
-       return (eloop->poll_fd = epoll_create1(EPOLL_CLOEXEC));
-#else
-       return (eloop->poll_fd = -1);
-#endif
-}
-#endif
-
-int
-eloop_requeue(struct eloop *eloop)
-{
-#if defined(HAVE_POLL)
-
-       UNUSED(eloop);
-       return 0;
-#else /* !HAVE_POLL */
-       struct eloop_event *e;
-       int error;
-#if defined(HAVE_KQUEUE)
-       size_t i;
-       struct kevent *ke;
-#elif defined(HAVE_EPOLL)
-       struct epoll_event epe;
-#endif
-
-       assert(eloop != NULL);
-
-       if (eloop->poll_fd != -1)
-               close(eloop->poll_fd);
-       if (eloop_open(eloop) == -1)
-               return -1;
-#if defined (HAVE_KQUEUE)
-       i = eloop->signals_len;
-       TAILQ_FOREACH(e, &eloop->events, next) {
-               i++;
-               if (e->write_cb)
-                       i++;
-       }
-
-       if ((ke = malloc(sizeof(*ke) * i)) == NULL)
-               return -1;
-
-       for (i = 0; i < eloop->signals_len; i++)
-               EV_SET(&ke[i], (uintptr_t)eloop->signals[i],
-                   EVFILT_SIGNAL, EV_ADD, 0, 0, UPTR(NULL));
-
-       TAILQ_FOREACH(e, &eloop->events, next) {
-               EV_SET(&ke[i], (uintptr_t)e->fd, EVFILT_READ,
-                   EV_ADD, 0, 0, UPTR(e));
-               i++;
-               if (e->write_cb) {
-                       EV_SET(&ke[i], (uintptr_t)e->fd, EVFILT_WRITE,
-                           EV_ADD, 0, 0, UPTR(e));
-                       i++;
-               }
-       }
-
-       error =  kevent(eloop->poll_fd, ke, LENC(i), NULL, 0, NULL);
-       free(ke);
-
-#elif defined(HAVE_EPOLL)
-
-       error = 0;
-       TAILQ_FOREACH(e, &eloop->events, next) {
-               memset(&epe, 0, sizeof(epe));
-               epe.data.fd = e->fd;
-               epe.events = EPOLLIN;
-               if (e->write_cb)
-                       epe.events |= EPOLLOUT;
-               epe.data.ptr = e;
-               if (epoll_ctl(eloop->poll_fd, EPOLL_CTL_ADD, e->fd, &epe) == -1)
-                       error = -1;
-       }
-#endif
-
-       return error;
-#endif /* HAVE_POLL */
-}
-
-int
+void
 eloop_signal_set_cb(struct eloop *eloop,
     const int *signals, size_t signals_len,
     void (*signal_cb)(int, void *), void *signal_cb_ctx)
@@ -845,10 +557,8 @@ eloop_signal_set_cb(struct eloop *eloop,
        eloop->signals_len = signals_len;
        eloop->signal_cb = signal_cb;
        eloop->signal_cb_ctx = signal_cb_ctx;
-       return eloop_requeue(eloop);
 }
 
-#ifndef HAVE_KQUEUE
 struct eloop_siginfo {
        int sig;
        struct eloop *eloop;
@@ -876,16 +586,16 @@ eloop_signal3(int sig, __unused siginfo_t *siginfo, __unused void *arg)
        eloop_timeout_add_now(_eloop_siginfo.eloop,
            eloop_signal1, &_eloop_siginfo);
 }
-#endif
 
 int
 eloop_signal_mask(struct eloop *eloop, sigset_t *oldset)
 {
        sigset_t newset;
        size_t i;
-#ifndef HAVE_KQUEUE
-       struct sigaction sa;
-#endif
+       struct sigaction sa = {
+           .sa_sigaction = eloop_signal3,
+           .sa_flags = SA_SIGINFO,
+       };
 
        assert(eloop != NULL);
 
@@ -895,19 +605,13 @@ eloop_signal_mask(struct eloop *eloop, sigset_t *oldset)
        if (sigprocmask(SIG_SETMASK, &newset, oldset) == -1)
                return -1;
 
-#ifndef HAVE_KQUEUE
        _eloop = eloop;
-
-       memset(&sa, 0, sizeof(sa));
-       sa.sa_sigaction = eloop_signal3;
-       sa.sa_flags = SA_SIGINFO;
        sigemptyset(&sa.sa_mask);
 
        for (i = 0; i < eloop->signals_len; i++) {
                if (sigaction(eloop->signals[i], &sa, NULL) == -1)
                        return -1;
        }
-#endif
        return 0;
 }
 
@@ -927,19 +631,11 @@ eloop_new(void)
        }
 
        TAILQ_INIT(&eloop->events);
-       eloop->events_maxfd = -1;
        TAILQ_INIT(&eloop->free_events);
        TAILQ_INIT(&eloop->timeouts);
        TAILQ_INIT(&eloop->free_timeouts);
        eloop->exitcode = EXIT_FAILURE;
 
-#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
-       if (eloop_open(eloop) == -1) {
-               eloop_free(eloop);
-               return NULL;
-       }
-#endif
-
        return eloop;
 }
 
@@ -952,10 +648,7 @@ eloop_clear(struct eloop *eloop)
        if (eloop == NULL)
                return;
 
-       free(eloop->event_fds);
-       eloop->event_fds = NULL;
-       eloop->events_len = 0;
-       eloop->events_maxfd = -1;
+       eloop->nevents = 0;
        eloop->signals = NULL;
        eloop->signals_len = 0;
 
@@ -976,21 +669,15 @@ eloop_clear(struct eloop *eloop)
                free(t);
        }
 
-#if defined(HAVE_POLL)
        free(eloop->fds);
        eloop->fds = NULL;
-       eloop->fds_len = 0;
-#endif
+       eloop->nfds = 0;
 }
 
 void
 eloop_free(struct eloop *eloop)
 {
 
-#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
-       if (eloop != NULL)
-               close(eloop->poll_fd);
-#endif
        eloop_clear(eloop);
        free(eloop);
 }
@@ -1002,18 +689,7 @@ eloop_start(struct eloop *eloop, sigset_t *signals)
        struct eloop_event *e;
        struct eloop_timeout *t;
        void (*t0)(void *);
-#if defined(HAVE_KQUEUE)
-       struct kevent ke;
-       UNUSED(signals);
-#elif defined(HAVE_EPOLL)
-       struct epoll_event epe;
-#endif
-#if defined(HAVE_KQUEUE) || defined(HAVE_POLL)
        struct timespec ts, *tsp;
-#endif
-#ifndef HAVE_KQUEUE
-       int timeout;
-#endif
 
        assert(eloop != NULL);
 
@@ -1030,7 +706,7 @@ eloop_start(struct eloop *eloop, sigset_t *signals)
                }
 
                t = TAILQ_FIRST(&eloop->timeouts);
-               if (t == NULL && eloop->events_len == 0)
+               if (t == NULL && eloop->nevents == 0)
                        break;
 
                if (t != NULL)
@@ -1044,7 +720,6 @@ eloop_start(struct eloop *eloop, sigset_t *signals)
                }
 
                if (t != NULL) {
-#if defined(HAVE_KQUEUE) || defined(HAVE_POLL)
                        if (t->seconds > INT_MAX) {
                                ts.tv_sec = (time_t)INT_MAX;
                                ts.tv_nsec = 0;
@@ -1053,43 +728,10 @@ eloop_start(struct eloop *eloop, sigset_t *signals)
                                ts.tv_nsec = (long)t->nseconds;
                        }
                        tsp = &ts;
-#endif
-
-#ifndef HAVE_KQUEUE
-                       if (t->seconds > INT_MAX / 1000 ||
-                           (t->seconds == INT_MAX / 1000 &&
-                           ((t->nseconds + 999999) / 1000000
-                           > INT_MAX % 1000000)))
-                               timeout = INT_MAX;
-                       else
-                               timeout = (int)(t->seconds * 1000 +
-                                   (t->nseconds + 999999) / 1000000);
-#endif
-               } else {
-#if defined(HAVE_KQUEUE) || defined(HAVE_POLL)
+               } else
                        tsp = NULL;
-#endif
-#ifndef HAVE_KQUEUE
-                       timeout = -1;
-#endif
-               }
 
-#if defined(HAVE_KQUEUE)
-               n = kevent(eloop->poll_fd, NULL, 0, &ke, 1, tsp);
-#elif defined(HAVE_EPOLL)
-               if (signals)
-                       n = epoll_pwait(eloop->poll_fd, &epe, 1,
-                           timeout, signals);
-               else
-                       n = epoll_wait(eloop->poll_fd, &epe, 1, timeout);
-#elif defined(HAVE_POLL)
-               if (signals)
-                       n = POLLTS(eloop->fds, (nfds_t)eloop->events_len,
-                           tsp, signals);
-               else
-                       n = poll(eloop->fds, (nfds_t)eloop->events_len,
-                           timeout);
-#endif
+               n = ppoll(eloop->fds, (nfds_t)eloop->nevents, tsp, signals);
                if (n == -1) {
                        if (errno == EINTR)
                                continue;
@@ -1098,47 +740,20 @@ eloop_start(struct eloop *eloop, sigset_t *signals)
                if (n == 0)
                        continue;
 
-               /* Process any triggered events.
-                * We go back to the start after calling each callback incase
-                * the current event or next event is removed. */
-#if defined(HAVE_KQUEUE)
-               if (ke.filter == EVFILT_SIGNAL) {
-                       eloop->signal_cb((int)ke.ident,
-                           eloop->signal_cb_ctx);
-               } else {
-                       e = (struct eloop_event *)ke.udata;
-                       if (ke.filter == EVFILT_WRITE && e->write_cb != NULL)
-                               e->write_cb(e->write_cb_arg);
-                       else if (ke.filter == EVFILT_READ && e->read_cb != NULL)
-                               e->read_cb(e->read_cb_arg);
-               }
-#elif defined(HAVE_EPOLL)
-               e = (struct eloop_event *)epe.data.ptr;
-               if (epe.events & EPOLLOUT && e->write_cb != NULL)
-                       e->write_cb(e->write_cb_arg);
-               else if (epe.events & (EPOLLIN | EPOLLERR | EPOLLHUP) &&
-                   e->read_cb != NULL)
-                       e->read_cb(e->read_cb_arg);
-#elif defined(HAVE_POLL)
-               size_t i;
-
-               for (i = 0; i < eloop->events_len; i++) {
-                       if (eloop->fds[i].revents & POLLOUT) {
-                               e = eloop->event_fds[eloop->fds[i].fd];
+               TAILQ_FOREACH(e, &eloop->events, next) {
+                       if (e->pollfd->revents & POLLOUT) {
                                if (e->write_cb != NULL) {
                                        e->write_cb(e->write_cb_arg);
                                        break;
                                }
                        }
-                       if (eloop->fds[i].revents) {
-                               e = eloop->event_fds[eloop->fds[i].fd];
+                       if (e->pollfd->revents) {
                                if (e->read_cb != NULL) {
                                        e->read_cb(e->read_cb_arg);
                                        break;
                                }
                        }
                }
-#endif
        }
 
        return eloop->exitcode;
index 40a1b2ffc18550eb50ec12cb4d55fbb4eaf96b13..9001c1b7840e8b2b99da88d85ee37cb7229293be 100644 (file)
@@ -83,12 +83,11 @@ int eloop_q_timeout_add_msec(struct eloop *, int,
     unsigned long, void (*)(void *), void *);
 int eloop_q_timeout_delete(struct eloop *, int, void (*)(void *), void *);
 
-int eloop_signal_set_cb(struct eloop *, const int *, size_t,
+void eloop_signal_set_cb(struct eloop *, const int *, size_t,
     void (*)(int, void *), void *);
 int eloop_signal_mask(struct eloop *, sigset_t *oldset);
 
 struct eloop * eloop_new(void);
-int eloop_requeue(struct eloop *);
 void eloop_clear(struct eloop *);
 void eloop_free(struct eloop *);
 void eloop_exit(struct eloop *, int);
index ae52c6ede43fcc5c05ce5af63e218781b4647ce0..93cb8a290e0f3a714366f176a55ba13baaccbc81 100644 (file)
@@ -788,10 +788,9 @@ ps_root_start(struct dhcpcd_ctx *ctx)
        if ((ctx->ps_eloop = eloop_new()) == NULL)
                return -1;
 
-       if (eloop_signal_set_cb(ctx->ps_eloop,
+       eloop_signal_set_cb(ctx->ps_eloop,
            dhcpcd_signals, dhcpcd_signals_len,
-           ps_root_readerrorsig, ctx) == -1)
-               return -1;
+           ps_root_readerrorsig, ctx);
 
        return pid;
 }
index d4fdac1ef112ef3cb49cf0a4161042f036907e5e..5d7e2ca5eae3481b870912272b7e396b4ccdb54c 100644 (file)
@@ -243,12 +243,8 @@ ps_dostart(struct dhcpcd_ctx *ctx,
                ctx->ps_inet_fd = -1;
        }
 
-       if (eloop_signal_set_cb(ctx->eloop,
-           dhcpcd_signals, dhcpcd_signals_len, signal_cb, ctx) == -1)
-       {
-               logerr("%s: eloop_signal_set_cb", __func__);
-               goto errexit;
-       }
+       eloop_signal_set_cb(ctx->eloop,
+           dhcpcd_signals, dhcpcd_signals_len, signal_cb, ctx);
 
        /* ctx->sigset aready has the initial sigmask set in main() */
        if (eloop_signal_mask(ctx->eloop, NULL) == -1) {