Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Am I over-engineering per-thread signal blocking?

In my applications, I generally want to intercept SIGINT and SIGTERM signals in order to close down gracefully.

In order to prevent worker threads from "stealing" signals, I do this in the entrypoint for each:

// Block signals in this thread
sigset_t signal_set;
sigaddset(&signal_set, SIGINT);
sigaddset(&signal_set, SIGTERM);
sigaddset(&signal_set, SIGHUP);
sigaddset(&signal_set, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &signal_set, NULL);

If I don't, when I perform Ctrl+C, some of the time (it's unspecified as to which thread will get the signal) my handlers in the base thread won't be invoked — instead, the signal just terminates the process from within the worker thread. This is obviously not cool.

So I have one signal-handling thread and block signals everywhere else.

However, I don't notice anybody else doing this, it's easy enough to forget to do, and it's also not entirely portable. Is there some more simple trick I'm missing?


References:

  • POSIX threads and signals
  • http://www.linuxprogrammingblog.com/all-about-linux-signals?page=11
  • http://www.unixguide.net/network/socketfaq/2.19.shtml
like image 918
Lightness Races in Orbit Avatar asked Nov 21 '12 17:11

Lightness Races in Orbit


1 Answers

I find it a perfectly reasonable thing to do.

You could block the signals in main, before any other thread is spawned. The spawned threads will inherit the creator thread signal mask and you can unblock signals only in the signal handling thread (being careful only if that thread spawns other threads as well).

Or you can leave the signals blocked everywhere and explicitly handle them via sigwait and friends in the signal handling thread.

like image 94
chill Avatar answered Oct 07 '22 21:10

chill