...
This non-compliant code example also violates SIG31-C. Do not access or modify shared objects in signal handlers.
Non-Compliant Code Example (External finite state machine)
This non-compliant code example moves the finite state machine out of the signal handler, making the handler asynchronous-safe.
Code Block | ||
---|---|---|
| ||
#include <signal.h>
volatile sig_atomic_t sig1 = 0;
volatile sig_atomic_t sig2 = 0;
void handler(int signum) {
if (signum == SIGUSR1) {
sig1 = 1;
}
else if (signum == SIGUSR2) {
sig2 = 1;
}
}
int main(void) {
int state = 0;
signal(SIGUSR1, handler);
signal(SIGUSR2, handler);
while (state != 2) {
/* do nothing or give up CPU for a while */
if (state == 0 && sig1) {
state = 1;
sig2 = 0;
}
if (state == 1 && sig2) {
state = 2;
}
}
/* ... */
return 0;
}
|
There is still a race condition in this code where a SIGUSR2
sent immediately after a SIGUSR1
is ignored. This is because the SIGUSR2
is processed before the while loop sets the state to 1 and sig2
to 0, which erases the evidence of SIGUSR2
. To eliminate this race condition, the OS must queue subsequent signals while one signal is being handled, and the finite state machine must be handled by the signal handler.
Compliant Solution (POSIX)
...