diff options
author | Ulrich Drepper <drepper@redhat.com> | 2009-05-15 20:42:36 -0700 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2009-05-15 20:42:36 -0700 |
commit | 9437b427cec6266abd303983848549a5c4ba0d0a (patch) | |
tree | 7d3c7df6abb9a33d4f35a3dc20baa59ff1a53ea1 /nptl/pthread_cancel.c | |
parent | bbc5d74dd0bd1c3dbe7ea8515f081dc7e318272c (diff) | |
download | glibc-9437b427cec6266abd303983848549a5c4ba0d0a.tar.gz glibc-9437b427cec6266abd303983848549a5c4ba0d0a.tar.xz glibc-9437b427cec6266abd303983848549a5c4ba0d0a.zip |
Fix change to prevent cancel signal in unsafe places.
The bits tested to decide when to delay the return when switching off async cancel mode were wrong. Fix that. Also close a race condition in pthread_cancel where the bit indicating the cancellation is unconditionally set even if the cancel type might have changed.
Diffstat (limited to 'nptl/pthread_cancel.c')
-rw-r--r-- | nptl/pthread_cancel.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c index a13af56b37..55bb0da922 100644 --- a/nptl/pthread_cancel.c +++ b/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. @@ -44,6 +44,7 @@ pthread_cancel (th) int newval; do { + again: oldval = pd->cancelhandling; newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK; @@ -59,7 +60,10 @@ pthread_cancel (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. */ |