summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_exit.c
diff options
context:
space:
mode:
authordillon <dillon@FreeBSD.org>2001-09-01 04:37:34 +0000
committerdillon <dillon@FreeBSD.org>2001-09-01 04:37:34 +0000
commite398f0b04ebdb3aa5eef3391bc781370ddefee07 (patch)
tree58d75c395daa79f940e4b0b97322165ab00551cd /sys/kern/kern_exit.c
parent4969658e58791180bd5fd92088d6034a28970f81 (diff)
downloadFreeBSD-src-e398f0b04ebdb3aa5eef3391bc781370ddefee07.zip
FreeBSD-src-e398f0b04ebdb3aa5eef3391bc781370ddefee07.tar.gz
Giant pushdown sys_exit(), [o]wait(), wait4()
Diffstat (limited to 'sys/kern/kern_exit.c')
-rw-r--r--sys/kern/kern_exit.c55
1 files changed, 39 insertions, 16 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index e725eb0..8022cb5 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -93,6 +93,8 @@ static struct exit_list_head exit_list = TAILQ_HEAD_INITIALIZER(exit_list);
/*
* exit --
* Death of process.
+ *
+ * MPSAFE
*/
void
sys_exit(p, uap)
@@ -101,7 +103,7 @@ sys_exit(p, uap)
int rval;
} */ *uap;
{
-
+ mtx_lock(&Giant);
exit1(p, W_EXITCODE(uap->rval, 0));
/* NOTREACHED */
}
@@ -388,6 +390,9 @@ exit1(p, rv)
}
#ifdef COMPAT_43
+/*
+ * MPSAFE, the dirty work is handled by wait1().
+ */
int
owait(p, uap)
struct proc *p;
@@ -405,15 +410,20 @@ owait(p, uap)
}
#endif /* COMPAT_43 */
+/*
+ * MPSAFE, the dirty work is handled by wait1().
+ */
int
wait4(p, uap)
struct proc *p;
struct wait_args *uap;
{
-
return (wait1(p, uap, 0));
}
+/*
+ * MPSAFE
+ */
static int
wait1(q, uap, compat)
register struct proc *q;
@@ -429,10 +439,13 @@ wait1(q, uap, compat)
register struct proc *p, *t;
int status, error;
+ mtx_lock(&Giant);
if (uap->pid == 0)
uap->pid = -q->p_pgid;
- if (uap->options &~ (WUNTRACED|WNOHANG|WLINUXCLONE))
- return (EINVAL);
+ if (uap->options &~ (WUNTRACED|WNOHANG|WLINUXCLONE)) {
+ error = EINVAL;
+ goto done2;
+ }
loop:
nfound = 0;
sx_slock(&proctree_lock);
@@ -478,12 +491,14 @@ loop:
if (uap->status) {
status = p->p_xstat; /* convert to int */
if ((error = copyout((caddr_t)&status,
- (caddr_t)uap->status, sizeof(status))))
- return (error);
+ (caddr_t)uap->status, sizeof(status)))) {
+ goto done2;
+ }
}
if (uap->rusage && (error = copyout((caddr_t)p->p_ru,
- (caddr_t)uap->rusage, sizeof (struct rusage))))
- return (error);
+ (caddr_t)uap->rusage, sizeof (struct rusage)))) {
+ goto done2;
+ }
/*
* If we got the child via a ptrace 'attach',
* we need to give it back to the old parent.
@@ -499,7 +514,8 @@ loop:
wakeup((caddr_t)t);
PROC_UNLOCK(t);
sx_xunlock(&proctree_lock);
- return (0);
+ error = 0;
+ goto done2;
}
}
sx_xunlock(&proctree_lock);
@@ -563,7 +579,8 @@ loop:
mtx_destroy(&p->p_mtx);
zfree(proc_zone, p);
nprocs--;
- return (0);
+ error = 0;
+ goto done2;
}
if (p->p_stat == SSTOP && (p->p_flag & P_WAITED) == 0 &&
(p->p_flag & P_TRACED || uap->options & WUNTRACED)) {
@@ -584,21 +601,27 @@ loop:
(caddr_t)uap->status, sizeof(status));
} else
error = 0;
- return (error);
+ goto done2;
}
mtx_unlock_spin(&sched_lock);
PROC_UNLOCK(p);
}
sx_sunlock(&proctree_lock);
- if (nfound == 0)
- return (ECHILD);
+ if (nfound == 0) {
+ error = ECHILD;
+ goto done2;
+ }
if (uap->options & WNOHANG) {
q->p_retval[0] = 0;
- return (0);
+ error = 0;
+ goto done2;
}
- if ((error = tsleep((caddr_t)q, PWAIT | PCATCH, "wait", 0)))
- return (error);
+ if ((error = tsleep((caddr_t)q, PWAIT | PCATCH, "wait", 0)) != 0)
+ goto done2;
goto loop;
+done2:
+ mtx_unlock(&Giant);
+ return(error);
}
/*
OpenPOWER on IntegriCloud