diff options
Diffstat (limited to 'libpthread/nptl/pthread_cancel.c')
-rw-r--r-- | libpthread/nptl/pthread_cancel.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/libpthread/nptl/pthread_cancel.c b/libpthread/nptl/pthread_cancel.c index 31885234e..4a958bcde 100644 --- a/libpthread/nptl/pthread_cancel.c +++ b/libpthread/nptl/pthread_cancel.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -26,7 +26,8 @@ int -pthread_cancel (pthread_t th) +pthread_cancel ( + pthread_t th) { volatile struct pthread *pd = (volatile struct pthread *) th; @@ -43,6 +44,7 @@ pthread_cancel (pthread_t th) int newval; do { + again: oldval = pd->cancelhandling; newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK; @@ -58,7 +60,10 @@ pthread_cancel (pthread_t th) if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval)) { /* Mark the cancellation as "in progress". */ - atomic_bit_set (&pd->cancelhandling, CANCELING_BIT); + if (atomic_compare_and_exchange_bool_acq (&pd->cancelhandling, + oldval | CANCELING_BITMASK, + oldval)) + goto again; /* The cancellation handler will take care of marking the thread as canceled. */ |