Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 6765cbd

Browse files
committed
Tidy up GetMultiXactIdMembers()'s behavior on error
One of the error paths left *members uninitialized. That's not a live bug, because most callers don't look at *members when the function returns -1, but let's be tidy. One caller, in heap_lock_tuple(), does "if (members != NULL) pfree(members)", but AFAICS it never passes an invalid 'multi' value so it should not reach that error case. The callers are also a bit inconsistent in their expectations. heap_lock_tuple() pfrees the 'members' array if it's not-NULL, others pfree() it if "nmembers >= 0", and others if "nmembers > 0". That's not a live bug either, because the function should never return 0, but add an Assert for that to make it more clear. I left the callers alone for now. I also moved the line where we set *nmembers. It wasn't wrong before, but I like to do that right next to the 'return' statement, to make it clear that it's always set on return. Also remove one unreachable return statement after ereport(ERROR), for brevity and for consistency with the similar if-block right after it. Author: Greg Nancarrow with the additional changes by me Backpatch-through: 9.6, all supported versions
1 parent 9438962 commit 6765cbd

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

src/backend/access/transam/multixact.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,7 +1220,10 @@ GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members,
12201220
debug_elog3(DEBUG2, "GetMembers: asked for %u", multi);
12211221

12221222
if (!MultiXactIdIsValid(multi) || from_pgupgrade)
1223+
{
1224+
*members = NULL;
12231225
return -1;
1226+
}
12241227

12251228
/* See if the MultiXactId is in the local cache */
12261229
length = mXactCacheGetById(multi, members);
@@ -1271,13 +1274,10 @@ GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members,
12711274
LWLockRelease(MultiXactGenLock);
12721275

12731276
if (MultiXactIdPrecedes(multi, oldestMXact))
1274-
{
12751277
ereport(ERROR,
12761278
(errcode(ERRCODE_INTERNAL_ERROR),
12771279
errmsg("MultiXactId %u does no longer exist -- apparent wraparound",
12781280
multi)));
1279-
return -1;
1280-
}
12811281

12821282
if (!MultiXactIdPrecedes(multi, nextMXact))
12831283
ereport(ERROR,
@@ -1377,7 +1377,6 @@ GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members,
13771377
LWLockRelease(MultiXactOffsetControlLock);
13781378

13791379
ptr = (MultiXactMember *) palloc(length * sizeof(MultiXactMember));
1380-
*members = ptr;
13811380

13821381
/* Now get the members themselves. */
13831382
LWLockAcquire(MultiXactMemberControlLock, LW_EXCLUSIVE);
@@ -1422,13 +1421,17 @@ GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members,
14221421

14231422
LWLockRelease(MultiXactMemberControlLock);
14241423

1424+
/* A multixid with zero members should not happen */
1425+
Assert(truelength > 0);
1426+
14251427
/*
14261428
* Copy the result into the local cache.
14271429
*/
14281430
mXactCachePut(multi, truelength, ptr);
14291431

14301432
debug_elog3(DEBUG2, "GetMembers: no cache for %s",
14311433
mxid_to_string(multi, truelength, ptr));
1434+
*members = ptr;
14321435
return truelength;
14331436
}
14341437

@@ -1529,7 +1532,6 @@ mXactCacheGetById(MultiXactId multi, MultiXactMember **members)
15291532

15301533
size = sizeof(MultiXactMember) * entry->nmembers;
15311534
ptr = (MultiXactMember *) palloc(size);
1532-
*members = ptr;
15331535

15341536
memcpy(ptr, entry->members, size);
15351537

@@ -1545,6 +1547,7 @@ mXactCacheGetById(MultiXactId multi, MultiXactMember **members)
15451547
*/
15461548
dlist_move_head(&MXactCache, iter.cur);
15471549

1550+
*members = ptr;
15481551
return entry->nmembers;
15491552
}
15501553
}

0 commit comments

Comments
 (0)