diff options
Diffstat (limited to 'queue_epoll.c')
-rw-r--r-- | queue_epoll.c | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/queue_epoll.c b/queue_epoll.c index ab289c7..a680180 100644 --- a/queue_epoll.c +++ b/queue_epoll.c @@ -9,6 +9,7 @@ * migrating clients between threads */ #if defined(HAVE_EPOLL_WAIT) && ! MOG_LIBKQUEUE +#include "compat_epoll_pwait.h" #include <sys/utsname.h> /* @@ -100,6 +101,25 @@ struct mog_queue * mog_queue_new(void) return mog_queue_init(epoll_fd); } +static struct mog_fd * epoll_event_check(int rc, struct epoll_event *event) +{ + struct mog_fd *mfd; + + switch (rc) { + case 1: + mfd = event->data.ptr; + mog_fd_check_out(mfd); + return mfd; + case 0: + return NULL; + } + + if (errno != EINTR) + /* rc could be > 1 if the kernel is broken :P */ + die_errno("epoll_wait() failed with (%d)", rc); + return NULL; +} + /* * grabs one active event off the event queue * epoll_wait() has "wake-one" behavior (like accept()) @@ -109,7 +129,6 @@ struct mog_fd * mog_idleq_wait(struct mog_queue *q, int timeout) { int rc; struct epoll_event event; - struct mog_fd *mfd; bool cancellable = timeout != 0; if (cancellable) @@ -120,20 +139,18 @@ struct mog_fd * mog_idleq_wait(struct mog_queue *q, int timeout) if (cancellable) mog_cancel_disable(); + return epoll_event_check(rc, &event); +} - switch (rc) { - case 1: - mfd = event.data.ptr; - mog_fd_check_out(mfd); - return mfd; - case 0: - return NULL; - } +struct mog_fd * mog_idleq_wait_intr(struct mog_queue *q, int timeout) +{ + int rc; + struct epoll_event event; + sigset_t set; - if (errno != EINTR) - /* rc could be > 1 if the kernel is broken :P */ - die_errno("epoll_wait() failed with (%d)", rc); - return NULL; + CHECK(int, 0, sigemptyset(&set)); + rc = epoll_pwait(q->queue_fd, &event, 1, timeout, &set); + return epoll_event_check(rc, &event); } MOG_NOINLINE static void |