12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- #include <errno.h>
- #include "pthreadP.h"
- #include <atomic.h>
- int
- __pthread_setcanceltype (type, oldtype)
- 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)
|