From a032a6587011cbdac8c2f7e11f15dc4e592bbb55 Mon Sep 17 00:00:00 2001 From: Austin Foxley Date: Tue, 16 Feb 2010 12:27:18 -0800 Subject: mass sync with glibc nptl Signed-off-by: Austin Foxley --- libpthread/nptl/cancellation.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'libpthread/nptl/cancellation.c') diff --git a/libpthread/nptl/cancellation.c b/libpthread/nptl/cancellation.c index 1d28d383f..eac7973db 100644 --- a/libpthread/nptl/cancellation.c +++ b/libpthread/nptl/cancellation.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -70,14 +70,13 @@ __pthread_disable_asynccancel (int oldtype) return; struct pthread *self = THREAD_SELF; + int newval; + int oldval = THREAD_GETMEM (self, cancelhandling); while (1) { - int newval = oldval & ~CANCELTYPE_BITMASK; - - if (newval == oldval) - break; + newval = oldval & ~CANCELTYPE_BITMASK; int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval, oldval); @@ -87,4 +86,15 @@ __pthread_disable_asynccancel (int oldtype) /* Prepare the next round. */ oldval = curval; } + + /* We cannot return when we are being canceled. Upon return the + thread might be things which would have to be undone. The + following loop should loop until the cancellation signal is + delivered. */ + while (__builtin_expect ((newval & (CANCELING_BITMASK | CANCELED_BITMASK)) + == CANCELING_BITMASK, 0)) + { + lll_futex_wait (&self->cancelhandling, newval, LLL_PRIVATE); + newval = THREAD_GETMEM (self, cancelhandling); + } } -- cgit v1.2.3