diff options
author | jhb <jhb@FreeBSD.org> | 2001-06-27 06:15:44 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2001-06-27 06:15:44 +0000 |
commit | f4029cf62b7527d3d28d121fa81da9c63fbce9af (patch) | |
tree | 328ceb66f0239d2e5bd750e910fea544fefd0235 /sys/kern/kern_exit.c | |
parent | b2bba7ca2ac8a4de0678d1fe23ee5189bc40c8e4 (diff) | |
download | FreeBSD-src-f4029cf62b7527d3d28d121fa81da9c63fbce9af.zip FreeBSD-src-f4029cf62b7527d3d28d121fa81da9c63fbce9af.tar.gz |
- Always use the proc lock of the task leader to protect the peers list of
processes.
- Don't construct fake call args and then call kill(). psignal is not
anymore complicated and is quicker and not prone to locking problems.
Calling psignal() avoids having to do a pfind() since we already have a
proc pointer and also allows us to keep the task leader locked while we
kill all the peer processes so the list is kept coherent.
- When a kthread exits, do a wakeup() on its proc pointers. This can be
used by kernel modules that have kthreads and want to ensure they have
safely exited before completely the MOD_UNLOAD event.
Connectivity provided by: Usenix wireless
Diffstat (limited to 'sys/kern/kern_exit.c')
-rw-r--r-- | sys/kern/kern_exit.c | 27 |
1 files changed, 12 insertions, 15 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 6454d11..b1a2ee5 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -131,20 +131,11 @@ exit1(p, rv) /* are we a task leader? */ PROC_LOCK(p); if(p == p->p_leader) { - struct kill_args killArgs; - - killArgs.signum = SIGKILL; q = p->p_peers; - while(q) { - killArgs.pid = q->p_pid; - /* - * The interface for kill is better - * than the internal signal - */ - PROC_UNLOCK(p); - kill(p, &killArgs); - PROC_LOCK(p); - nq = q; + while (q != NULL) { + PROC_LOCK(q); + psignal(q, SIGKILL); + PROC_UNLOCK(q); q = q->p_peers; } while (p->p_peers) @@ -197,7 +188,7 @@ exit1(p, rv) /* * Remove ourself from our leader's peer list and wake our leader. */ - PROC_LOCK(p); + PROC_LOCK(p->p_leader); if(p->p_leader->p_peers) { q = p->p_leader; while(q->p_peers != p) @@ -205,7 +196,7 @@ exit1(p, rv) q->p_peers = p->p_peers; wakeup((caddr_t)p->p_leader); } - PROC_UNLOCK(p); + PROC_UNLOCK(p->p_leader); /* * XXX Shutdown SYSV semaphores @@ -359,6 +350,12 @@ exit1(p, rv) else psignal(p->p_pptr, SIGCHLD); PROC_UNLOCK(p->p_pptr); + + /* + * If this is a kthread, then wakeup anyone waiting for it to exit. + */ + if (p->p_flag & P_KTHREAD) + wakeup((caddr_t)p); PROC_UNLOCK(p); sx_xunlock(&proctree_lock); |