diff options
author | davidxu <davidxu@FreeBSD.org> | 2008-10-24 01:03:31 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2008-10-24 01:03:31 +0000 |
commit | e66e7ee6bbe3a5b6d25e28eba2984a209a1d69da (patch) | |
tree | 155e2292d15151c02e028236ab56960d1587f709 /sys/kern/subr_sleepqueue.c | |
parent | 2e4682de7537d80bbc49cc4b8072dd2d237e2a9d (diff) | |
download | FreeBSD-src-e66e7ee6bbe3a5b6d25e28eba2984a209a1d69da.zip FreeBSD-src-e66e7ee6bbe3a5b6d25e28eba2984a209a1d69da.tar.gz |
partly revert revision 184199, because TDF_NEEDSIGCHK is persitent
when thread is in kernel mode, it can cause dead loop, now unlock
process lock after acquired sleep queue lock and thread lock to
avoid the problem. This means TDF_NEEDSIGCHK and TDF_NEEDSUSPCHK must
be set with process lock and thread lock being hold at same time.
Diffstat (limited to 'sys/kern/subr_sleepqueue.c')
-rw-r--r-- | sys/kern/subr_sleepqueue.c | 15 |
1 files changed, 5 insertions, 10 deletions
diff --git a/sys/kern/subr_sleepqueue.c b/sys/kern/subr_sleepqueue.c index 751fa64..0f00a70 100644 --- a/sys/kern/subr_sleepqueue.c +++ b/sys/kern/subr_sleepqueue.c @@ -396,7 +396,6 @@ sleepq_catch_signals(void *wchan, int pri) return (0); } -catch_sig: thread_unlock(td); mtx_unlock_spin(&sc->sc_lock); CTR3(KTR_PROC, "sleepq catching signals: thread %p (pid %ld, %s)", @@ -416,19 +415,15 @@ catch_sig: ret = ERESTART; mtx_unlock(&ps->ps_mtx); } - PROC_UNLOCK(p); mtx_lock_spin(&sc->sc_lock); thread_lock(td); - if (ret != 0) - goto out; - if ((td->td_flags & (TDF_NEEDSIGCHK | TDF_NEEDSUSPCHK)) != 0) - goto catch_sig; - - sleepq_switch(wchan, pri); - return (0); + PROC_UNLOCK(p); + if (ret == 0) { + sleepq_switch(wchan, pri); + return (0); + } -out: /* * There were pending signals and this thread is still * on the sleep queue, remove it from the sleep queue. |