Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: changed code examples

...

Noncompliant Code Example

This code raises sets a signal within handler, while also setting a child thread to do work. This is meant to terminate the program, but results in undefined behavior.

Code Block
bgColor#ffcccc
langc
volatile sig_atomic_t flag = 0;

void handler(int signum) {
  flag = 1;
}


void func(void *data) {
  /*/ ... */
  if (thread_should_exit) {keep running until user sends SIGUSR1
   while raise( SIGTERM!flag);  // Undefined! {
  }
  /* ... */
  }
}


int main(void) {
  signal(SIGUSR1, handler); // Undefined!
  int result;
  thrd_t thread;
  
  int result;
  if ((result = thrd_create(&tid, func, NULL)) != thrd_success) {
    /* Handle Error */
  }

  /* ... */

  return 0;
}

Compliant Solution

This code terminates the child thread rather than raising a signal. This has the same effect as the noncompliant code example, but is well-defined in C11dispenses with the signal handler, and uses an atomic_flag to indicate when the child thread should terminate its loop.

Code Block
bgColor#ccccff
langc
atomic_flag flag = ATOMIC_VAR_INIT;


void func(void *data) {
  /*/ ... */
  if (thread_should_exit) {keep running until user sends SIGUSR1
   while thrd_exit(0!flag);  // OK{
  }
  /* ... */
  }
}


int main(void) {
  int result;
  thrd_t thread;
  
  int result;
  if ((result = thrd_create(&tid, func, NULL)) != thrd_success) {
    /* Handle Error */
  }


  /* ... */


  /* Set flag when done */
  while (!atomic_flag_test_and_set( &flag)) { /* try again */ }


  return 0;
}

Exceptions

CON37:EX0: Platforms that provide defined behavior when multithreaded programs use custom signal handlers are exempt from this rule. This would include POSIX, for example.

...