diff options
Diffstat (limited to 'pthread/pt-cancel.c')
-rw-r--r-- | pthread/pt-cancel.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/pthread/pt-cancel.c b/pthread/pt-cancel.c index d19c557..96c77f7 100644 --- a/pthread/pt-cancel.c +++ b/pthread/pt-cancel.c @@ -31,10 +31,33 @@ pthread_cancel (pthread_t t) if (! p) return ESRCH; + __pthread_mutex_lock (&p->cancel_lock); + if (p->cancel_pending) + { + __pthread_mutex_unlock (&p->cancel_lock); + return 0; + } + p->cancel_pending = 1; - if (p->cancel_state == PTHREAD_CANCEL_ENABLE - && p->cancel_type == PTHREAD_CANCEL_ASYNCHRONOUS) + + if (p->cancel_state != PTHREAD_CANCEL_ENABLE) + { + __pthread_mutex_unlock (&p->cancel_lock); + return 0; + } + + if (p->cancel_type == PTHREAD_CANCEL_ASYNCHRONOUS) + /* CANCEL_LOCK is unlocked by this call. */ err = __pthread_do_cancel (p); + else + { + if (p->cancel_hook != NULL) + /* Thread blocking on a cancellation point. Invoke hook to unblock. + See __pthread_cond_timedwait_internal. */ + p->cancel_hook (p->cancel_hook_arg); + + __pthread_mutex_unlock (&p->cancel_lock); + } return err; } |