summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_exit.c14
-rw-r--r--sys/kern/kern_time.c2
2 files changed, 14 insertions, 2 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 2adfa9c..e455063 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -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);
/*
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index 29de672..772edc3 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -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;
}
OpenPOWER on IntegriCloud