Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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
bgColor#ffcccc

#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)

...