summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2003-06-20 03:36:45 +0000
committerdavidxu <davidxu@FreeBSD.org>2003-06-20 03:36:45 +0000
commit88ed270c3d7240b20e5769f4669bd23a48045308 (patch)
tree7148057315bf4342b048b81b471703121d100f86
parentc0a849442b33e0542e11f3216f85775d8c5402f7 (diff)
downloadFreeBSD-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.c18
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);
OpenPOWER on IntegriCloud