summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Munro2021-03-01 03:28:12 +0000
committerThomas Munro2021-03-01 04:24:47 +0000
commitf5a5773a9dc4185414fe538525e20d8512c2ba35 (patch)
tree1ccd54e64409d6197720f5e8fa64cccae5addc95
parent814f1d8bc395bb9b4c0ae090ceea60adfbeb8e49 (diff)
Allow condition variables to be used in interrupt code.
Adjust the condition variable sleep loop to work correctly when code reached by its internal CHECK_FOR_INTERRUPTS() call interacts with another condition variable. There are no such cases currently, but a proposed patch would do this. Discussion: https://postgr.es/m/CA+hUKGLdemy2gBm80kz20GTe6hNVwoErE8KwcJk6-U56oStjtg@mail.gmail.com
-rw-r--r--src/backend/storage/lmgr/condition_variable.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/src/backend/storage/lmgr/condition_variable.c b/src/backend/storage/lmgr/condition_variable.c
index 0a61ff0031f..80d70c154cf 100644
--- a/src/backend/storage/lmgr/condition_variable.c
+++ b/src/backend/storage/lmgr/condition_variable.c
@@ -165,8 +165,6 @@ ConditionVariableTimedSleep(ConditionVariable *cv, long timeout,
/* Reset latch before examining the state of the wait list. */
ResetLatch(MyLatch);
- CHECK_FOR_INTERRUPTS();
-
/*
* If this process has been taken out of the wait list, then we know
* that it has been signaled by ConditionVariableSignal (or
@@ -190,6 +188,15 @@ ConditionVariableTimedSleep(ConditionVariable *cv, long timeout,
}
SpinLockRelease(&cv->mutex);
+ /*
+ * Check for interrupts, and return spuriously if that caused the
+ * current sleep target to change (meaning that interrupt handler code
+ * waited for a different condition variable).
+ */
+ CHECK_FOR_INTERRUPTS();
+ if (cv != cv_sleep_target)
+ done = true;
+
/* We were signaled, so return */
if (done)
return false;