diff options
author | davidxu <davidxu@FreeBSD.org> | 2003-06-20 03:36:45 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2003-06-20 03:36:45 +0000 |
commit | 88ed270c3d7240b20e5769f4669bd23a48045308 (patch) | |
tree | 7148057315bf4342b048b81b471703121d100f86 | |
parent | c0a849442b33e0542e11f3216f85775d8c5402f7 (diff) | |
download | FreeBSD-src-88ed270c3d7240b20e5769f4669bd23a48045308.zip FreeBSD-src-88ed270c3d7240b20e5769f4669bd23a48045308.tar.gz |
When a STOP signal is being sent to a process, it is possible all
threads in the process have already masked the signal, so job control
is delayed. But later a thread unmasking the STOP signal should enable
job control, so in issignal(), scanning all threads in process to see
if we can direct suspend some of them, not just suspend current thread.
-rw-r--r-- | sys/kern/kern_sig.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index c40044c..ec176a2 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1760,8 +1760,12 @@ tdsignal(struct thread *td, int sig) mtx_lock_spin(&sched_lock); FOREACH_THREAD_IN_PROC(p, td0) { if (TD_IS_SLEEPING(td0) && - (td0->td_flags & TDF_SINTR)) + (td0->td_flags & TDF_SINTR) && + !TD_IS_SUSPENDED(td0)) { thread_suspend_one(td0); + } else if (td != td0) { + td0->td_flags |= TDF_ASTPENDING; + } } thread_stopped(p); if (p->p_numthreads == p->p_suspcount) { @@ -1898,7 +1902,8 @@ issignal(td) struct proc *p; struct sigacts *ps; sigset_t sigpending; - register int sig, prop; + int sig, prop; + struct thread *td0; p = td->td_proc; ps = p->p_sigacts; @@ -2019,6 +2024,15 @@ issignal(td) p->p_flag |= P_STOPPED_SIG; p->p_xstat = sig; mtx_lock_spin(&sched_lock); + FOREACH_THREAD_IN_PROC(p, td0) { + if (TD_IS_SLEEPING(td0) && + (td0->td_flags & TDF_SINTR) && + !TD_IS_SUSPENDED(td0)) { + thread_suspend_one(td0); + } else if (td != td0) { + td0->td_flags |= TDF_ASTPENDING; + } + } thread_stopped(p); thread_suspend_one(td); PROC_UNLOCK(p); |