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?