1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- #include <errno.h>
- #include "pthreadP.h"
- #include <atomic.h>
- int
- attribute_protected
- __pthread_setcanceltype (
- int type,
- int *oldtype)
- {
- 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);
-
- if (oldtype != NULL)
- *oldtype = ((oldval & CANCELTYPE_BITMASK)
- ? PTHREAD_CANCEL_ASYNCHRONOUS : PTHREAD_CANCEL_DEFERRED);
-
- if (oldval == newval)
- break;
-
- 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;
- }
-
- oldval = curval;
- }
- return 0;
- }
- strong_alias (__pthread_setcanceltype, pthread_setcanceltype)
|