Wait for the real interval timer callout handler to finish executing if it

is currently executing when we try to remove it in exit1().  Without this,
it was possible for the callout to bogusly rearm itself and eventually
refire after the process had been free'd resulting in a panic.

PR:		kern/51964
Reported by:	Jilles Tjoelker <jilles@stack.nl>
Reviewed by:	tegge, bde
This commit is contained in:
John Baldwin 2003-06-09 21:46:22 +00:00
parent 8bccf7034e
commit 5499ea019d
2 changed files with 14 additions and 2 deletions

View File

@ -218,8 +218,18 @@ exit1(struct thread *td, int rv)
p->p_flag &= ~(P_TRACED | P_PPWAIT);
SIGEMPTYSET(p->p_siglist);
SIGEMPTYSET(td->td_siglist);
if (timevalisset(&p->p_realtimer.it_value))
callout_stop(&p->p_itcallout);
/*
* Stop the real interval timer. If the handler is currently
* executing, prevent it from rearming itself and let it finish.
*/
if (timevalisset(&p->p_realtimer.it_value) &&
callout_stop(&p->p_itcallout) == 0) {
timevalclear(&p->p_realtimer.it_interval);
msleep(&p->p_itcallout, &p->p_mtx, PWAIT, "ritwait", 0);
KASSERT(!timevalisset(&p->p_realtimer.it_value),
("realtime timer is still armed"));
}
PROC_UNLOCK(p);
/*

View File

@ -531,6 +531,8 @@ realitexpire(void *arg)
psignal(p, SIGALRM);
if (!timevalisset(&p->p_realtimer.it_interval)) {
timevalclear(&p->p_realtimer.it_value);
if (p->p_flag & P_WEXIT)
wakeup(&p->p_itcallout);
PROC_UNLOCK(p);
return;
}