summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Munro2021-03-01 03:28:12 +0000
committerThomas Munro2021-03-01 04:24:47 +0000
commitf5a5773a9dc4185414fe538525e20d8512c2ba35 (patch)
tree1ccd54e64409d6197720f5e8fa64cccae5addc95 /src
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
Diffstat (limited to 'src')
-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;