- Proc locking. Most of signal handling is now MP safe and doesn't require

Giant.  The only exception is the CANSIGNAL() macro.  Unlocking the proc
  lock around sendsig() in trapsignal() is also questionable.  Note that
  the functions sigexit(), psignal(), and issignal() must be called with
  the proc lock of the process in question held.  postsig() and
  trapsignal() should not be called with the proc lock held, but they
  also do not require Giant anymore either.
- Remove spl's that are now no longer needed as they are fully replaced.
This commit is contained in:
jhb 2001-03-07 02:59:54 +00:00
parent 7c5cd82d2e
commit d18d94674a

View File

@ -178,17 +178,18 @@ int
CURSIG(struct proc *p)
{
sigset_t tmpset;
int r;
int r = 0;
PROC_LOCK(p);
if (SIGISEMPTY(p->p_siglist))
return (0);
goto out;
tmpset = p->p_siglist;
SIGSETNAND(tmpset, p->p_sigmask);
if (SIGISEMPTY(tmpset) && (p->p_flag & P_TRACED) == 0)
return (0);
mtx_lock(&Giant);
goto out;
r = issignal(p);
mtx_unlock(&Giant);
out:
PROC_UNLOCK(p);
return (r);
}
@ -224,11 +225,13 @@ do_sigaction(p, sig, act, oact, old)
struct sigaction *act, *oact;
int old;
{
register struct sigacts *ps = p->p_sigacts;
register struct sigacts *ps;
if (sig <= 0 || sig > _SIG_MAXSIG)
return (EINVAL);
PROC_LOCK(p);
ps = p->p_sigacts;
if (oact) {
oact->sa_handler = ps->ps_sigact[_SIG_IDX(sig)];
oact->sa_mask = ps->ps_catchmask[_SIG_IDX(sig)];
@ -250,13 +253,14 @@ do_sigaction(p, sig, act, oact, old)
}
if (act) {
if ((sig == SIGKILL || sig == SIGSTOP) &&
act->sa_handler != SIG_DFL)
act->sa_handler != SIG_DFL) {
PROC_UNLOCK(p);
return (EINVAL);
}
/*
* Change setting atomically.
*/
(void) splhigh();
ps->ps_catchmask[_SIG_IDX(sig)] = act->sa_mask;
SIG_CANTMASK(ps->ps_catchmask[_SIG_IDX(sig)]);
@ -336,9 +340,8 @@ do_sigaction(p, sig, act, oact, old)
SIGDELSET(ps->ps_osigset, sig);
else
SIGADDSET(ps->ps_osigset, sig);
(void) spl0();
}
PROC_UNLOCK(p);
return (0);
}
@ -425,9 +428,11 @@ siginit(p)
{
register int i;
PROC_LOCK(p);
for (i = 1; i <= NSIG; i++)
if (sigprop(i) & SA_IGNORE && i != SIGCONT)
SIGADDSET(p->p_sigignore, i);
PROC_UNLOCK(p);
}
/*
@ -437,7 +442,7 @@ void
execsigs(p)
register struct proc *p;
{
register struct sigacts *ps = p->p_sigacts;
register struct sigacts *ps;
register int sig;
/*
@ -445,6 +450,8 @@ execsigs(p)
* through p_sigmask (unless they were caught,
* and are now ignored by default).
*/
PROC_LOCK(p);
ps = p->p_sigacts;
while (SIGNOTEMPTY(p->p_sigcatch)) {
sig = sig_ffs(&p->p_sigcatch);
SIGDELSET(p->p_sigcatch, sig);
@ -466,14 +473,13 @@ execsigs(p)
* Reset no zombies if child dies flag as Solaris does.
*/
p->p_procsig->ps_flag &= ~PS_NOCLDWAIT;
PROC_UNLOCK(p);
}
/*
* do_sigprocmask() - MP SAFE ONLY IF p == curproc
* do_sigprocmask()
*
* Manipulate signal mask. This routine is MP SAFE *ONLY* if
* p == curproc. Also remember that in order to remain MP SAFE
* no spl*() calls may be made.
* Manipulate signal mask.
*/
static int
do_sigprocmask(p, how, set, oset, old)
@ -484,6 +490,7 @@ do_sigprocmask(p, how, set, oset, old)
{
int error;
PROC_LOCK(p);
if (oset != NULL)
*oset = p->p_sigmask;
@ -509,6 +516,7 @@ do_sigprocmask(p, how, set, oset, old)
break;
}
}
PROC_UNLOCK(p);
return (error);
}
@ -582,8 +590,12 @@ sigpending(p, uap)
struct proc *p;
struct sigpending_args *uap;
{
sigset_t siglist;
return (copyout(&p->p_siglist, uap->set, sizeof(sigset_t)));
PROC_LOCK(p);
siglist = p->p_siglist;
PROC_UNLOCK(p);
return (copyout(&siglist, uap->set, sizeof(sigset_t)));
}
#ifdef COMPAT_43 /* XXX - COMPAT_FBSD3 */
@ -599,7 +611,9 @@ osigpending(p, uap)
struct osigpending_args *uap;
{
PROC_LOCK(p);
SIG2OSIG(p->p_siglist, p->p_retval[0]);
PROC_UNLOCK(p);
return (0);
}
#endif /* COMPAT_43 */
@ -671,10 +685,10 @@ osigblock(p, uap)
OSIG2SIG(uap->mask, set);
SIG_CANTMASK(set);
(void) splhigh();
PROC_LOCK(p);
SIG2OSIG(p->p_sigmask, p->p_retval[0]);
SIGSETOR(p->p_sigmask, set);
(void) spl0();
PROC_UNLOCK(p);
return (0);
}
@ -692,10 +706,10 @@ osigsetmask(p, uap)
OSIG2SIG(uap->mask, set);
SIG_CANTMASK(set);
(void) splhigh();
PROC_LOCK(p);
SIG2OSIG(p->p_sigmask, p->p_retval[0]);
SIGSETLO(p->p_sigmask, set);
(void) spl0();
PROC_UNLOCK(p);
return (0);
}
#endif /* COMPAT_43 || COMPAT_SUNOS */
@ -717,7 +731,7 @@ sigsuspend(p, uap)
struct sigsuspend_args *uap;
{
sigset_t mask;
register struct sigacts *ps = p->p_sigacts;
register struct sigacts *ps;
int error;
error = copyin(uap->sigmask, &mask, sizeof(mask));
@ -731,13 +745,16 @@ sigsuspend(p, uap)
* save it here and mark the sigacts structure
* to indicate this.
*/
PROC_LOCK(p);
ps = p->p_sigacts;
p->p_oldsigmask = p->p_sigmask;
p->p_flag |= P_OLDMASK;
SIG_CANTMASK(mask);
p->p_sigmask = mask;
while (tsleep((caddr_t) ps, PPAUSE|PCATCH, "pause", 0) == 0)
while (msleep((caddr_t) ps, &p->p_mtx, PPAUSE|PCATCH, "pause", 0) == 0)
/* void */;
PROC_UNLOCK(p);
/* always return EINTR rather than ERESTART... */
return (EINTR);
}
@ -755,15 +772,18 @@ osigsuspend(p, uap)
struct osigsuspend_args *uap;
{
sigset_t mask;
register struct sigacts *ps = p->p_sigacts;
register struct sigacts *ps;
PROC_LOCK(p);
ps = p->p_sigacts;
p->p_oldsigmask = p->p_sigmask;
p->p_flag |= P_OLDMASK;
OSIG2SIG(uap->mask, mask);
SIG_CANTMASK(mask);
SIGSETLO(p->p_sigmask, mask);
while (tsleep((caddr_t) ps, PPAUSE|PCATCH, "opause", 0) == 0)
while (msleep((caddr_t) ps, &p->p_mtx, PPAUSE|PCATCH, "opause", 0) == 0)
/* void */;
PROC_UNLOCK(p);
/* always return EINTR rather than ERESTART... */
return (EINTR);
}
@ -786,8 +806,10 @@ osigstack(p, uap)
int error;
if (uap->oss != NULL) {
PROC_LOCK(p);
ss.ss_sp = p->p_sigstk.ss_sp;
ss.ss_onstack = sigonstack(cpu_getstack(p));
PROC_UNLOCK(p);
error = copyout(&ss, uap->oss, sizeof(struct sigstack));
if (error)
return (error);
@ -796,10 +818,12 @@ osigstack(p, uap)
if (uap->nss != NULL) {
if ((error = copyin(uap->nss, &ss, sizeof(ss))) != 0)
return (error);
PROC_LOCK(p);
p->p_sigstk.ss_sp = ss.ss_sp;
p->p_sigstk.ss_size = 0;
p->p_sigstk.ss_flags |= ss.ss_onstack & SS_ONSTACK;
p->p_flag |= P_ALTSTACK;
PROC_UNLOCK(p);
}
return (0);
}
@ -823,9 +847,11 @@ sigaltstack(p, uap)
oonstack = sigonstack(cpu_getstack(p));
if (uap->oss != NULL) {
PROC_LOCK(p);
ss = p->p_sigstk;
ss.ss_flags = (p->p_flag & P_ALTSTACK)
? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
PROC_UNLOCK(p);
if ((error = copyout(&ss, uap->oss, sizeof(stack_t))) != 0)
return (error);
}
@ -840,10 +866,15 @@ sigaltstack(p, uap)
if (!(ss.ss_flags & SS_DISABLE)) {
if (ss.ss_size < p->p_sysent->sv_minsigstksz)
return (ENOMEM);
PROC_LOCK(p);
p->p_sigstk = ss;
p->p_flag |= P_ALTSTACK;
} else
PROC_UNLOCK(p);
} else {
PROC_LOCK(p);
p->p_flag &= ~P_ALTSTACK;
PROC_UNLOCK(p);
}
}
return (0);
}
@ -867,12 +898,24 @@ killpg1(cp, sig, pgid, all)
*/
ALLPROC_LOCK(AP_SHARED);
LIST_FOREACH(p, &allproc, p_list) {
if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
p == cp || !CANSIGNAL(cp, p, sig))
PROC_LOCK(p);
if (p->p_pid <= 1 || p->p_flag & P_SYSTEM || p == cp) {
PROC_UNLOCK(p);
continue;
}
PROC_UNLOCK(p);
/*
* XXX: this locking needs work.. specifically the
* session checks..
*/
if (!CANSIGNAL(cp, p, sig))
continue;
nfound++;
if (sig)
if (sig) {
PROC_LOCK(p);
psignal(p, sig);
PROC_UNLOCK(p);
}
}
ALLPROC_LOCK(AP_RELEASE);
} else {
@ -887,13 +930,27 @@ killpg1(cp, sig, pgid, all)
return (ESRCH);
}
LIST_FOREACH(p, &pgrp->pg_members, p_pglist) {
if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
p->p_stat == SZOMB ||
!CANSIGNAL(cp, p, sig))
PROC_LOCK(p);
if (p->p_pid <= 1 || p->p_flag & P_SYSTEM) {
PROC_UNLOCK(p);
continue;
}
PROC_UNLOCK(p);
mtx_lock_spin(&sched_lock);
if (p->p_stat == SZOMB) {
mtx_unlock_spin(&sched_lock);
continue;
}
mtx_unlock_spin(&sched_lock);
/* XXX: locking b0rked */
if (!CANSIGNAL(cp, p, sig))
continue;
nfound++;
if (sig)
if (sig) {
PROC_LOCK(p);
psignal(p, sig);
PROC_UNLOCK(p);
}
}
}
return (nfound ? 0 : ESRCH);
@ -919,10 +976,14 @@ kill(cp, uap)
/* kill single process */
if ((p = pfind(uap->pid)) == NULL)
return (ESRCH);
/* XXX: locking b0rked */
if (!CANSIGNAL(cp, p, uap->signum))
return (EPERM);
if (uap->signum)
if (uap->signum) {
PROC_LOCK(p);
psignal(p, uap->signum);
PROC_UNLOCK(p);
}
return (0);
}
switch (uap->pid) {
@ -980,10 +1041,14 @@ pgsignal(pgrp, sig, checkctty)
{
register struct proc *p;
if (pgrp)
LIST_FOREACH(p, &pgrp->pg_members, p_pglist)
if (pgrp) {
LIST_FOREACH(p, &pgrp->pg_members, p_pglist) {
PROC_LOCK(p);
if (checkctty == 0 || p->p_flag & P_CONTROLT)
psignal(p, sig);
PROC_UNLOCK(p);
}
}
}
/*
@ -999,6 +1064,7 @@ trapsignal(p, sig, code)
{
register struct sigacts *ps = p->p_sigacts;
PROC_LOCK(p);
if ((p->p_flag & P_TRACED) == 0 && SIGISMEMBER(p->p_sigcatch, sig) &&
!SIGISMEMBER(p->p_sigmask, sig)) {
p->p_stats->p_ru.ru_nsignals++;
@ -1007,8 +1073,10 @@ trapsignal(p, sig, code)
ktrpsig(p->p_tracep, sig, ps->ps_sigact[_SIG_IDX(sig)],
&p->p_sigmask, code);
#endif
PROC_UNLOCK(p); /* XXX ??? */
(*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)], sig,
&p->p_sigmask, code);
PROC_LOCK(p);
SIGSETOR(p->p_sigmask, ps->ps_catchmask[_SIG_IDX(sig)]);
if (!SIGISMEMBER(ps->ps_signodefer, sig))
SIGADDSET(p->p_sigmask, sig);
@ -1027,6 +1095,7 @@ trapsignal(p, sig, code)
p->p_sig = sig; /* XXX to verify code */
psignal(p, sig);
}
PROC_UNLOCK(p);
}
/*
@ -1055,7 +1124,7 @@ psignal(p, sig)
panic("psignal signal number");
}
PROC_LOCK(p);
PROC_LOCK_ASSERT(p, MA_OWNED);
KNOTE(&p->p_klist, NOTE_SIGNAL | sig);
prop = sigprop(sig);
@ -1075,10 +1144,8 @@ psignal(p, sig)
* and if it is set to SIG_IGN,
* action will be SIG_DFL here.)
*/
if (SIGISMEMBER(p->p_sigignore, sig) || (p->p_flag & P_WEXIT)) {
PROC_UNLOCK(p);
if (SIGISMEMBER(p->p_sigignore, sig) || (p->p_flag & P_WEXIT))
return;
}
if (SIGISMEMBER(p->p_sigmask, sig))
action = SIG_HOLD;
else if (SIGISMEMBER(p->p_sigcatch, sig))
@ -1104,10 +1171,8 @@ psignal(p, sig)
* and don't clear any pending SIGCONT.
*/
if (prop & SA_TTYSTOP && p->p_pgrp->pg_jobc == 0 &&
action == SIG_DFL) {
PROC_UNLOCK(p);
action == SIG_DFL)
return;
}
SIG_CONTSIGMASK(p->p_siglist);
}
SIGADDSET(p->p_siglist, sig);
@ -1119,7 +1184,6 @@ psignal(p, sig)
mtx_lock_spin(&sched_lock);
if (action == SIG_HOLD && (!(prop & SA_CONT) || p->p_stat != SSTOP)) {
mtx_unlock_spin(&sched_lock);
PROC_UNLOCK(p);
return;
}
switch (p->p_stat) {
@ -1169,13 +1233,12 @@ psignal(p, sig)
goto out;
SIGDELSET(p->p_siglist, sig);
p->p_xstat = sig;
PROC_UNLOCK(p);
PROCTREE_LOCK(PT_SHARED);
if ((p->p_pptr->p_procsig->ps_flag & PS_NOCLDSTOP) == 0)
if ((p->p_pptr->p_procsig->ps_flag & PS_NOCLDSTOP) == 0) {
PROC_LOCK(p->p_pptr);
psignal(p->p_pptr, SIGCHLD);
PROC_UNLOCK(p->p_pptr);
}
stop(p);
PROCTREE_LOCK(PT_RELEASE);
PROC_LOCK(p);
goto out;
} else
goto runfast;
@ -1277,7 +1340,6 @@ psignal(p, sig)
out:
/* If we jump here, sched_lock should not be owned. */
mtx_assert(&sched_lock, MA_NOTOWNED);
PROC_UNLOCK(p);
}
/*
@ -1299,6 +1361,7 @@ issignal(p)
sigset_t mask;
register int sig, prop;
PROC_LOCK_ASSERT(p, MA_OWNED);
for (;;) {
int traced = (p->p_flag & P_TRACED) || (p->p_stops & S_SIG);
@ -1306,12 +1369,12 @@ issignal(p)
SIGSETNAND(mask, p->p_sigmask);
if (p->p_flag & P_PPWAIT)
SIG_STOPSIGMASK(mask);
if (!SIGNOTEMPTY(mask)) /* no signal to send */
if (!SIGNOTEMPTY(mask)) /* no signal to send */
return (0);
sig = sig_ffs(&mask);
prop = sigprop(sig);
STOPEVENT(p, S_SIG, sig);
_STOPEVENT(p, S_SIG, sig);
/*
* We should see pending but ignored signals
@ -1327,20 +1390,20 @@ issignal(p)
* stopped until released by the parent.
*/
p->p_xstat = sig;
PROCTREE_LOCK(PT_SHARED);
PROC_LOCK(p->p_pptr);
psignal(p->p_pptr, SIGCHLD);
PROC_UNLOCK(p->p_pptr);
do {
stop(p);
PROCTREE_LOCK(PT_RELEASE);
mtx_lock_spin(&sched_lock);
PROC_UNLOCK_NOSWITCH(p);
DROP_GIANT_NOSWITCH();
mi_switch();
mtx_unlock_spin(&sched_lock);
PICKUP_GIANT();
PROCTREE_LOCK(PT_SHARED);
PROC_LOCK(p);
} while (!trace_req(p)
&& p->p_flag & P_TRACED);
PROCTREE_LOCK(PT_RELEASE);
/*
* If the traced bit got turned off, go back up
@ -1404,16 +1467,19 @@ issignal(p)
prop & SA_TTYSTOP))
break; /* == ignore */
p->p_xstat = sig;
PROCTREE_LOCK(PT_SHARED);
stop(p);
if ((p->p_pptr->p_procsig->ps_flag & PS_NOCLDSTOP) == 0)
if ((p->p_pptr->p_procsig->ps_flag & PS_NOCLDSTOP) == 0) {
PROC_LOCK(p->p_pptr);
psignal(p->p_pptr, SIGCHLD);
PROCTREE_LOCK(PT_RELEASE);
PROC_UNLOCK(p->p_pptr);
}
mtx_lock_spin(&sched_lock);
PROC_UNLOCK_NOSWITCH(p);
DROP_GIANT_NOSWITCH();
mi_switch();
mtx_unlock_spin(&sched_lock);
PICKUP_GIANT();
PROC_LOCK(p);
break;
} else if (prop & SA_IGNORE) {
/*
@ -1459,7 +1525,7 @@ stop(p)
register struct proc *p;
{
PROCTREE_ASSERT(PT_SHARED);
PROC_LOCK_ASSERT(p, MA_OWNED);
mtx_lock_spin(&sched_lock);
p->p_stat = SSTOP;
p->p_flag &= ~P_WAITED;
@ -1476,13 +1542,15 @@ postsig(sig)
register int sig;
{
register struct proc *p = curproc;
struct sigacts *ps = p->p_sigacts;
struct sigacts *ps;
sig_t action;
sigset_t returnmask;
int code;
KASSERT(sig != 0, ("postsig"));
PROC_LOCK(p);
ps = p->p_sigacts;
SIGDELSET(p->p_siglist, sig);
action = ps->ps_sigact[_SIG_IDX(sig)];
#ifdef KTRACE
@ -1490,7 +1558,7 @@ postsig(sig)
ktrpsig(p->p_tracep, sig, action, p->p_flag & P_OLDMASK ?
&p->p_oldsigmask : &p->p_sigmask, 0);
#endif
STOPEVENT(p, S_SIG, sig);
_STOPEVENT(p, S_SIG, sig);
if (action == SIG_DFL) {
/*
@ -1514,7 +1582,6 @@ postsig(sig)
* mask from before the sigsuspend is what we want
* restored after the signal processing is completed.
*/
(void) splhigh();
if (p->p_flag & P_OLDMASK) {
returnmask = p->p_oldsigmask;
p->p_flag &= ~P_OLDMASK;
@ -1535,7 +1602,6 @@ postsig(sig)
SIGADDSET(p->p_sigignore, sig);
ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL;
}
(void) spl0();
p->p_stats->p_ru.ru_nsignals++;
if (p->p_sig != sig) {
code = 0;
@ -1544,6 +1610,7 @@ postsig(sig)
p->p_code = 0;
p->p_sig = 0;
}
PROC_UNLOCK(p);
(*p->p_sysent->sv_sendsig)(action, sig, &returnmask, code);
}
}
@ -1560,7 +1627,9 @@ killproc(p, why)
p, p->p_pid, p->p_comm);
log(LOG_ERR, "pid %d (%s), uid %d, was killed: %s\n", p->p_pid, p->p_comm,
p->p_cred && p->p_ucred ? p->p_ucred->cr_uid : -1, why);
PROC_LOCK(p);
psignal(p, SIGKILL);
PROC_UNLOCK(p);
}
/*
@ -1577,6 +1646,7 @@ sigexit(p, sig)
int sig;
{
PROC_LOCK_ASSERT(p, MA_OWNED);
p->p_acflag |= AXSIG;
if (sigprop(sig) & SA_CORE) {
p->p_sig = sig;
@ -1586,6 +1656,7 @@ sigexit(p, sig)
* these messages.)
* XXX : Todo, as well as euid, write out ruid too
*/
PROC_UNLOCK(p);
if (coredump(p) == 0)
sig |= WCOREFLAG;
if (kern_logsigexit)
@ -1595,7 +1666,10 @@ sigexit(p, sig)
p->p_cred && p->p_ucred ? p->p_ucred->cr_uid : -1,
sig &~ WCOREFLAG,
sig & WCOREFLAG ? " (core dumped)" : "");
}
} else
PROC_UNLOCK(p);
if (!mtx_owned(&Giant))
mtx_lock(&Giant);
exit1(p, W_EXITCODE(0, sig));
/* NOTREACHED */
}
@ -1702,11 +1776,14 @@ coredump(p)
struct mount *mp;
char *name; /* name of corefile */
off_t limit;
STOPEVENT(p, S_CORE, 0);
if (((sugid_coredump == 0) && p->p_flag & P_SUGID) || do_coredump == 0)
PROC_LOCK(p);
_STOPEVENT(p, S_CORE, 0);
if (((sugid_coredump == 0) && p->p_flag & P_SUGID) || do_coredump == 0) {
PROC_UNLOCK(p);
return (EFAULT);
}
/*
* Note that the bulk of limit checking is done after
@ -1717,8 +1794,11 @@ coredump(p)
* if it is larger than the limit.
*/
limit = p->p_rlimit[RLIMIT_CORE].rlim_cur;
if (limit == 0)
if (limit == 0) {
PROC_UNLOCK(p);
return 0;
}
PROC_UNLOCK(p);
restart:
name = expand_name(p->p_comm, p->p_ucred->cr_uid, p->p_pid);
@ -1749,7 +1829,9 @@ coredump(p)
vattr.va_size = 0;
VOP_LEASE(vp, p, cred, LEASE_WRITE);
VOP_SETATTR(vp, &vattr, cred, p);
PROC_LOCK(p);
p->p_acflag |= ACORE;
PROC_UNLOCK(p);
error = p->p_sysent->sv_coredump ?
p->p_sysent->sv_coredump(p, vp, limit) :
@ -1780,7 +1862,9 @@ nosys(p, args)
struct nosys_args *args;
{
PROC_LOCK(p);
psignal(p, SIGSYS);
PROC_UNLOCK(p);
return (EINVAL);
}
@ -1797,16 +1881,21 @@ pgsigio(sigio, sig, checkctty)
return;
if (sigio->sio_pgid > 0) {
PROC_LOCK(sigio->sio_proc);
if (CANSIGIO(sigio->sio_ruid, sigio->sio_ucred,
sigio->sio_proc))
psignal(sigio->sio_proc, sig);
PROC_UNLOCK(sigio->sio_proc);
} else if (sigio->sio_pgid < 0) {
struct proc *p;
LIST_FOREACH(p, &sigio->sio_pgrp->pg_members, p_pglist)
LIST_FOREACH(p, &sigio->sio_pgrp->pg_members, p_pglist) {
PROC_LOCK(p);
if (CANSIGIO(sigio->sio_ruid, sigio->sio_ucred, p) &&
(checkctty == 0 || (p->p_flag & P_CONTROLT)))
psignal(p, sig);
PROC_UNLOCK(p);
}
}
}
@ -1818,8 +1907,9 @@ filt_sigattach(struct knote *kn)
kn->kn_ptr.p_proc = p;
kn->kn_flags |= EV_CLEAR; /* automatically set */
/* XXX lock the proc here while adding to the list? */
PROC_LOCK(p);
SLIST_INSERT_HEAD(&p->p_klist, kn, kn_selnext);
PROC_UNLOCK(p);
return (0);
}
@ -1829,7 +1919,9 @@ filt_sigdetach(struct knote *kn)
{
struct proc *p = kn->kn_ptr.p_proc;
PROC_LOCK(p);
SLIST_REMOVE(&p->p_klist, kn, knote, kn_selnext);
PROC_UNLOCK(p);
}
/*