- 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
This commit is contained in:
John Baldwin 2001-06-27 06:15:44 +00:00
parent c1c5db8149
commit 776e0b3693
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=78870

View File

@ -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);