static uint32 proclock_hash(const void *key, Size keysize);
static void RemoveLocalLock(LOCALLOCK *locallock);
static PROCLOCK *SetupLockInTable(LockMethod lockMethodTable, PGPROC *proc,
- const LOCKTAG *locktag, uint32 hashcode, LOCKMODE lockmode);
+ PGPROC *leader, const LOCKTAG *locktag, uint32 hashcode,
+ LOCKMODE lockmode);
static void GrantLockLocal(LOCALLOCK *locallock, ResourceOwner owner);
static void BeginStrongLockAcquire(LOCALLOCK *locallock, uint32 fasthashcode);
static void FinishStrongLockAcquire(void);
* away anytime. So we have to use SetupLockInTable() to recompute the
* lock and proclock pointers, even if they're already set.
*/
- proclock = SetupLockInTable(lockMethodTable, MyProc, locktag,
- hashcode, lockmode);
+ proclock = SetupLockInTable(lockMethodTable, MyProc, LockGroupLeader,
+ locktag, hashcode, lockmode);
if (!proclock)
{
AbortStrongLockAcquire();
* held at exit.
*/
static PROCLOCK *
-SetupLockInTable(LockMethod lockMethodTable, PGPROC *proc,
+SetupLockInTable(LockMethod lockMethodTable, PGPROC *proc, PGPROC *leader,
const LOCKTAG *locktag, uint32 hashcode, LOCKMODE lockmode)
{
LOCK *lock;
{
uint32 partition = LockHashPartition(hashcode);
+ proclock->groupLeader = leader;
proclock->holdMask = 0;
proclock->releaseMask = 0;
/* Add proclock to appropriate lists */
if (!FAST_PATH_CHECK_LOCKMODE(proc, f, lockmode))
continue;
- proclock = SetupLockInTable(lockMethodTable, proc, locktag,
+ proclock = SetupLockInTable(lockMethodTable, proc,
+ proc->lockGroupLeader, locktag,
hashcode, lockmode);
if (!proclock)
{
/* Find or create lock object. */
LWLockAcquire(partitionLock, LW_EXCLUSIVE);
- proclock = SetupLockInTable(lockMethodTable, MyProc, locktag,
- locallock->hashcode, lockmode);
+ proclock = SetupLockInTable(lockMethodTable, MyProc, LockGroupLeader,
+ locktag, locallock->hashcode, lockmode);
if (!proclock)
{
LWLockRelease(partitionLock);
PROCLOCKTAG proclocktag;
int partition;
+ /* Can't prepare a lock group follower. */
+ Assert(MyProc == LockGroupLeader);
+
/* This is a critical section: any error means big trouble */
START_CRIT_SECTION();
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->holdMask = 0;
proclock->releaseMask = 0;
/* Add proclock to appropriate lists */
LWLockAcquire(partitionLock, LW_EXCLUSIVE);
proclock = SetupLockInTable(LockMethods[DEFAULT_LOCKMETHOD], proc,
- &tag, hashcode, ExclusiveLock);
+ proc->lockGroupLeader, &tag, hashcode,
+ ExclusiveLock);
if (!proclock)
{
LWLockRelease(partitionLock);