diff options
-rw-r--r-- | sys/kern/kern_kse.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_sig.c | 26 | ||||
-rw-r--r-- | sys/kern/kern_thr.c | 6 | ||||
-rw-r--r-- | sys/kern/kern_thread.c | 2 | ||||
-rw-r--r-- | sys/sys/signalvar.h | 9 |
5 files changed, 25 insertions, 20 deletions
diff --git a/sys/kern/kern_kse.c b/sys/kern/kern_kse.c index bc71b47..4ea5231 100644 --- a/sys/kern/kern_kse.c +++ b/sys/kern/kern_kse.c @@ -413,7 +413,7 @@ kse_thr_interrupt(struct thread *td, struct kse_thr_interrupt_args *uap) if (sig > 0) { td2->td_flags &= ~TDF_INTERRUPT; mtx_unlock_spin(&sched_lock); - tdsignal(td2, sig); + tdsignal(td2, sig, SIGTARGET_P); } else if (sig == 0) { mtx_unlock_spin(&sched_lock); } else { diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 7f5ef68..8d22399 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -95,7 +95,7 @@ static int filt_signal(struct knote *kn, long hint); static struct thread *sigtd(struct proc *p, int sig, int prop); static int kern_sigtimedwait(struct thread *td, sigset_t set, siginfo_t *info, struct timespec *timeout); -static void do_tdsignal(struct thread *td, int sig); +static void do_tdsignal(struct thread *td, int sig, sigtarget_t target); struct filterops sig_filtops = { 0, filt_sigattach, filt_sigdetach, filt_signal }; @@ -761,7 +761,7 @@ sigwait(struct thread *td, struct sigwait_args *uap) /* Repost if we got an error. */ if (error && info.si_signo) { PROC_LOCK(td->td_proc); - tdsignal(td, info.si_signo); + tdsignal(td, info.si_signo, SIGTARGET_TD); PROC_UNLOCK(td->td_proc); } return (error); @@ -800,7 +800,7 @@ sigtimedwait(struct thread *td, struct sigtimedwait_args *uap) /* Repost if we got an error. */ if (error && info.si_signo) { PROC_LOCK(td->td_proc); - tdsignal(td, info.si_signo); + tdsignal(td, info.si_signo, SIGTARGET_TD); PROC_UNLOCK(td->td_proc); } else { td->td_retval[0] = info.si_signo; @@ -831,7 +831,7 @@ sigwaitinfo(struct thread *td, struct sigwaitinfo_args *uap) /* Repost if we got an error. */ if (error && info.si_signo) { PROC_LOCK(td->td_proc); - tdsignal(td, info.si_signo); + tdsignal(td, info.si_signo, SIGTARGET_TD); PROC_UNLOCK(td->td_proc); } else { td->td_retval[0] = info.si_signo; @@ -1538,7 +1538,7 @@ trapsignal(struct thread *td, int sig, u_long code) mtx_unlock(&ps->ps_mtx); p->p_code = code; /* XXX for core dump/debugger */ p->p_sig = sig; /* XXX to verify code */ - tdsignal(td, sig); + tdsignal(td, sig, SIGTARGET_TD); } PROC_UNLOCK(p); } @@ -1607,21 +1607,21 @@ psignal(struct proc *p, int sig) */ td = sigtd(p, sig, prop); - tdsignal(td, sig); + tdsignal(td, sig, SIGTARGET_P); } /* * MPSAFE */ void -tdsignal(struct thread *td, int sig) +tdsignal(struct thread *td, int sig, sigtarget_t target) { sigset_t saved; struct proc *p = td->td_proc; if (p->p_flag & P_SA) saved = p->p_siglist; - do_tdsignal(td, sig); + do_tdsignal(td, sig, target); if ((p->p_flag & P_SA) && !(p->p_flag & P_SIGEVENT)) { if (SIGSETEQ(saved, p->p_siglist)) return; @@ -1634,7 +1634,7 @@ tdsignal(struct thread *td, int sig) } static void -do_tdsignal(struct thread *td, int sig) +do_tdsignal(struct thread *td, int sig, sigtarget_t target) { struct proc *p; register sig_t action; @@ -1656,10 +1656,12 @@ do_tdsignal(struct thread *td, int sig) /* * If this thread is blocking this signal then we'll leave it in the - * proc so that we can find it in the first thread that unblocks it. + * proc so that we can find it in the first thread that unblocks + * it-- unless the signal is meant for the thread and not the process. */ - if (SIGISMEMBER(td->td_sigmask, sig)) - siglist = &p->p_siglist; + if (target == SIGTARGET_P) + siglist = SIGISMEMBER(td->td_sigmask, sig) ? + &p->p_siglist : &td->td_siglist; else siglist = &td->td_siglist; diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c index dcc0847..92890d0 100644 --- a/sys/kern/kern_thr.c +++ b/sys/kern/kern_thr.c @@ -258,11 +258,7 @@ thr_kill(struct thread *td, struct thr_kill_args *uap) goto out; } - /* - * We need a way to force this to go into this thread's siglist. - * Until then blocked signals will go to the proc. - */ - tdsignal(ttd, uap->sig); + tdsignal(ttd, uap->sig, SIGTARGET_TD); out: PROC_UNLOCK(p); diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index bc71b47..4ea5231 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -413,7 +413,7 @@ kse_thr_interrupt(struct thread *td, struct kse_thr_interrupt_args *uap) if (sig > 0) { td2->td_flags &= ~TDF_INTERRUPT; mtx_unlock_spin(&sched_lock); - tdsignal(td2, sig); + tdsignal(td2, sig, SIGTARGET_P); } else if (sig == 0) { mtx_unlock_spin(&sched_lock); } else { diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h index 9e1b908..70b7904 100644 --- a/sys/sys/signalvar.h +++ b/sys/sys/signalvar.h @@ -205,6 +205,13 @@ __sigseteq(sigset_t *set1, sigset_t *set2) #ifdef _KERNEL +/* + * Specifies the target of a signal. + * P - Doesn't matter which thread it gets delivered to. + * TD - Must be delivered to a specific thread. + */ +typedef enum sigtarget_enum { SIGTARGET_P, SIGTARGET_TD } sigtarget_t; + /* Return nonzero if process p has an unmasked pending signal. */ #define SIGPENDING(td) \ (!SIGISEMPTY((td)->td_siglist) && \ @@ -267,7 +274,7 @@ void sigexit(struct thread *td, int signum) __dead2; int sig_ffs(sigset_t *set); void siginit(struct proc *p); void signotify(struct thread *td); -void tdsignal(struct thread *td, int sig); +void tdsignal(struct thread *td, int sig, sigtarget_t target); void trapsignal(struct thread *td, int sig, u_long code); /* |