0002-Forward-received-condition-variable-signals-on-ca-v6.patch
application/octet-stream
Filename: 0002-Forward-received-condition-variable-signals-on-ca-v6.patch
Type: application/octet-stream
Part: 1
Patch
Format: format-patch
Series: patch v6-0002
Subject: Forward received condition variable signals on cancel.
| File | + | − |
|---|---|---|
| src/backend/storage/lmgr/condition_variable.c | 11 | 0 |
From 327fe5536a508963a68e8aded6dbb83effd68933 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Tue, 9 Jul 2019 20:48:06 +1200
Subject: [PATCH 2/3] Forward received condition variable signals on cancel.
After a process decides not to wait for a condition variable, it can
still consume a signal before it reaches ConditionVariableSleep(). In
that case, pass the signal on to another waiter if possible, so that
a signal doesn't go missing when there is another process waiting that
should receive it.
Author: Thomas Munro
Discussion: https://postgr.es/m/CA%2BhUKGLQ_RW%2BXs8znDn36e-%2Bmq2--zrPemBqTQ8eKT-VO1OF4Q%40mail.gmail.com
---
src/backend/storage/lmgr/condition_variable.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/src/backend/storage/lmgr/condition_variable.c b/src/backend/storage/lmgr/condition_variable.c
index 951039da551..c22522beeb8 100644
--- a/src/backend/storage/lmgr/condition_variable.c
+++ b/src/backend/storage/lmgr/condition_variable.c
@@ -246,6 +246,7 @@ void
ConditionVariableCancelSleep(void)
{
ConditionVariable *cv = cv_sleep_target;
+ bool signaled = false;
if (cv == NULL)
return;
@@ -253,8 +254,18 @@ ConditionVariableCancelSleep(void)
SpinLockAcquire(&cv->mutex);
if (proclist_contains(&cv->wakeup, MyProc->pgprocno, cvWaitLink))
proclist_delete(&cv->wakeup, MyProc->pgprocno, cvWaitLink);
+ else
+ signaled = true;
SpinLockRelease(&cv->mutex);
+ /*
+ * If we've received a signal, pass it on to another waiting process, if
+ * there is one. Otherwise a call to ConditionVariableSignal() might get
+ * lost, despite there being another process ready to handle it.
+ */
+ if (signaled)
+ ConditionVariableSignal(cv);
+
cv_sleep_target = NULL;
}
--
2.21.0