aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2014-10-14 09:55:26 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2014-10-14 10:06:47 +0300
commite0d97d77bf0875e4d5cc7dedfe701d9999bf678c (patch)
tree7c43bbcbd2ba7448aea27e0b907821f0997c106d /src
parent0ff5047d52ab84dad682ad140b6992c294580eb1 (diff)
downloadpostgresql-e0d97d77bf0875e4d5cc7dedfe701d9999bf678c.tar.gz
postgresql-e0d97d77bf0875e4d5cc7dedfe701d9999bf678c.zip
Fix deadlock with LWLockAcquireWithVar and LWLockWaitForVar.
LWLockRelease should release all backends waiting with LWLockWaitForVar, even when another backend has already been woken up to acquire the lock, i.e. when releaseOK is false. LWLockWaitForVar can return as soon as the protected value changes, even if the other backend will acquire the lock. Fix that by resetting releaseOK to true in LWLockWaitForVar, whenever adding itself to the wait queue. This should fix the bug reported by MauMau, where the system occasionally hangs when there is a lot of concurrent WAL activity and a checkpoint. Backpatch to 9.4, where this code was added.
Diffstat (limited to 'src')
-rw-r--r--src/backend/storage/lmgr/lwlock.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index 9fe6855945b..bcec17335b8 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -1005,6 +1005,12 @@ LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval)
lock->tail = proc;
lock->head = proc;
+ /*
+ * Set releaseOK, to make sure we get woken up as soon as the lock is
+ * released.
+ */
+ lock->releaseOK = true;
+
/* Can release the mutex now */
SpinLockRelease(&lock->mutex);