fix: server shutdown on SIGTERM — use sigaction without SA_RESTART
CI / lint (pull_request) Successful in 7s
CI / sanitizers (address) (pull_request) Successful in 14s
CI / sanitizers (undefined) (pull_request) Successful in 14s
CI / fuzz-build (pull_request) Successful in 12s
CI / coverage (pull_request) Successful in 9s
CI / build-and-test (pull_request) Failing after 58s
CI / valgrind (pull_request) Successful in 11s
CI / lint (pull_request) Successful in 7s
CI / sanitizers (address) (pull_request) Successful in 14s
CI / sanitizers (undefined) (pull_request) Successful in 14s
CI / fuzz-build (pull_request) Successful in 12s
CI / coverage (pull_request) Successful in 9s
CI / build-and-test (pull_request) Failing after 58s
CI / valgrind (pull_request) Successful in 11s
The previous code used signal() to register the cleanup handler, but on glibc (and many other modern libc implementations), signal() implicitly sets SA_RESTART, which causes blocking syscalls like accept() to be transparently restarted after the handler runs. As a result, accept() never returns EINTR, the accept loop never breaks, and the server never exits on SIGTERM/SIGINT. Fix by using sigaction() with sa_flags = 0 (no SA_RESTART), guaranteeing that accept() is interrupted and returns EINTR, allowing the loop to exit and the server to shut down cleanly.
This commit is contained in:
+6
-2
@@ -180,8 +180,12 @@ int main(int argc, char* argv[]) {
|
|||||||
log_message(LOG_LEVEL_WARNING, "--ca has no effect without --tls");
|
log_message(LOG_LEVEL_WARNING, "--ca has no effect without --tls");
|
||||||
}
|
}
|
||||||
|
|
||||||
signal(SIGINT, cleanup);
|
struct sigaction sa;
|
||||||
signal(SIGTERM, cleanup);
|
sigemptyset(&sa.sa_mask);
|
||||||
|
sa.sa_handler = cleanup;
|
||||||
|
sa.sa_flags = 0; /* Do NOT set SA_RESTART — we need accept() to return EINTR */
|
||||||
|
sigaction(SIGINT, &sa, NULL);
|
||||||
|
sigaction(SIGTERM, &sa, NULL);
|
||||||
g_server = server_create(port);
|
g_server = server_create(port);
|
||||||
if (g_server == NULL) {
|
if (g_server == NULL) {
|
||||||
log_message(LOG_LEVEL_ERROR, "Failed to create server");
|
log_message(LOG_LEVEL_ERROR, "Failed to create server");
|
||||||
|
|||||||
Reference in New Issue
Block a user