Back to index

glibc  2.9
Functions
pthread_setcanceltype.c File Reference
#include <errno.h>
#include "pthreadP.h"
#include <atomic.h>

Go to the source code of this file.

Functions

int __pthread_setcanceltype (int type, int *oldtype)

Function Documentation

int __pthread_setcanceltype ( int  type,
int oldtype 
)

Definition at line 26 of file pthread_setcanceltype.c.

{
  volatile struct pthread *self;

  if (type < PTHREAD_CANCEL_DEFERRED || type > PTHREAD_CANCEL_ASYNCHRONOUS)
    return EINVAL;

  self = THREAD_SELF;

  int oldval = THREAD_GETMEM (self, cancelhandling);
  while (1)
    {
      int newval = (type == PTHREAD_CANCEL_ASYNCHRONOUS
                  ? oldval | CANCELTYPE_BITMASK
                  : oldval & ~CANCELTYPE_BITMASK);

      /* Store the old value.  */
      if (oldtype != NULL)
       *oldtype = ((oldval & CANCELTYPE_BITMASK)
                  ? PTHREAD_CANCEL_ASYNCHRONOUS : PTHREAD_CANCEL_DEFERRED);

      /* Avoid doing unnecessary work.  The atomic operation can
        potentially be expensive if the memory has to be locked and
        remote cache lines have to be invalidated.  */
      if (oldval == newval)
       break;

      /* Update the cancel handling word.  This has to be done
        atomically since other bits could be modified as well.  */
      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
                                         oldval);
      if (__builtin_expect (curval == oldval, 1))
       {
         if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
           {
             THREAD_SETMEM (self, result, PTHREAD_CANCELED);
             __do_cancel ();
           }

         break;
       }

      /* Prepare for the next round.  */
      oldval = curval;
    }

  return 0;
}

Here is the call graph for this function: