aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_sig.c
diff options
context:
space:
mode:
authorSeigo Tanimura <tanimura@FreeBSD.org>2002-02-23 11:12:57 +0000
committerSeigo Tanimura <tanimura@FreeBSD.org>2002-02-23 11:12:57 +0000
commitf591779bb575703cbb6674d324afb4bd212b8cbb (patch)
tree2289c653c0f7aa23498f82b603c33107952652ec /sys/kern/kern_sig.c
parent4aaca8854285a47e7fd520d5a2797dbf03d05bec (diff)
downloadsrc-f591779bb575703cbb6674d324afb4bd212b8cbb.tar.gz
src-f591779bb575703cbb6674d324afb4bd212b8cbb.zip
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)
Notes
Notes: svn path=/head/; revision=91140
Diffstat (limited to 'sys/kern/kern_sig.c')
-rw-r--r--sys/kern/kern_sig.c44
1 files changed, 29 insertions, 15 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 27acc64a298d..f871cd58a09d 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);
}
}