Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Fixed the race condition in CS & NCCE

...

Code Block
bgColor#ffcccc
volatile int a, b;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t mut_sig = PTHREAD_COND_INITIALIZER;

void main(void) {
  int j;

  pthread_mutex_lock(&mut);
  pthread_create(&thread_identifier,NULL,(void*)thread, NULL);

  /* wait until canceltype is set */
  pthread_cond_wait(&mut_sig, &mut);
  pthread_mutex_unlock(&mut);

  /* do stuff, like data input */
  j = getc(STDIN);
  /* since we don't know when the character is read in, the program could continue at any time */
  pthread_cancel(thread_identifier);

  printf("a: %i | b: %i", a, b);

  /* clean up */
  pthread_mutex_destroy(&mut);
  pthread_cond_destroy(&mut_sig);
}

void thread(void) {
  int i, c;

  /* set the cancelability flag during mutex. */
  /* this guarantees this block calls after pthread_cond_wait() and, more importantly, before pthread_cancel() */
  pthread_mutex_lock(&mut);
  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&i);
  pthread_cond_signal(&mut_sig);
  pthread_mutex_unlock(&mut);

  while (1)
  {
    c = b;
    b = a;
    a = c;
  }
}

...

Code Block
bgColor#ccccff
volatile int a, b;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t mut_sig = PTHREAD_COND_INITIALIZER;

void main(void) {
  int j;

  pthread_mutex_lock(&mut);
  pthread_create(&thread_identifier,NULL,(void*)thread, NULL);

  /* wait until canceltype is set */
  pthread_cond_wait(&mut_sig, &mut);
  pthread_mutex_unlock(&mut);

  /* do stuff, like data input */
  j = getc(STDIN);
  /* since we don't know when the character is read in, the program could continue at any time */
  pthread_cancel(thread_identifier);

  /* pthread_join waits for the thread to finish up before continuing */
  pthread_join(thread_identifier, 0);

  printf("a: %i | b: %i", a, b);

  /* clean up */
  pthread_mutex_destroy(&mut);
  pthread_cond_destroy(&mut_sig);
}
void thread(void) {
  int i, c;

  /* set the cancelability flag during mutex. */
  /* this guarantees this block calls after pthread_cond_wait() and, more importantly, before pthread_cancel() */
  pthread_mutex_lock(&mut);
  pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,&i);
  pthread_cond_signal(&mut_sig);
  pthread_mutex_unlock(&mut);

  while (1)
  {
    c = b;
    b = a;
    a = c;
    /* now we're safe to cancel, creating cancel point */
    pthread_testcancel();
  }
}

...

In Java, similar reasoning resulted in the deprecation of Thread.stop() and appears in the Java Secure Coding Standard as CON13-J. Ensure that threads are stopped cleanlyDo not use Thread.stop() to terminate threads .

References

Wiki Markup
\[[MKS|AA. References#MKS]\] [{{pthread_cancel()}} Man Page|http://www.mkssoftware.com/docs/man3/pthread_cancel.3.asp]
\[[Open Group 04|AA. References#Open Group 04]\] [Threads Overview|http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html]