summaryrefslogtreecommitdiffstats
path: root/lib/libthr/thread/thr_cond.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libthr/thread/thr_cond.c')
-rw-r--r--lib/libthr/thread/thr_cond.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/lib/libthr/thread/thr_cond.c b/lib/libthr/thread/thr_cond.c
index 85eecaa..95970d9 100644
--- a/lib/libthr/thread/thr_cond.c
+++ b/lib/libthr/thread/thr_cond.c
@@ -162,6 +162,14 @@ cond_cancel_handler(void *arg)
_mutex_cv_lock(info->mutex, info->count);
}
+/*
+ * Cancellation behaivor:
+ * Thread may be canceled at start, if thread is canceled, it means it
+ * did not get a wakeup from pthread_cond_signal(), otherwise, it is
+ * not canceled.
+ * Thread cancellation never cause wakeup from pthread_cond_signal()
+ * to be lost.
+ */
static int
cond_wait_common(pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *abstime, int cancel)
@@ -180,6 +188,8 @@ cond_wait_common(pthread_cond_t *cond, pthread_mutex_t *mutex,
(ret = init_static(curthread, cond)) != 0))
return (ret);
+ _thr_testcancel(curthread);
+
cv = *cond;
THR_UMUTEX_LOCK(curthread, &cv->c_lock);
ret = _mutex_cv_unlock(mutex, &info.count);
@@ -200,10 +210,10 @@ cond_wait_common(pthread_cond_t *cond, pthread_mutex_t *mutex,
if (cancel) {
THR_CLEANUP_PUSH(curthread, cond_cancel_handler, &info);
- _thr_cancel_enter_defer(curthread);
+ _thr_cancel_enter_defer(curthread, 0);
ret = _thr_ucond_wait(&cv->c_kerncv, &cv->c_lock, tsp, 1);
info.cond = NULL;
- _thr_cancel_leave_defer(curthread, ret);
+ _thr_cancel_leave_defer(curthread, (ret != 0));
THR_CLEANUP_POP(curthread, 0);
} else {
ret = _thr_ucond_wait(&cv->c_kerncv, &cv->c_lock, tsp, 0);
OpenPOWER on IntegriCloud