Skip to content

Commit 3134f25

Browse files
committed
eloop: support epoll_pwait2 for kernels >= 5.11
As it more matches ppoll semantics. Note that epoll_pwait does NOT work with zero events, so use ppoll in this case.
1 parent 5f92561 commit 3134f25

2 files changed

Lines changed: 35 additions & 13 deletions

File tree

src/eloop.c

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,13 @@
5050
#define _kevent kevent
5151
#endif
5252
#elif defined(__linux__)
53+
#include <linux/version.h>
5354
#include <sys/epoll.h>
55+
#include <poll.h>
5456
#define USE_EPOLL
57+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
58+
#define HAVE_EPOLL_PWAIT2
59+
#endif
5560
#else
5661
#include <poll.h>
5762
#define USE_PPOLL
@@ -925,24 +930,38 @@ eloop_run_kqueue(struct eloop *eloop, const struct timespec *ts)
925930
static int
926931
eloop_run_epoll(struct eloop *eloop, const struct timespec *ts)
927932
{
928-
int timeout, n, nn;
933+
int n, nn;
929934
struct epoll_event *epe;
930935
struct eloop_event *e;
931936
unsigned short events;
932937

933-
if (ts != NULL) {
934-
if (ts->tv_sec > INT_MAX / 1000 ||
935-
(ts->tv_sec == INT_MAX / 1000 &&
936-
((ts->tv_nsec + 999999) / 1000000 > INT_MAX % 1000000)))
937-
timeout = INT_MAX;
938-
else
939-
timeout = (int)(ts->tv_sec * 1000 +
940-
(ts->tv_nsec + 999999) / 1000000);
941-
} else
942-
timeout = -1;
938+
/* epoll does not work with zero events */
939+
if (eloop->nfds == 0)
940+
n = ppoll(NULL, 0, ts, &eloop->sigset);
941+
else
942+
#ifdef HAVE_EPOLL_PWAIT2
943+
n = epoll_pwait2(eloop->fd, eloop->fds, (int)eloop->nfds,
944+
ts, &eloop->sigset);
945+
#else
946+
{
947+
int timeout;
948+
949+
if (ts != NULL) {
950+
if (ts->tv_sec > INT_MAX / 1000 ||
951+
(ts->tv_sec == INT_MAX / 1000 &&
952+
((ts->tv_nsec + 999999) / 1000000 >
953+
INT_MAX % 1000000)))
954+
timeout = INT_MAX;
955+
else
956+
timeout = (int)(ts->tv_sec * 1000 +
957+
(ts->tv_nsec + 999999) / 1000000);
958+
} else
959+
timeout = -1;
943960

944-
n = epoll_pwait(eloop->fd, eloop->fds, (int)eloop->nfds, timeout,
945-
&eloop->sigset);
961+
n = epoll_pwait(eloop->fd, eloop->fds, (int)eloop->nfds,
962+
timeout, &eloop->sigset);
963+
}
964+
#endif
946965
if (n == -1)
947966
return -1;
948967

src/privsep-linux.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,9 @@ static struct sock_filter ps_seccomp_filter[] = {
325325
#ifdef __NR_epoll_pwait
326326
SECCOMP_ALLOW(__NR_epoll_pwait),
327327
#endif
328+
#ifdef __NR_epoll_pwait2
329+
SECCOMP_ALLOW(__NR_epoll_pwait2),
330+
#endif
328331
#ifdef __NR_exit_group
329332
SECCOMP_ALLOW(__NR_exit_group),
330333
#endif

0 commit comments

Comments
 (0)