sleepq_block: if a pending signal is detected but has already been taken
by the time the calling thread tries to take it, don't return EINTR. Instead return zero leading to a spurious wakeup.
This commit is contained in:
parent
d028f9dec2
commit
45e2aff386
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_sleepq.c,v 1.10 2007/07/09 21:10:53 ad Exp $ */
|
||||
/* $NetBSD: kern_sleepq.c,v 1.11 2007/08/01 23:30:54 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006, 2007 The NetBSD Foundation, Inc.
|
||||
|
@ -42,7 +42,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_sleepq.c,v 1.10 2007/07/09 21:10:53 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_sleepq.c,v 1.11 2007/08/01 23:30:54 ad Exp $");
|
||||
|
||||
#include "opt_ktrace.h"
|
||||
|
||||
|
@ -240,6 +240,7 @@ sleepq_block(int timo, bool catch)
|
|||
int error = 0, sig;
|
||||
struct proc *p;
|
||||
lwp_t *l = curlwp;
|
||||
bool early = false;
|
||||
|
||||
#ifdef KTRACE
|
||||
if (KTRPOINT(l->l_proc, KTR_CSW))
|
||||
|
@ -255,37 +256,33 @@ sleepq_block(int timo, bool catch)
|
|||
if ((l->l_flag & LW_PENDSIG) != 0 && sigispending(l, 0)) {
|
||||
/* lwp_unsleep() will release the lock */
|
||||
lwp_unsleep(l);
|
||||
error = EINTR;
|
||||
goto catchit;
|
||||
early = true;
|
||||
}
|
||||
if ((l->l_flag & (LW_CANCELLED|LW_WEXIT|LW_WCORE)) != 0) {
|
||||
l->l_flag &= ~LW_CANCELLED;
|
||||
/* lwp_unsleep() will release the lock */
|
||||
lwp_unsleep(l);
|
||||
error = EINTR;
|
||||
goto catchit;
|
||||
early = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (timo)
|
||||
callout_reset(&l->l_tsleep_ch, timo, sleepq_timeout, l);
|
||||
if (!early) {
|
||||
if (timo)
|
||||
callout_reset(&l->l_tsleep_ch, timo, sleepq_timeout, l);
|
||||
mi_switch(l);
|
||||
|
||||
mi_switch(l);
|
||||
|
||||
/*
|
||||
* When we reach this point, the LWP and sleep queue are unlocked.
|
||||
*/
|
||||
if (timo) {
|
||||
/*
|
||||
* Even if the callout appears to have fired, we need to
|
||||
* stop it in order to synchronise with other CPUs.
|
||||
*/
|
||||
if (callout_stop(&l->l_tsleep_ch))
|
||||
error = EWOULDBLOCK;
|
||||
/* The LWP and sleep queue are now unlocked. */
|
||||
if (timo) {
|
||||
/*
|
||||
* Even if the callout appears to have fired, we need to
|
||||
* stop it in order to synchronise with other CPUs.
|
||||
*/
|
||||
if (callout_stop(&l->l_tsleep_ch))
|
||||
error = EWOULDBLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
if (catch && error == 0) {
|
||||
catchit:
|
||||
p = l->l_proc;
|
||||
if ((l->l_flag & (LW_CANCELLED | LW_WEXIT | LW_WCORE)) != 0)
|
||||
error = EINTR;
|
||||
|
|
Loading…
Reference in New Issue