o The mutex locking functions aren't normally cancellation points. But,

we still have to DTRT when an asynchronously cancellable thread is
  cancelled while waiting for a mutex.
o While dequeueing a waiting mutex don't skip a thread if it has
  a cancel pending. Only skip it if it is also async cancellable.
This commit is contained in:
Mike Makonnen 2004-03-26 14:47:54 +00:00
parent 8733f60328
commit 81fda5bdd5

View File

@ -324,7 +324,6 @@ mutex_lock_common(pthread_mutex_t * mutex, int nonblock,
PTHREAD_ASSERT(((*mutex)->m_protocol >= PTHREAD_PRIO_NONE && PTHREAD_ASSERT(((*mutex)->m_protocol >= PTHREAD_PRIO_NONE &&
(*mutex)->m_protocol <= PTHREAD_PRIO_PROTECT), (*mutex)->m_protocol <= PTHREAD_PRIO_PROTECT),
"Invalid mutex protocol"); "Invalid mutex protocol");
pthread_testcancel();
_SPINLOCK(&(*mutex)->lock); _SPINLOCK(&(*mutex)->lock);
/* /*
@ -418,7 +417,6 @@ mutex_lock_common(pthread_mutex_t * mutex, int nonblock,
_thread_critical_exit(curthread); _thread_critical_exit(curthread);
out: out:
_SPINUNLOCK(&(*mutex)->lock); _SPINUNLOCK(&(*mutex)->lock);
pthread_testcancel();
return (error); return (error);
} }
@ -771,7 +769,10 @@ mutex_queue_deq(pthread_mutex_t mutex)
* Only exit the loop if the thread hasn't been * Only exit the loop if the thread hasn't been
* cancelled. * cancelled.
*/ */
if ((pthread->cancelflags & PTHREAD_CANCELLING) == 0 && if (((pthread->cancelflags & PTHREAD_CANCELLING) == 0 ||
(pthread->cancelflags & PTHREAD_CANCEL_DISABLE) != 0 ||
((pthread->cancelflags & PTHREAD_CANCELLING) != 0 &&
(pthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) == 0)) &&
pthread->state == PS_MUTEX_WAIT) pthread->state == PS_MUTEX_WAIT)
break; break;
else else
@ -887,6 +888,14 @@ get_mcontested(pthread_mutex_t mutexp, const struct timespec *abstime)
_thread_critical_enter(curthread); _thread_critical_enter(curthread);
mutex_queue_enq(mutexp, curthread); mutex_queue_enq(mutexp, curthread);
do { do {
if ((curthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0 &&
(curthread->cancelflags & PTHREAD_CANCEL_DISABLE) == 0 &&
(curthread->cancelflags & PTHREAD_CANCELLING) != 0) {
mutex_queue_remove(mutexp, curthread);
_thread_critical_exit(curthread);
_SPINUNLOCK(&mutexp->lock);
pthread_testcancel();
}
PTHREAD_SET_STATE(curthread, PS_MUTEX_WAIT); PTHREAD_SET_STATE(curthread, PS_MUTEX_WAIT);
curthread->data.mutex = mutexp; curthread->data.mutex = mutexp;
_thread_critical_exit(curthread); _thread_critical_exit(curthread);