1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00

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.
This commit is contained in:
Ulrich Drepper
2009-05-15 20:42:36 -07:00
parent bbc5d74dd0
commit 9437b427ce
4 changed files with 16 additions and 14 deletions

View File

@ -88,10 +88,6 @@ __libc_disable_asynccancel (int oldtype)
struct pthread *self = THREAD_SELF;
int newval;
#ifdef THREAD_ATOMIC_AND
THREAD_ATOMIC_AND (self, cancelhandling, ~CANCELTYPE_BITMASK);
newval = THREAD_GETMEM (self, cancelhandling);
#else
int oldval = THREAD_GETMEM (self, cancelhandling);
while (1)
@ -109,13 +105,13 @@ __libc_disable_asynccancel (int oldtype)
/* Prepare the next round. */
oldval = curval;
}
#endif
/* 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 & CANCELED_BITMASK, 0))
while (__builtin_expect ((newval & (CANCELING_BITMASK | CANCELED_BITMASK))
== CANCELING_BITMASK, 0))
{
lll_futex_wait (&self->cancelhandling, newval, LLL_PRIVATE);
newval = THREAD_GETMEM (self, cancelhandling);