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:
parent
8733f60328
commit
81fda5bdd5
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user