I'm currently researching using sigprocmask
to block certain signals (in this case, SIGALRM
and SIGCHLD
) when a critical segment of code is executing. Both of the signal handlers associated with these signals will access and modify a central data structure, so it is crucial that I prevent them from accessing it while the main process is working on it.
At the moment, my plan would be to simply disable these signals at the start of the critical section of code, and then re-enable them at the end.
void criticalFunction(void) {
// disable signals with sigprocmask
// critical code
// enable signals with sigprocmask
}
However, the signal handler's for the signals which will be blocked also call criticalFunction
. What will happen when they call the sigprocmask
function and enable blocking on their own signals? Will they stall or keep executing? (Or some third condition..)
The only note I was able to find about this is the following:
If sigprocmask() is called in a signal handler, returning from the handler may undo the work of sigprocmask() by restoring the original pending signal mask. (http://www.mkssoftware.com/docs/man3/sigprocmask.3.asp)
(This is a follow-up question to my previous question: Signal handler accessing queue data structure (race condition?))
Your design is wrong when you say that "signal handlers [...] call
criticalFunction
." Signal handlers should never do any serious amount of work. They're not made for that.The only thing you should reasonably do from within a signal handler is to modify a variable of type
sigatomic_t
. This is usually used to set a flag, and the remainder of your code (e.g. the main loop) just has to check periodically if any flags have been set.I think it is in fact undefined behaviour if a signal handler does anything other than that. Update: From
man 2 signal
: "Seesignal(7)
for a list of the async-signal-safe functions that can be safely called from inside a signal handler."