Skip to content

Commit 2025ab2

Browse files
committed
MINOR: better signal handling
The use of signals is simplified, their actions are divided into two groups: - signals that interrupt the operation of the program (HUP, INT, TERM, USR1) - signals that are ignored (PIPE, USR2)
1 parent f4b7d50 commit 2025ab2

File tree

3 files changed

+82
-27
lines changed

3 files changed

+82
-27
lines changed

include/types/worker.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ struct worker {
4141
#endif
4242
};
4343

44+
struct worker_signal {
45+
struct ev_signal signal;
46+
int signum;
47+
void (*func)(struct ev_loop *, struct ev_signal *, int);
48+
};
49+
4450
#endif /* _TYPES_WORKER_H */
4551

4652
/*

src/.build-counter

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2432
1+
2437

src/worker.c

Lines changed: 75 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ static void worker_stop(struct ev_loop *loop, const char *msg __maybe_unused)
386386

387387
/***
388388
* NAME
389-
* worker_sigint_cb -
389+
* worker_signal_stop_cb -
390390
*
391391
* ARGUMENTS
392392
* loop -
@@ -399,14 +399,51 @@ static void worker_stop(struct ev_loop *loop, const char *msg __maybe_unused)
399399
* RETURN VALUE
400400
* This function does not return a value.
401401
*/
402-
static void worker_sigint_cb(struct ev_loop *loop, struct ev_signal *ev __maybe_unused, int revents __maybe_unused)
402+
static void worker_signal_stop_cb(struct ev_loop *loop, struct ev_signal *ev, int revents __maybe_unused)
403403
{
404+
char buffer[BUFSIZ];
405+
const char *sig_name;
406+
407+
DBG_FUNC(NULL, "%p, %p, 0x%08x", loop, ev, revents);
408+
409+
if (_NULL(sig_name = strsignal(ev->signum)))
410+
sig_name = "Unknown signal";
411+
(void)snprintf(buffer, sizeof(buffer), "signal received - %s (%d)", sig_name, ev->signum);
412+
413+
worker_stop(loop, buffer);
414+
}
415+
416+
417+
/***
418+
* NAME
419+
* worker_signal_ignore_cb -
420+
*
421+
* ARGUMENTS
422+
* loop -
423+
* ev -
424+
* revents -
425+
*
426+
* DESCRIPTION
427+
* -
428+
*
429+
* RETURN VALUE
430+
* This function does not return a value.
431+
*/
432+
static void worker_signal_ignore_cb(struct ev_loop *loop __maybe_unused, struct ev_signal *ev, int revents __maybe_unused)
433+
{
434+
const char *sig_name;
435+
404436
DBG_FUNC(NULL, "%p, %p, 0x%08x", loop, ev, revents);
405437

406-
worker_stop(loop, "SIGINT signal received");
438+
if (_NULL(sig_name = strsignal(ev->signum)))
439+
sig_name = "Unknown signal";
440+
441+
W_DBG(WORKER, NULL, "signal ignored - %s received (%d)", sig_name, ev->signum);
407442
}
408443

409444

445+
446+
410447
/***
411448
* NAME
412449
* worker_runtime_cb -
@@ -515,27 +552,31 @@ static void worker_accept_cb(struct ev_loop *loop __maybe_unused, struct ev_io *
515552
* worker_run_exit -
516553
*
517554
* ARGUMENTS
518-
* fd -
519-
* ev_base -
520-
* ev_sigint -
521-
* ev_accept -
522-
* retval -
555+
* fd -
556+
* ev_base -
557+
* ev_signals -
558+
* nr_signals -
559+
* ev_accept -
560+
* retval -
523561
*
524562
* DESCRIPTION
525563
* -
526564
*
527565
* RETURN VALUE
528566
* -
529567
*/
530-
static int worker_run_exit(int fd, struct ev_loop *ev_base, struct ev_signal *ev_sigint, struct ev_io *ev_accept, int retval)
568+
static int worker_run_exit(int fd, struct ev_loop *ev_base, struct worker_signal *ev_signals, int nr_signals, struct ev_io *ev_accept, int retval)
531569
{
532-
DBG_FUNC(NULL, "%d, %p, %p, %p, %d", fd, ev_base, ev_sigint, ev_accept, retval);
570+
int i;
571+
572+
DBG_FUNC(NULL, "%d, %p, %p, %d, %p, %d", fd, ev_base, ev_signals, nr_signals, ev_accept, retval);
533573

534574
if (ev_is_active(ev_accept) || ev_is_pending(ev_accept))
535575
ev_io_stop(ev_base, ev_accept);
536576

537-
if (ev_is_active(ev_sigint) || ev_is_pending(ev_sigint))
538-
ev_signal_stop(ev_base, ev_sigint);
577+
for (i = 0; i < nr_signals; i++)
578+
if (ev_is_active(&(ev_signals[i].signal)) || ev_is_pending(&(ev_signals[i].signal)))
579+
ev_signal_stop(ev_base, &(ev_signals[i].signal));
539580

540581
if (_nNULL(ev_base) && !ev_is_default_loop(ev_base))
541582
ev_loop_destroy(ev_base);
@@ -562,11 +603,18 @@ static int worker_run_exit(int fd, struct ev_loop *ev_base, struct ev_signal *ev
562603
*/
563604
int worker_run(void)
564605
{
565-
struct ev_timer ev_runtime;
566-
struct ev_loop *ev_base;
567-
struct ev_io ev_accept;
568-
struct ev_signal ev_sigint;
569-
int rc, i, fd = -1;
606+
struct worker_signal ev_signals[] = {
607+
{ .signum = SIGHUP, .func = worker_signal_stop_cb },
608+
{ .signum = SIGINT, .func = worker_signal_stop_cb },
609+
{ .signum = SIGPIPE, .func = worker_signal_ignore_cb },
610+
{ .signum = SIGTERM, .func = worker_signal_stop_cb },
611+
{ .signum = SIGUSR1, .func = worker_signal_stop_cb },
612+
{ .signum = SIGUSR2, .func = worker_signal_ignore_cb },
613+
};
614+
struct ev_timer ev_runtime;
615+
struct ev_loop *ev_base;
616+
struct ev_io ev_accept;
617+
int rc, i, fd = -1;
570618

571619
DBG_FUNC(NULL, "");
572620

@@ -576,7 +624,8 @@ int worker_run(void)
576624
return EX_SOFTWARE;
577625
}
578626

579-
(void)memset(&ev_sigint, 0, sizeof(ev_sigint));
627+
for (i = 0; i < TABLESIZE(ev_signals); i++)
628+
(void)memset(&(ev_signals[i].signal), 0, sizeof(ev_signals[0].signal));
580629
(void)memset(&ev_accept, 0, sizeof(ev_accept));
581630

582631
ev_base = ev_default_loop(cfg.ev_backend);
@@ -588,26 +637,24 @@ int worker_run(void)
588637

589638
W_DBG(WORKER, NULL, " libev: using backend '%s'", ev_backend_type(ev_base));
590639

591-
(void)signal(SIGPIPE, SIG_IGN);
592-
593640
fd = create_server_socket();
594641
if (_ERROR(fd)) {
595642
w_log(NULL, _F("Failed to create server socket"));
596643

597-
return worker_run_exit(fd, ev_base, &ev_sigint, &ev_accept, EX_SOFTWARE);
644+
return worker_run_exit(fd, ev_base, ev_signals, TABLESIZE(ev_signals), &ev_accept, EX_SOFTWARE);
598645
}
599646

600647
if (_ERROR(socket_set_nonblocking(fd))) {
601648
w_log(NULL, _F("Failed to set client socket to non-blocking: %m"));
602649

603-
return worker_run_exit(fd, ev_base, &ev_sigint, &ev_accept, EX_SOFTWARE);
650+
return worker_run_exit(fd, ev_base, ev_signals, TABLESIZE(ev_signals), &ev_accept, EX_SOFTWARE);
604651
}
605652

606653
prg.workers = calloc(cfg.num_workers, sizeof(*(prg.workers)));
607654
if (_NULL(prg.workers)) {
608655
w_log(NULL, _F("Failed to allocate memory for workers: %m"));
609656

610-
return worker_run_exit(fd, ev_base, &ev_sigint, &ev_accept, EX_SOFTWARE);
657+
return worker_run_exit(fd, ev_base, ev_signals, TABLESIZE(ev_signals), &ev_accept, EX_SOFTWARE);
611658
}
612659

613660
for (i = 0; i < cfg.num_workers; i++) {
@@ -623,8 +670,10 @@ int worker_run(void)
623670
ev_io_init(&ev_accept, worker_accept_cb, fd, EV_READ);
624671
ev_io_start(ev_base, &ev_accept);
625672

626-
ev_signal_init(&ev_sigint, worker_sigint_cb, SIGINT);
627-
ev_signal_start(ev_base, &ev_sigint);
673+
for (i = 0; i < TABLESIZE(ev_signals); i++) {
674+
ev_signal_init(&(ev_signals[i].signal), ev_signals[i].func, ev_signals[i].signum);
675+
ev_signal_start(ev_base, &(ev_signals[i].signal));
676+
}
628677

629678
if (cfg.runtime_us > 0) {
630679
ev_timer_init(&ev_runtime, worker_runtime_cb, cfg.runtime_us / 1e6, 0.0);
@@ -652,7 +701,7 @@ int worker_run(void)
652701
W_DBG(WORKER, NULL, " Worker %02d: terminated (%d)", w->id, rc);
653702
}
654703

655-
return worker_run_exit(fd, ev_base, &ev_sigint, &ev_accept, EX_OK);
704+
return worker_run_exit(fd, ev_base, ev_signals, TABLESIZE(ev_signals), &ev_accept, EX_OK);
656705
}
657706

658707
/*

0 commit comments

Comments
 (0)