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.
This commit is contained in:
parent
82e83f46a2
commit
82d4b262d9
@ -754,23 +754,31 @@ LWLockRelease(LWLockId lockid)
|
|||||||
if (lock->exclusive == 0 && lock->shared == 0 && lock->releaseOK)
|
if (lock->exclusive == 0 && lock->shared == 0 && lock->releaseOK)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Remove the to-be-awakened PGPROCs from the queue. If the front
|
* Remove the to-be-awakened PGPROCs from the queue.
|
||||||
* waiter wants exclusive lock, awaken him only. Otherwise awaken
|
|
||||||
* as many waiters as want shared access (or just want to be
|
|
||||||
* woken up when the lock becomes free without acquiring it,
|
|
||||||
* ie. LWLockWaitUntilFree).
|
|
||||||
*/
|
*/
|
||||||
bool releaseOK = true;
|
bool releaseOK = true;
|
||||||
|
|
||||||
proc = head;
|
proc = head;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First wake up any backends that want to be woken up without
|
||||||
|
* acquiring the lock.
|
||||||
|
*/
|
||||||
|
while (proc->lwWaitMode == LW_WAIT_UNTIL_FREE && proc->lwWaitLink)
|
||||||
|
proc = proc->lwWaitLink;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the front waiter wants exclusive lock, awaken him only.
|
||||||
|
* Otherwise awaken as many waiters as want shared access.
|
||||||
|
*/
|
||||||
if (proc->lwWaitMode != LW_EXCLUSIVE)
|
if (proc->lwWaitMode != LW_EXCLUSIVE)
|
||||||
{
|
{
|
||||||
while (proc->lwWaitLink != NULL &&
|
while (proc->lwWaitLink != NULL &&
|
||||||
proc->lwWaitLink->lwWaitMode != LW_EXCLUSIVE)
|
proc->lwWaitLink->lwWaitMode != LW_EXCLUSIVE)
|
||||||
{
|
{
|
||||||
proc = proc->lwWaitLink;
|
|
||||||
if (proc->lwWaitMode != LW_WAIT_UNTIL_FREE)
|
if (proc->lwWaitMode != LW_WAIT_UNTIL_FREE)
|
||||||
releaseOK = false;
|
releaseOK = false;
|
||||||
|
proc = proc->lwWaitLink;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* proc is now the last PGPROC to be released */
|
/* proc is now the last PGPROC to be released */
|
||||||
@ -778,9 +786,8 @@ LWLockRelease(LWLockId lockid)
|
|||||||
proc->lwWaitLink = NULL;
|
proc->lwWaitLink = NULL;
|
||||||
/*
|
/*
|
||||||
* Prevent additional wakeups until retryer gets to run. Backends
|
* Prevent additional wakeups until retryer gets to run. Backends
|
||||||
* that are just waiting for the lock to become free don't prevent
|
* that are just waiting for the lock to become free don't retry
|
||||||
* wakeups, because they might decide that they don't want the
|
* automatically.
|
||||||
* lock, after all.
|
|
||||||
*/
|
*/
|
||||||
if (proc->lwWaitMode != LW_WAIT_UNTIL_FREE)
|
if (proc->lwWaitMode != LW_WAIT_UNTIL_FREE)
|
||||||
releaseOK = false;
|
releaseOK = false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user