Back to index

glibc  2.9
Functions
cleanup_defer_compat.c File Reference
#include "pthreadP.h"

Go to the source code of this file.

Functions

void _pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer, void(*)(void *) routine, void *arg)
 strong_alias (_pthread_cleanup_push_defer, __pthread_cleanup_push_defer)

Function Documentation

void _pthread_cleanup_push_defer ( struct _pthread_cleanup_buffer buffer,
void (*) (void *)  routine,
void *  arg 
)

Definition at line 24 of file cleanup_defer_compat.c.

{
  struct pthread *self = THREAD_SELF;

  buffer->__routine = routine;
  buffer->__arg = arg;
  buffer->__prev = THREAD_GETMEM (self, cleanup);

  int cancelhandling = THREAD_GETMEM (self, cancelhandling);

  /* Disable asynchronous cancellation for now.  */
  if (__builtin_expect (cancelhandling & CANCELTYPE_BITMASK, 0))
    while (1)
      {
       int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
                                          cancelhandling
                                          & ~CANCELTYPE_BITMASK,
                                          cancelhandling);
       if (__builtin_expect (curval == cancelhandling, 1))
         /* Successfully replaced the value.  */
         break;

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

  buffer->__canceltype = (cancelhandling & CANCELTYPE_BITMASK
                       ? PTHREAD_CANCEL_ASYNCHRONOUS
                       : PTHREAD_CANCEL_DEFERRED);

  THREAD_SETMEM (self, cleanup, buffer);
}

Definition at line 59 of file cleanup_defer_compat.c.

{
  struct pthread *self = THREAD_SELF;

  THREAD_SETMEM (self, cleanup, buffer->__prev);

  int cancelhandling;
  if (__builtin_expect (buffer->__canceltype != PTHREAD_CANCEL_DEFERRED, 0)
      && ((cancelhandling = THREAD_GETMEM (self, cancelhandling))
         & CANCELTYPE_BITMASK) == 0)
    {
      while (1)
       {
         int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
                                            cancelhandling
                                            | CANCELTYPE_BITMASK,
                                            cancelhandling);
         if (__builtin_expect (curval == cancelhandling, 1))
           /* Successfully replaced the value.  */
           break;

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

      CANCELLATION_P (self);
    }

  /* If necessary call the cleanup routine after we removed the
     current cleanup block from the list.  */
  if (execute)
    buffer->__routine (buffer->__arg);
}