From 48ce9170b057ddd2165b0239a92aede15849f7a3 Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Mon, 12 Jun 2023 01:42:08 +0200 Subject: use signalfd to stop on SIGTERM Is this an overkill? I don't know. The thing is, correctly intercepting SIGTERM (also SIGINT, etc.) is incredibly tricky. For example, before this commit, my I/O loops in server.c and worker.c were inherently racy. This was immediately obvious if you tried to run the tests. The tests (especially the Valgrind flavour) would run a worker, wait until it prints a "Waiting for a new command" line, and try to kill it using SIGTERM. The problem is, the global_stop_flag check could have already been executed by the worker, and it would hang forever in recv(). The solution seems to be to use signalfd and select()/poll(). I've never used either before, but it seems to work well enough - at least the very same tests pass and don't hang now. --- src/command.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/command.h') diff --git a/src/command.h b/src/command.h index 90facbb..3d13abd 100644 --- a/src/command.h +++ b/src/command.h @@ -8,6 +8,7 @@ #ifndef __COMMAND_H__ #define __COMMAND_H__ +#include "event_loop.h" #include "msg.h" #include @@ -28,6 +29,8 @@ void cmd_dispatcher_destroy(struct cmd_dispatcher *); int cmd_dispatcher_handle(const struct cmd_dispatcher *, const struct msg *command, struct msg **response); +int cmd_dispatcher_add_to_event_loop(const struct cmd_dispatcher *, struct event_loop *, int fd); + struct cmd_conn_ctx { int fd; void *arg; -- cgit v1.2.3