Skip to content

Commit 82d4b26

Browse files
committed
Fix bug in the new wait-until-lwlock-is-free mechanism.
If there was a wait-until-free process in the head of the wait queue, followed by an exclusive locker, the exclusive locker was not be woken up as it should.
1 parent 82e83f4 commit 82d4b26

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

src/backend/storage/lmgr/lwlock.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -754,33 +754,40 @@ LWLockRelease(LWLockId lockid)
754754
if (lock->exclusive == 0 && lock->shared == 0 && lock->releaseOK)
755755
{
756756
/*
757-
* Remove the to-be-awakened PGPROCs from the queue. If the front
758-
* waiter wants exclusive lock, awaken him only. Otherwise awaken
759-
* as many waiters as want shared access (or just want to be
760-
* woken up when the lock becomes free without acquiring it,
761-
* ie. LWLockWaitUntilFree).
757+
* Remove the to-be-awakened PGPROCs from the queue.
762758
*/
763759
bool releaseOK = true;
764760

765761
proc = head;
762+
763+
/*
764+
* First wake up any backends that want to be woken up without
765+
* acquiring the lock.
766+
*/
767+
while (proc->lwWaitMode == LW_WAIT_UNTIL_FREE && proc->lwWaitLink)
768+
proc = proc->lwWaitLink;
769+
770+
/*
771+
* If the front waiter wants exclusive lock, awaken him only.
772+
* Otherwise awaken as many waiters as want shared access.
773+
*/
766774
if (proc->lwWaitMode != LW_EXCLUSIVE)
767775
{
768776
while (proc->lwWaitLink != NULL &&
769777
proc->lwWaitLink->lwWaitMode != LW_EXCLUSIVE)
770778
{
771-
proc = proc->lwWaitLink;
772779
if (proc->lwWaitMode != LW_WAIT_UNTIL_FREE)
773780
releaseOK = false;
781+
proc = proc->lwWaitLink;
774782
}
775783
}
776784
/* proc is now the last PGPROC to be released */
777785
lock->head = proc->lwWaitLink;
778786
proc->lwWaitLink = NULL;
779787
/*
780788
* Prevent additional wakeups until retryer gets to run. Backends
781-
* that are just waiting for the lock to become free don't prevent
782-
* wakeups, because they might decide that they don't want the
783-
* lock, after all.
789+
* that are just waiting for the lock to become free don't retry
790+
* automatically.
784791
*/
785792
if (proc->lwWaitMode != LW_WAIT_UNTIL_FREE)
786793
releaseOK = false;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy