int partition;
/* Can't prepare a lock group follower. */
- Assert(MyProc == LockGroupLeader);
+ Assert(LockGroupLeader == MyProc || LockGroupLeader == NULL);
/* This is a critical section: any error means big trouble */
START_CRIT_SECTION();
Assert(proclock->tag.myProc == MyProc);
+ /*
+ * We shouldn't be in a lock group, except for a single-entry
+ * group for which we're the leader, which is OK. We need to
+ * clear the groupLeader pointer in that case, so that the dummy
+ * PGPROC doesn't end up pointing back to our PGPROC.
+ */
+ if (proclock->groupLeader != NULL)
+ {
+ Assert(proclock->groupLeader == MyProc);
+ Assert(MyProc->lockGroupMembers == 1);
+ proclock->groupLeader = NULL;
+ }
+
lock = proclock->tag.myLock;
/* Ignore VXID locks */
Assert(lock->nGranted >= 0);
Assert(lock->nGranted <= lock->nRequested);
Assert((proclock->holdMask & ~lock->grantMask) == 0);
- Assert(proclock->tag.myProc == proclock->groupLeader);
/* Ignore it if nothing to release (must be a session lock) */
if (proclock->releaseMask == 0)
SHMQueueInsertBefore(&(newproc->myProcLocks[partition]),
&proclock->procLink);
- /* Update lock group leader. */
- proclock->groupLeader = newproc;
-
PROCLOCK_PRINT("PostPrepare_Locks: updated", proclock);
} /* loop over PROCLOCKs within this partition */
*/
if (!found)
{
- proclock->groupLeader = proc;
+ proclock->groupLeader = NULL;
proclock->holdMask = 0;
proclock->releaseMask = 0;
/* Add proclock to appropriate lists */
PGXACT *MyPgXact = NULL;
/*
- * If we're not in a lock group, LockGroupLeader should be set to the
- * same value as MyProc, if this backend intends to do any heavyweight locking.
- * This also occurs when we are a lock group leader. When we are a lock
- * group following, LockGroupLeader points to the group leader's PGPROC.
+ * If we're not in a lock group, LockGroupLeader will be NULL. Otherwise,
+ * it should be the set to the leader of the lock group of which we're a
+ * member. This will be the same as MyProc iff we're the group leader.
*/
PGPROC *LockGroupLeader = NULL;
}
procs[i].pgprocno = i;
- procs[i].lockGroupLeader = &procs[i];
/*
* Newly created PGPROCs for normal backends, autovacuum and bgworkers
errmsg("sorry, too many clients already")));
}
MyPgXact = &ProcGlobal->allPgXact[MyProc->pgprocno];
- LockGroupLeader = MyProc;
/*
* Cross-check that the PGPROC is of the type we expect; if this were
MyProc->lwWaitLink = NULL;
MyProc->waitLock = NULL;
MyProc->waitProcLock = NULL;
- Assert(MyProc->lockGroupLeader == MyProc);
+ Assert(MyProc->lockGroupLeader == NULL);
#ifdef USE_ASSERT_CHECKING
{
int i;
MyProc->lwWaitLink = NULL;
MyProc->waitLock = NULL;
MyProc->waitProcLock = NULL;
- Assert(MyProc->lockGroupLeader == MyProc);
+ Assert(MyProc->lockGroupLeader == NULL);
#ifdef USE_ASSERT_CHECKING
{
int i;
ReplicationSlotRelease();
/* If we're a lock group member, detach from the lock group. */
- if (LockGroupLeader != MyProc)
+ if (LockGroupLeader != NULL && LockGroupLeader != MyProc)
{
int members;
LWLockRelease(LockGroupLeader->backendLock);
LWLockAcquire(MyProc->backendLock, LW_EXCLUSIVE);
- MyProc->lockGroupLeader = MyProc;
+ MyProc->lockGroupLeader = NULL;
LWLockRelease(MyProc->backendLock);
/* If we're the last member of the lock group, detach the PGPROC. */
* be a lock group leader, allowing our PGPROC to be recycled
* immediately.
*/
- if (IsLockGroupLeader)
+ if (LockGroupLeader == MyProc)
{
int members;
members = --proc->lockGroupMembers;
LWLockRelease(proc->backendLock);
- if (members == 0)
- IsLockGroupLeader = false;
+ LockGroupLeader = NULL;
}
/*
* designation, then we can immediately release our PGPROC. If not, then
* the last group member will do that on exit.
*/
- if (!IsLockGroupLeader)
+ if (LockGroupLeader == NULL)
{
PGPROC * volatile * procgloballist;
BecomeLockGroupLeader(void)
{
/* Can't be leader and follower. */
- Assert(LockGroupLeader == MyProc);
+ Assert(LockGroupLeader == NULL || LockGroupLeader == MyProc);
/* This can be called more than once; but we must not redo the work. */
- if (!IsLockGroupLeader)
+ if (LockGroupLeader == NULL)
{
LWLockAcquire(MyProc->backendLock, LW_EXCLUSIVE);
Assert(MyProc->lockGroupMembers == 0);
- Assert(MyProc->lockGroupLeader == MyProc);
+ Assert(MyProc->lockGroupLeader == NULL);
+ MyProc->lockGroupLeader = MyProc;
MyProc->lockGroupLeaderIdentifier = MyProcPid;
MyProc->lockGroupMembers = 1;
LWLockRelease(MyProc->backendLock);
- IsLockGroupLeader = true;
}
}
{
bool ok = false;
- /* Can't be leader and follower. */
- Assert(!IsLockGroupLeader);
-
- /* Can't become a follower if we already are one. */
- Assert(MyProc == LockGroupLeader);
+ /* Can't become a follower if we already in a lock group. */
+ Assert(LockGroupLeader == NULL);
/* Can't follow ourselves. */
Assert(MyProc != leader);