Rework locking code in GetMultiXactIdMembers
After commit 53c2a97a9266, the code flow around the "retry" goto label in GetMultiXactIdMembers was confused about what was possible: we never return there with a held lock, so there's no point in testing for one. This realization lets us simplify the code a bit. While at it, make the scope of a couple of local variables in the same function a bit tighter. Per Coverity.
This commit is contained in:
parent
f9baaf96d3
commit
a0b808baef
@ -1247,14 +1247,12 @@ GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members,
|
|||||||
MultiXactOffset offset;
|
MultiXactOffset offset;
|
||||||
int length;
|
int length;
|
||||||
int truelength;
|
int truelength;
|
||||||
int i;
|
|
||||||
MultiXactId oldestMXact;
|
MultiXactId oldestMXact;
|
||||||
MultiXactId nextMXact;
|
MultiXactId nextMXact;
|
||||||
MultiXactId tmpMXact;
|
MultiXactId tmpMXact;
|
||||||
MultiXactOffset nextOffset;
|
MultiXactOffset nextOffset;
|
||||||
MultiXactMember *ptr;
|
MultiXactMember *ptr;
|
||||||
LWLock *lock;
|
LWLock *lock;
|
||||||
LWLock *prevlock = NULL;
|
|
||||||
|
|
||||||
debug_elog3(DEBUG2, "GetMembers: asked for %u", multi);
|
debug_elog3(DEBUG2, "GetMembers: asked for %u", multi);
|
||||||
|
|
||||||
@ -1361,18 +1359,9 @@ retry:
|
|||||||
pageno = MultiXactIdToOffsetPage(multi);
|
pageno = MultiXactIdToOffsetPage(multi);
|
||||||
entryno = MultiXactIdToOffsetEntry(multi);
|
entryno = MultiXactIdToOffsetEntry(multi);
|
||||||
|
|
||||||
/*
|
/* Acquire the bank lock for the page we need. */
|
||||||
* If this page falls under a different bank, release the old bank's lock
|
|
||||||
* and acquire the lock of the new bank.
|
|
||||||
*/
|
|
||||||
lock = SimpleLruGetBankLock(MultiXactOffsetCtl, pageno);
|
lock = SimpleLruGetBankLock(MultiXactOffsetCtl, pageno);
|
||||||
if (lock != prevlock)
|
LWLockAcquire(lock, LW_EXCLUSIVE);
|
||||||
{
|
|
||||||
if (prevlock != NULL)
|
|
||||||
LWLockRelease(prevlock);
|
|
||||||
LWLockAcquire(lock, LW_EXCLUSIVE);
|
|
||||||
prevlock = lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
slotno = SimpleLruReadPage(MultiXactOffsetCtl, pageno, true, multi);
|
slotno = SimpleLruReadPage(MultiXactOffsetCtl, pageno, true, multi);
|
||||||
offptr = (MultiXactOffset *) MultiXactOffsetCtl->shared->page_buffer[slotno];
|
offptr = (MultiXactOffset *) MultiXactOffsetCtl->shared->page_buffer[slotno];
|
||||||
@ -1407,17 +1396,19 @@ retry:
|
|||||||
|
|
||||||
if (pageno != prev_pageno)
|
if (pageno != prev_pageno)
|
||||||
{
|
{
|
||||||
|
LWLock *newlock;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since we're going to access a different SLRU page, if this page
|
* Since we're going to access a different SLRU page, if this page
|
||||||
* falls under a different bank, release the old bank's lock and
|
* falls under a different bank, release the old bank's lock and
|
||||||
* acquire the lock of the new bank.
|
* acquire the lock of the new bank.
|
||||||
*/
|
*/
|
||||||
lock = SimpleLruGetBankLock(MultiXactOffsetCtl, pageno);
|
newlock = SimpleLruGetBankLock(MultiXactOffsetCtl, pageno);
|
||||||
if (prevlock != lock)
|
if (newlock != lock)
|
||||||
{
|
{
|
||||||
LWLockRelease(prevlock);
|
LWLockRelease(lock);
|
||||||
LWLockAcquire(lock, LW_EXCLUSIVE);
|
LWLockAcquire(newlock, LW_EXCLUSIVE);
|
||||||
prevlock = lock;
|
lock = newlock;
|
||||||
}
|
}
|
||||||
slotno = SimpleLruReadPage(MultiXactOffsetCtl, pageno, true, tmpMXact);
|
slotno = SimpleLruReadPage(MultiXactOffsetCtl, pageno, true, tmpMXact);
|
||||||
}
|
}
|
||||||
@ -1429,8 +1420,7 @@ retry:
|
|||||||
if (nextMXOffset == 0)
|
if (nextMXOffset == 0)
|
||||||
{
|
{
|
||||||
/* Corner case 2: next multixact is still being filled in */
|
/* Corner case 2: next multixact is still being filled in */
|
||||||
LWLockRelease(prevlock);
|
LWLockRelease(lock);
|
||||||
prevlock = NULL;
|
|
||||||
CHECK_FOR_INTERRUPTS();
|
CHECK_FOR_INTERRUPTS();
|
||||||
pg_usleep(1000L);
|
pg_usleep(1000L);
|
||||||
goto retry;
|
goto retry;
|
||||||
@ -1439,14 +1429,14 @@ retry:
|
|||||||
length = nextMXOffset - offset;
|
length = nextMXOffset - offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
LWLockRelease(prevlock);
|
LWLockRelease(lock);
|
||||||
prevlock = NULL;
|
lock = NULL;
|
||||||
|
|
||||||
ptr = (MultiXactMember *) palloc(length * sizeof(MultiXactMember));
|
ptr = (MultiXactMember *) palloc(length * sizeof(MultiXactMember));
|
||||||
|
|
||||||
truelength = 0;
|
truelength = 0;
|
||||||
prev_pageno = -1;
|
prev_pageno = -1;
|
||||||
for (i = 0; i < length; i++, offset++)
|
for (int i = 0; i < length; i++, offset++)
|
||||||
{
|
{
|
||||||
TransactionId *xactptr;
|
TransactionId *xactptr;
|
||||||
uint32 *flagsptr;
|
uint32 *flagsptr;
|
||||||
@ -1459,18 +1449,20 @@ retry:
|
|||||||
|
|
||||||
if (pageno != prev_pageno)
|
if (pageno != prev_pageno)
|
||||||
{
|
{
|
||||||
|
LWLock *newlock;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since we're going to access a different SLRU page, if this page
|
* Since we're going to access a different SLRU page, if this page
|
||||||
* falls under a different bank, release the old bank's lock and
|
* falls under a different bank, release the old bank's lock and
|
||||||
* acquire the lock of the new bank.
|
* acquire the lock of the new bank.
|
||||||
*/
|
*/
|
||||||
lock = SimpleLruGetBankLock(MultiXactMemberCtl, pageno);
|
newlock = SimpleLruGetBankLock(MultiXactMemberCtl, pageno);
|
||||||
if (lock != prevlock)
|
if (newlock != lock)
|
||||||
{
|
{
|
||||||
if (prevlock)
|
if (lock)
|
||||||
LWLockRelease(prevlock);
|
LWLockRelease(lock);
|
||||||
LWLockAcquire(lock, LW_EXCLUSIVE);
|
LWLockAcquire(newlock, LW_EXCLUSIVE);
|
||||||
prevlock = lock;
|
lock = newlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
slotno = SimpleLruReadPage(MultiXactMemberCtl, pageno, true, multi);
|
slotno = SimpleLruReadPage(MultiXactMemberCtl, pageno, true, multi);
|
||||||
@ -1496,8 +1488,7 @@ retry:
|
|||||||
truelength++;
|
truelength++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prevlock)
|
LWLockRelease(lock);
|
||||||
LWLockRelease(prevlock);
|
|
||||||
|
|
||||||
/* A multixid with zero members should not happen */
|
/* A multixid with zero members should not happen */
|
||||||
Assert(truelength > 0);
|
Assert(truelength > 0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user