diff options
author | Ulrich Drepper <drepper@redhat.com> | 2002-12-08 08:25:05 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2002-12-08 08:25:05 +0000 |
commit | bdb04f922004ff8433591f138e40c09722836c45 (patch) | |
tree | 965b2db38d2cd7f9fb5114a10d53e3ddcc2bfad4 /nptl/cancellation.c | |
parent | 3335502bec2220c7d1e89929d489c1a91a1d862b (diff) | |
download | glibc-bdb04f922004ff8433591f138e40c09722836c45.tar.gz glibc-bdb04f922004ff8433591f138e40c09722836c45.tar.xz glibc-bdb04f922004ff8433591f138e40c09722836c45.zip |
Update.
* scripts/output-format.sed: Fix bug in one of the s expressions which used / for one too many things.
Diffstat (limited to 'nptl/cancellation.c')
-rw-r--r-- | nptl/cancellation.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/nptl/cancellation.c b/nptl/cancellation.c index 890b26ec4e..3cdc574880 100644 --- a/nptl/cancellation.c +++ b/nptl/cancellation.c @@ -20,6 +20,7 @@ #include <setjmp.h> #include <stdlib.h> #include "pthreadP.h" +#include "atomic.h" /* This function is responsible for calling all registered cleanup @@ -90,3 +91,64 @@ __cleanup_thread (struct pthread *self, char *currentframe) } } } + + +/* The next two functions are similar to pthread_setcanceltype() but + more specialized for the use in the cancelable functions like write(). + They do not need to check parameters etc. */ +int +attribute_hidden +__pthread_enable_asynccancel (void) +{ + struct pthread *self = THREAD_SELF; + int oldval; + + while (1) + { + oldval = THREAD_GETMEM (self, cancelhandling); + int newval = oldval | CANCELTYPE_BITMASK; + + if (newval == oldval) + break; + + if (atomic_compare_and_exchange_acq (&self->cancelhandling, newval, + oldval) == 0) + { + if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval)) + { + THREAD_SETMEM (self, result, PTHREAD_CANCELED); + __do_cancel (CURRENT_STACK_FRAME); + } + + break; + } + } + + return oldval; +} + + +void +attribute_hidden +__pthread_disable_asynccancel (int oldtype) +{ + /* If asynchronous cancellation was enabled before we do not have + anything to do. */ + if (oldtype & CANCELTYPE_BITMASK) + return; + + struct pthread *self = THREAD_SELF; + + while (1) + { + int oldval = THREAD_GETMEM (self, cancelhandling); + int newval = oldval & ~CANCELTYPE_BITMASK; + + if (newval == oldval) + break; + + if (atomic_compare_and_exchange_acq (&self->cancelhandling, newval, + oldval) == 0) + break; + } +} |