diff options
author | tanimura <tanimura@FreeBSD.org> | 2002-02-23 11:12:57 +0000 |
---|---|---|
committer | tanimura <tanimura@FreeBSD.org> | 2002-02-23 11:12:57 +0000 |
commit | a09da298590e8c11ebafa37f79e0046814665237 (patch) | |
tree | 2289c653c0f7aa23498f82b603c33107952652ec /sys/kern/kern_sig.c | |
parent | 33e8ee5265ca2838260ab581a9cebdedb1e1e29b (diff) | |
download | FreeBSD-src-a09da298590e8c11ebafa37f79e0046814665237.zip FreeBSD-src-a09da298590e8c11ebafa37f79e0046814665237.tar.gz |
Lock struct pgrp, session and sigio.
New locks are:
- pgrpsess_lock which locks the whole pgrps and sessions,
- pg_mtx which protects the pgrp members, and
- s_mtx which protects the session members.
Please refer to sys/proc.h for the coverage of these locks.
Changes on the pgrp/session interface:
- pgfind() needs the pgrpsess_lock held.
- The caller of enterpgrp() is responsible to allocate a new pgrp and
session.
- Call enterthispgrp() in order to enter an existing pgrp.
- pgsignal() requires a pgrp lock held.
Reviewed by: jhb, alfred
Tested on: cvsup.jp.FreeBSD.org
(which is a quad-CPU machine running -current)
Diffstat (limited to 'sys/kern/kern_sig.c')
-rw-r--r-- | sys/kern/kern_sig.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 27acc64..f871cd5 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1001,16 +1001,21 @@ killpg1(cp, sig, pgid, all) } sx_sunlock(&allproc_lock); } else { - if (pgid == 0) + PGRPSESS_SLOCK(); + if (pgid == 0) { /* * zero pgid means send to my process group. */ pgrp = cp->p_pgrp; - else { + PGRP_LOCK(pgrp); + } else { pgrp = pgfind(pgid); - if (pgrp == NULL) + if (pgrp == NULL) { + PGRPSESS_SUNLOCK(); return (ESRCH); + } } + PGRPSESS_SUNLOCK(); LIST_FOREACH(p, &pgrp->pg_members, p_pglist) { PROC_LOCK(p); if (p->p_pid <= 1 || p->p_flag & P_SYSTEM) { @@ -1031,6 +1036,7 @@ killpg1(cp, sig, pgid, all) } PROC_UNLOCK(p); } + PGRP_UNLOCK(pgrp); } return (nfound ? 0 : ESRCH); } @@ -1124,8 +1130,15 @@ gsignal(pgid, sig) { struct pgrp *pgrp; - if (pgid && (pgrp = pgfind(pgid))) - pgsignal(pgrp, sig, 0); + if (pgid != 0) { + PGRPSESS_SLOCK(); + pgrp = pgfind(pgid); + PGRPSESS_SUNLOCK(); + if (pgrp != NULL) { + pgsignal(pgrp, sig, 0); + PGRP_UNLOCK(pgrp); + } + } } /* @@ -1140,6 +1153,7 @@ pgsignal(pgrp, sig, checkctty) register struct proc *p; if (pgrp) { + PGRP_LOCK_ASSERT(pgrp, MA_OWNED); LIST_FOREACH(p, &pgrp->pg_members, p_pglist) { PROC_LOCK(p); if (checkctty == 0 || p->p_flag & P_CONTROLT) @@ -1351,11 +1365,10 @@ psignal(p, sig) goto out; SIGDELSET(p->p_siglist, sig); p->p_xstat = sig; - if ((p->p_pptr->p_procsig->ps_flag & PS_NOCLDSTOP) == 0) { - PROC_LOCK(p->p_pptr); + PROC_LOCK(p->p_pptr); + if ((p->p_pptr->p_procsig->ps_flag & PS_NOCLDSTOP) == 0) psignal(p->p_pptr, SIGCHLD); - PROC_UNLOCK(p->p_pptr); - } + PROC_UNLOCK(p->p_pptr); mtx_lock_spin(&sched_lock); stop(p); mtx_unlock_spin(&sched_lock); @@ -1629,14 +1642,13 @@ issignal(p) if (prop & SA_STOP) { if (p->p_flag & P_TRACED || (p->p_pgrp->pg_jobc == 0 && - prop & SA_TTYSTOP)) + prop & SA_TTYSTOP)) break; /* == ignore */ p->p_xstat = sig; - if ((p->p_pptr->p_procsig->ps_flag & PS_NOCLDSTOP) == 0) { - PROC_LOCK(p->p_pptr); + PROC_LOCK(p->p_pptr); + if ((p->p_pptr->p_procsig->ps_flag & PS_NOCLDSTOP) == 0) psignal(p->p_pptr, SIGCHLD); - PROC_UNLOCK(p->p_pptr); - } + PROC_UNLOCK(p->p_pptr); mtx_lock_spin(&sched_lock); stop(p); PROC_UNLOCK(p); @@ -2074,7 +2086,7 @@ pgsigio(sigio, sig, checkctty) { if (sigio == NULL) return; - + if (sigio->sio_pgid > 0) { PROC_LOCK(sigio->sio_proc); if (CANSIGIO(sigio->sio_ucred, sigio->sio_proc->p_ucred)) @@ -2083,6 +2095,7 @@ pgsigio(sigio, sig, checkctty) } else if (sigio->sio_pgid < 0) { struct proc *p; + PGRP_LOCK(sigio->sio_pgrp); LIST_FOREACH(p, &sigio->sio_pgrp->pg_members, p_pglist) { PROC_LOCK(p); if (CANSIGIO(sigio->sio_ucred, p->p_ucred) && @@ -2090,6 +2103,7 @@ pgsigio(sigio, sig, checkctty) psignal(p, sig); PROC_UNLOCK(p); } + PGRP_UNLOCK(sigio->sio_pgrp); } } |