Vermeidung eines data races mit signal handlern
-
Hallöchen,
ich wollte mal fragen, ob jemandem eine bessere Herangehensweise zu dem Code hier einfällt:#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <stdbool.h> #include <sys/epoll.h> static sig_atomic_t volatile running = true; static void signal_handler(int sig) { (void)sig; running = false; } int main(void) { struct sigaction sa = { .sa_handler = &signal_handler }; sigemptyset(&sa.sa_mask); sigaction(SIGINT, &sa, 0); sigaction(SIGTERM, &sa, 0); sigset_t sigmask; sigemptyset(&sigmask); sigaddset(&sigmask, SIGINT); sigaddset(&sigmask, SIGTERM); int epollfd; // ... init stuff ... while (running) { sigset_t oldmask; sigprocmask(SIG_BLOCK, &sigmask, &oldmask); if (!running) { sigprocmask(SIG_SETMASK, &oldmask, 0); break; } struct epoll_event event; int ret = epoll_pwait(epollfd, &event, 1, -1, &oldmask); int err = errno; sigprocmask(SIG_SETMASK, &oldmask, 0); if (ret == -1 && err == EINTR) continue; // ... do stuff ... } // ... cleanup stuff ... }
Irgendwie sieht mir dieses hin und her mit dem
sigprocmask
sehr umständlich aus um die race condition zu vermeiden, die entsteht, wenn man es so macht:while (running) { // Wenn hier das Signal kommt, blockiert epoll für immer. struct epoll_event event; int ret = epoll_wait(epollfd, &event, 1, -1); }
Fällt jemandem was besseres ein, oder ist das so in Ordnung?