summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_thr.c
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2006-12-04 14:15:12 +0000
committerdavidxu <davidxu@FreeBSD.org>2006-12-04 14:15:12 +0000
commit22a81fc246efb2668eddcb6ccd27129feaa5910c (patch)
tree96b0dbfdbf6b0cc6b79bddb39c447b7346ae3471 /sys/kern/kern_thr.c
parent1f83d70e044c52a4ed74fe1aae9685e70ead1409 (diff)
downloadFreeBSD-src-22a81fc246efb2668eddcb6ccd27129feaa5910c.zip
FreeBSD-src-22a81fc246efb2668eddcb6ccd27129feaa5910c.tar.gz
if a thread blocked on userland condition variable is
pthread_cancel()ed, it is expected that the thread will not consume a pthread_cond_signal(), therefor, we use thr_wake() to mark a flag, the flag tells a thread calling do_cv_wait() in umtx code to not block on a condition variable. Thread library is expected that once a thread detected itself is in pthread_cond_wait, it will call the thr_wake() for itself in its SIGCANCEL handler.
Diffstat (limited to 'sys/kern/kern_thr.c')
-rw-r--r--sys/kern/kern_thr.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c
index 29c7614..37e3df2 100644
--- a/sys/kern/kern_thr.c
+++ b/sys/kern/kern_thr.c
@@ -402,6 +402,12 @@ kern_thr_suspend(struct thread *td, struct timespec *tsp)
TIMESPEC_TO_TIMEVAL(&tv, tsp);
hz = tvtohz(&tv);
}
+
+ if (td->td_pflags & TDP_WAKEUP) {
+ td->td_pflags &= ~TDP_WAKEUP;
+ return (0);
+ }
+
PROC_LOCK(td->td_proc);
if ((td->td_flags & TDF_THRWAKEUP) == 0)
error = msleep((void *)td, &td->td_proc->p_mtx, PCATCH, "lthr",
@@ -430,6 +436,11 @@ thr_wake(struct thread *td, struct thr_wake_args *uap)
struct proc *p;
struct thread *ttd;
+ if (uap->id == td->td_tid) {
+ td->td_pflags |= TDP_WAKEUP;
+ return (0);
+ }
+
p = td->td_proc;
PROC_LOCK(p);
ttd = thread_find(p, uap->id);
OpenPOWER on IntegriCloud