In kern_sigtimedwait, remove waitset bits for td_sigmask before

sleeping, so in do_tdsignal, we no longer need to test td_waitset.
now td_waitset is only used to give a thread higher priority when
delivering signal to multithreads process.
This also fixes a bug:
when a thread in sigwait states was suspended and later resumed
by SIGCONT, it can no longer receive signals belong to waitset.
This commit is contained in:
davidxu 2005-03-02 13:43:51 +00:00
parent 13d684fd15
commit 5bf5079e95

View File

@ -844,7 +844,7 @@ kern_sigtimedwait(struct thread *td, sigset_t waitset, siginfo_t *info,
struct timespec *timeout)
{
struct sigacts *ps;
sigset_t savedmask, sigset;
sigset_t savedmask;
struct proc *p;
int error, sig, hz, i, timevalid = 0;
struct timespec rts, ets, ts;
@ -894,23 +894,12 @@ kern_sigtimedwait(struct thread *td, sigset_t waitset, siginfo_t *info,
i = 0;
mtx_unlock(&ps->ps_mtx);
}
if (sig) {
td->td_sigmask = savedmask;
signotify(td);
if (sig)
goto out;
}
}
if (error)
goto out;
td->td_sigmask = savedmask;
signotify(td);
sigset = td->td_siglist;
SIGSETOR(sigset, p->p_siglist);
SIGSETAND(sigset, waitset);
if (!SIGISEMPTY(sigset))
goto again;
/*
* POSIX says this must be checked after looking for pending
* signals.
@ -933,6 +922,9 @@ kern_sigtimedwait(struct thread *td, sigset_t waitset, siginfo_t *info,
hz = 0;
td->td_waitset = &waitset;
td->td_sigmask = savedmask;
SIGSETNAND(td->td_sigmask, waitset);
signotify(td);
error = msleep(&ps, &p->p_mtx, PPAUSE|PCATCH, "sigwait", hz);
td->td_waitset = NULL;
if (timeout) {
@ -947,6 +939,8 @@ kern_sigtimedwait(struct thread *td, sigset_t waitset, siginfo_t *info,
goto again;
out:
td->td_sigmask = savedmask;
signotify(td);
if (sig) {
sig_t action;
@ -1597,8 +1591,8 @@ sigtd(struct proc *p, int sig, int prop)
FOREACH_THREAD_IN_PROC(p, td) {
if (td->td_waitset != NULL &&
SIGISMEMBER(*(td->td_waitset), sig)) {
mtx_unlock_spin(&sched_lock);
return (td);
mtx_unlock_spin(&sched_lock);
return (td);
}
if (!SIGISMEMBER(td->td_sigmask, sig)) {
if (td == curthread)
@ -1705,9 +1699,6 @@ do_tdsignal(struct thread *td, int sig, sigtarget_t target)
} else {
if (!SIGISMEMBER(td->td_sigmask, sig))
siglist = &td->td_siglist;
else if (td->td_waitset != NULL &&
SIGISMEMBER(*(td->td_waitset), sig))
siglist = &td->td_siglist;
else
siglist = &p->p_siglist;
}
@ -1733,11 +1724,7 @@ do_tdsignal(struct thread *td, int sig, sigtarget_t target)
mtx_unlock(&ps->ps_mtx);
return;
}
if (((td->td_waitset == NULL) &&
SIGISMEMBER(td->td_sigmask, sig)) ||
((td->td_waitset != NULL) &&
SIGISMEMBER(td->td_sigmask, sig) &&
!SIGISMEMBER(*(td->td_waitset), sig)))
if (SIGISMEMBER(td->td_sigmask, sig))
action = SIG_HOLD;
else if (SIGISMEMBER(ps->ps_sigcatch, sig))
action = SIG_CATCH;
@ -1779,11 +1766,6 @@ do_tdsignal(struct thread *td, int sig, sigtarget_t target)
SIGADDSET(*siglist, sig);
signotify(td); /* uses schedlock */
if (siglist == &td->td_siglist && (td->td_waitset != NULL) &&
action != SIG_HOLD) {
td->td_waitset = NULL;
}
/*
* Defer further processing for signals which are held,
* except that stopped processes must be continued by SIGCONT.