Skip to content

Commit 95f91f5

Browse files
committed
eloop: Replace the inner eloop concept with waitfd
This is what we really want and saves the massive headache of managing two loops.
1 parent b6671a7 commit 95f91f5

File tree

2 files changed

+53
-68
lines changed

2 files changed

+53
-68
lines changed

src/eloop.c

Lines changed: 52 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,18 @@
4949
#include <sys/epoll.h>
5050

5151
#include <linux/version.h>
52-
#include <poll.h>
5352
#define USE_EPOLL
5453
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
5554
#define HAVE_EPOLL_PWAIT2
5655
#endif
5756
#else
58-
#include <poll.h>
5957
#define USE_PPOLL
6058
#endif
6159

6260
#include <errno.h>
6361
#include <fcntl.h>
6462
#include <limits.h>
63+
#include <poll.h>
6564
#include <signal.h>
6665
#include <stdbool.h>
6766
#include <stdint.h>
@@ -154,8 +153,6 @@ struct eloop {
154153
#endif
155154
};
156155

157-
TAILQ_HEAD(eloop_head, eloop) eloops = TAILQ_HEAD_INITIALIZER(eloops);
158-
159156
#ifdef HAVE_REALLOCARRAY
160157
#define eloop_realloca reallocarray
161158
#else
@@ -244,20 +241,23 @@ eloop_event_count(const struct eloop *eloop)
244241
static int
245242
eloop_signal_kqueue(struct eloop *eloop, const int *signals, size_t nsignals)
246243
{
247-
size_t n = nsignals == 0 ? eloop->nsignals : nsignals;
248-
struct kevent ke[n], *kep = ke;
249-
size_t i;
244+
unsigned int cmd = nsignals == 0 ? EV_DELETE : EV_ADD;
250245

251-
if (eloop->signal_cb == NULL || n == 0)
246+
if (nsignals == 0) {
247+
signals = eloop->signals;
248+
nsignals = eloop->nsignals;
249+
}
250+
if (nsignals == 0)
252251
return 0;
253252

254-
if (signals == NULL)
255-
signals = eloop->signals;
256-
for (i = 0; i < n; i++)
257-
EV_SET(kep++, (uintptr_t)signals[i], EVFILT_SIGNAL,
258-
nsignals == 0 ? EV_DELETE : EV_ADD, 0, 0, NULL);
253+
struct kevent ke[nsignals], *kep = ke;
254+
size_t i;
255+
256+
for (i = 0; i < nsignals; i++)
257+
EV_SET(kep++, (uintptr_t)signals[i], EVFILT_SIGNAL, cmd, 0, 0,
258+
NULL);
259259

260-
return kevent(eloop->fd, ke, (KEVENT_N)n, NULL, 0, NULL);
260+
return kevent(eloop->fd, ke, (KEVENT_N)nsignals, NULL, 0, NULL);
261261
}
262262

263263
static int
@@ -615,30 +615,6 @@ eloop_exit(struct eloop *eloop, int code)
615615
eloop->exitnow = true;
616616
}
617617

618-
void
619-
eloop_exitall(int code)
620-
{
621-
struct eloop *eloop;
622-
623-
TAILQ_FOREACH(eloop, &eloops, next) {
624-
eloop->exitcode = code;
625-
eloop->exitnow = true;
626-
}
627-
}
628-
629-
void
630-
eloop_exitallinners(int code)
631-
{
632-
struct eloop *eloop;
633-
634-
TAILQ_FOREACH(eloop, &eloops, next) {
635-
if (eloop == TAILQ_FIRST(&eloops))
636-
continue;
637-
eloop->exitcode = code;
638-
eloop->exitnow = true;
639-
}
640-
}
641-
642618
#if defined(USE_KQUEUE) || defined(USE_EPOLL)
643619
static int
644620
eloop_open(struct eloop *eloop)
@@ -853,31 +829,9 @@ eloop_new(void)
853829
}
854830
#endif
855831

856-
TAILQ_INSERT_TAIL(&eloops, eloop, next);
857832
return eloop;
858833
}
859834

860-
struct eloop *
861-
eloop_new_with_signals(struct eloop *eloop)
862-
{
863-
struct eloop *e;
864-
int err;
865-
866-
e = eloop_new();
867-
if (e == NULL)
868-
return NULL;
869-
870-
err = eloop_signal_set_cb(e, eloop->signals, eloop->nsignals,
871-
eloop->signal_cb, eloop->signal_cb_ctx);
872-
if (err == -1) {
873-
eloop_free(e);
874-
return NULL;
875-
}
876-
memcpy(&e->sigset, &eloop->sigset, sizeof(e->sigset));
877-
878-
return e;
879-
}
880-
881835
void
882836
eloop_free(struct eloop *eloop)
883837
{
@@ -890,11 +844,42 @@ eloop_free(struct eloop *eloop)
890844
close(eloop->fd);
891845
#endif
892846
free(eloop->fds);
893-
TAILQ_REMOVE(&eloops, eloop, next);
894847
free(eloop);
895848
}
896849

850+
static unsigned short
851+
eloop_pollevents(struct pollfd *pfd)
852+
{
853+
unsigned short events = 0;
854+
855+
if (pfd->revents & POLLIN)
856+
events |= ELE_READ;
857+
if (pfd->revents & POLLOUT)
858+
events |= ELE_WRITE;
859+
if (pfd->revents & POLLHUP)
860+
events |= ELE_HANGUP;
861+
if (pfd->revents & POLLERR)
862+
events |= ELE_ERROR;
863+
if (pfd->revents & POLLNVAL)
864+
events |= ELE_NVAL;
865+
return events;
866+
}
867+
868+
int
869+
eloop_waitfd(int fd)
870+
{
871+
struct pollfd pfd = { .fd = fd, .events = POLLIN };
872+
int err;
873+
874+
err = ppoll(&pfd, 1, NULL, NULL);
875+
if (err == -1 || err == 0)
876+
return err;
877+
878+
return (int)eloop_pollevents(&pfd);
879+
}
880+
897881
#if defined(USE_KQUEUE)
882+
898883
static int
899884
eloop_run_kqueue(struct eloop *eloop, const struct timespec *ts)
900885
{
@@ -910,9 +895,10 @@ eloop_run_kqueue(struct eloop *eloop, const struct timespec *ts)
910895
for (nn = n, ke = eloop->fds; nn != 0; nn--, ke++) {
911896
if (eloop->exitnow || eloop->events_invalid)
912897
break;
913-
e = (struct eloop_event *)ke->udata;
914898
if (ke->filter == EVFILT_SIGNAL) {
915-
eloop->signal_cb((int)ke->ident, eloop->signal_cb_ctx);
899+
if (eloop->signal_cb != NULL)
900+
eloop->signal_cb((int)ke->ident,
901+
eloop->signal_cb_ctx);
916902
continue;
917903
}
918904
if (ke->filter == EVFILT_READ)
@@ -932,6 +918,7 @@ eloop_run_kqueue(struct eloop *eloop, const struct timespec *ts)
932918
events |= ELE_HANGUP;
933919
if (ke->flags & EV_ERROR)
934920
events |= ELE_ERROR;
921+
e = (struct eloop_event *)ke->udata;
935922
e->cb(e->cb_arg, events);
936923
}
937924

@@ -1077,10 +1064,10 @@ eloop_start(struct eloop *eloop)
10771064

10781065
#ifndef USE_KQUEUE
10791066
if (eloop_nsig != 0) {
1080-
int n = eloop_sig[--eloop_nsig];
1067+
int sig = eloop_sig[--eloop_nsig];
10811068

10821069
if (eloop->signal_cb != NULL)
1083-
eloop->signal_cb(n, eloop->signal_cb_ctx);
1070+
eloop->signal_cb(sig, eloop->signal_cb_ctx);
10841071
continue;
10851072
}
10861073
#endif

src/eloop.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,10 @@ int eloop_signal_set_cb(struct eloop *, const int *, size_t,
9494
int eloop_signal_mask(struct eloop *);
9595

9696
struct eloop *eloop_new(void);
97-
struct eloop *eloop_new_with_signals(struct eloop *);
9897
void eloop_free(struct eloop *);
9998
void eloop_exit(struct eloop *, int);
100-
void eloop_exitall(int);
101-
void eloop_exitallinners(int);
10299
int eloop_forked(struct eloop *, unsigned short);
100+
int eloop_waitfd(int);
103101
int eloop_start(struct eloop *);
104102

105103
#endif

0 commit comments

Comments
 (0)