Skip to content

Commit 7c25029

Browse files
committed
eloop: Only the main loop should process signals
But the way kqueue works is that all the queues will get the signal because they should all abort on SIGTERM/SIGINT. For this case, just exit the inner loop and let the main loop handle the signal procesing.
1 parent ef28138 commit 7c25029

File tree

3 files changed

+39
-62
lines changed

3 files changed

+39
-62
lines changed

src/dhcpsd.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,9 @@ dhcpsd_store_leases(struct ctx *ctx)
8787
}
8888

8989
static void
90-
dhcpsd_signal_cb(int sig, __unused void *arg)
90+
dhcpsd_signal_cb(int sig, void *arg)
9191
{
92+
struct ctx *ctx = arg;
9293
int exit_code = EXIT_FAILURE;
9394

9495
#define SIGMSG "received %s, %s"
@@ -105,7 +106,7 @@ dhcpsd_signal_cb(int sig, __unused void *arg)
105106
return;
106107
}
107108

108-
eloop_exitall(exit_code);
109+
eloop_exit(ctx->ctx_eloop, exit_code);
109110
}
110111

111112
int
@@ -187,7 +188,7 @@ dhcpsd_fork_cb(void *arg, unsigned short e)
187188

188189
/* Complicated, but it ensures we don't get a controlling terminal
189190
* and the ppid of any child processed match the main process. */
190-
static int
191+
static pid_t
191192
dhcpsd_fork(struct ctx *ctx)
192193
{
193194
int fork_fd[2];
@@ -271,7 +272,7 @@ dhcpsd_fork(struct ctx *ctx)
271272
}
272273
break;
273274
}
274-
return 0;
275+
return pid;
275276
}
276277

277278
static void

src/eloop.c

Lines changed: 34 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -244,20 +244,23 @@ eloop_event_count(const struct eloop *eloop)
244244
static int
245245
eloop_signal_kqueue(struct eloop *eloop, const int *signals, size_t nsignals)
246246
{
247-
size_t n = nsignals == 0 ? eloop->nsignals : nsignals;
248-
struct kevent ke[n], *kep = ke;
249-
size_t i;
247+
unsigned int cmd = nsignals == 0 ? EV_DELETE : EV_ADD;
250248

251-
if (eloop->signal_cb == NULL || n == 0)
249+
if (nsignals == 0) {
250+
signals = eloop->signals;
251+
nsignals = eloop->nsignals;
252+
}
253+
if (nsignals == 0)
252254
return 0;
253255

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);
256+
struct kevent ke[nsignals], *kep = ke;
257+
size_t i;
259258

260-
return kevent(eloop->fd, ke, (KEVENT_N)n, NULL, 0, NULL);
259+
for (i = 0; i < nsignals; i++)
260+
EV_SET(kep++, (uintptr_t)signals[i], EVFILT_SIGNAL, cmd, 0, 0,
261+
NULL);
262+
263+
return kevent(eloop->fd, ke, (KEVENT_N)nsignals, NULL, 0, NULL);
261264
}
262265

263266
static int
@@ -615,30 +618,6 @@ eloop_exit(struct eloop *eloop, int code)
615618
eloop->exitnow = true;
616619
}
617620

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-
642621
#if defined(USE_KQUEUE) || defined(USE_EPOLL)
643622
static int
644623
eloop_open(struct eloop *eloop)
@@ -857,27 +836,6 @@ eloop_new(void)
857836
return eloop;
858837
}
859838

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-
881839
void
882840
eloop_free(struct eloop *eloop)
883841
{
@@ -895,6 +853,11 @@ eloop_free(struct eloop *eloop)
895853
}
896854

897855
#if defined(USE_KQUEUE)
856+
857+
static int eloop_kqueue_signals[] = { SIGINT, SIGTERM };
858+
#define eloop_kqueue_nsignals \
859+
sizeof(eloop_kqueue_signals) / sizeof(eloop_kqueue_signals[0])
860+
898861
static int
899862
eloop_run_kqueue(struct eloop *eloop, const struct timespec *ts)
900863
{
@@ -903,6 +866,16 @@ eloop_run_kqueue(struct eloop *eloop, const struct timespec *ts)
903866
struct eloop_event *e;
904867
unsigned short events;
905868

869+
/* Inner loops generally don't have signals attached
870+
* but we do need to exit the loop to when interrupted
871+
* with SIGTERM or SIGINT. */
872+
if (eloop->nsignals == 0 && TAILQ_FIRST(&eloops)->nsignals) {
873+
eloop_signal_kqueue(eloop, eloop_kqueue_signals,
874+
eloop_kqueue_nsignals);
875+
eloop->signals = eloop_kqueue_signals;
876+
eloop->nsignals = eloop_kqueue_nsignals;
877+
}
878+
906879
n = kevent(eloop->fd, NULL, 0, eloop->fds, (KEVENT_N)eloop->nfds, ts);
907880
if (n == -1)
908881
return -1;
@@ -912,6 +885,12 @@ eloop_run_kqueue(struct eloop *eloop, const struct timespec *ts)
912885
break;
913886
e = (struct eloop_event *)ke->udata;
914887
if (ke->filter == EVFILT_SIGNAL) {
888+
if (eloop->signal_cb == NULL) {
889+
eloop_exit(eloop,
890+
ke->ident == SIGTERM ? EXIT_SUCCESS :
891+
EXIT_FAILURE);
892+
return nn;
893+
}
915894
eloop->signal_cb((int)ke->ident, eloop->signal_cb_ctx);
916895
continue;
917896
}

src/eloop.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,8 @@ 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);
103100
int eloop_start(struct eloop *);
104101

0 commit comments

Comments
 (0)