Set MyProc->heldLocks in ProcSleep
authorHeikki Linnakangas <[email protected]>
Mon, 4 Nov 2024 14:20:57 +0000 (16:20 +0200)
committerHeikki Linnakangas <[email protected]>
Mon, 4 Nov 2024 14:20:57 +0000 (16:20 +0200)
Previously, ProcSleep()'s caller was responsible for setting
MyProc->heldLocks, and we had comments to remind about that.  But it
seems simpler to make ProcSleep() itself responsible for it.
ProcSleep() already set the other info about the lock its waiting for
(waitLock, waitProcLock and waitLockMode), so it is natural for it to
set heldLocks too.

Reviewed-by: Maxim Orlov
Discussion: https://www.postgresql.org/message-id/7c2090cd-a72a-4e34-afaa-6dd2ef31440e@iki.fi

src/backend/storage/lmgr/lock.c
src/backend/storage/lmgr/proc.c

index b273ff1afd363378702be9a072aaad029afaaa6f..8abd9837293fb7c4245fbb380f1c9100d832b49f 100644 (file)
@@ -1095,11 +1095,6 @@ LockAcquireExtended(const LOCKTAG *locktag,
    }
    else
    {
-       /*
-        * Set bitmask of locks this process already holds on this object.
-        */
-       MyProc->heldLocks = proclock->holdMask;
-
        /*
         * Sleep till someone wakes me up. We do this even in the dontWait
         * case, because while trying to go to sleep, we may discover that we
@@ -1856,9 +1851,6 @@ MarkLockClear(LOCALLOCK *locallock)
 /*
  * WaitOnLock -- wait to acquire a lock
  *
- * Caller must have set MyProc->heldLocks to reflect locks already held
- * on the lockable object by this process.
- *
  * The appropriate partition lock must be held at entry, and will still be
  * held at exit.
  */
index 84a660a1438cc85b72ee0ad2d0287e89085f7a6f..ed270b6f1bdd016d0c2dfd07aeff30c8711edced 100644 (file)
@@ -1080,9 +1080,6 @@ AuxiliaryPidGetProc(int pid)
 /*
  * ProcSleep -- put a process to sleep on the specified lock
  *
- * Caller must have set MyProc->heldLocks to reflect locks already held
- * on the lockable object by this process (under all XIDs).
- *
  * It's not actually guaranteed that we need to wait when this function is
  * called, because it could be that when we try to find a position at which
  * to insert ourself into the wait queue, we discover that we must be inserted
@@ -1112,7 +1109,8 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable, bool dontWait)
    LWLock     *partitionLock = LockHashPartitionLock(hashcode);
    dclist_head *waitQueue = &lock->waitProcs;
    PGPROC     *insert_before = NULL;
-   LOCKMASK    myHeldLocks = MyProc->heldLocks;
+   LOCKMASK    myProcHeldLocks;
+   LOCKMASK    myHeldLocks;
    TimestampTz standbyWaitStart = 0;
    bool        early_deadlock = false;
    bool        allow_autovacuum_cancel = true;
@@ -1121,6 +1119,8 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable, bool dontWait)
    PGPROC     *leader = MyProc->lockGroupLeader;
 
    /*
+    * Determine which locks we're already holding.
+    *
     * If group locking is in use, locks held by members of my locking group
     * need to be included in myHeldLocks.  This is not required for relation
     * extension lock which conflict among group members. However, including
@@ -1130,6 +1130,8 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable, bool dontWait)
     * that kind of locks, but there doesn't appear to be a clear advantage of
     * the same.
     */
+   myProcHeldLocks = proclock->holdMask;
+   myHeldLocks = myProcHeldLocks;
    if (leader != NULL)
    {
        dlist_iter  iter;
@@ -1234,6 +1236,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable, bool dontWait)
    lock->waitMask |= LOCKBIT_ON(lockmode);
 
    /* Set up wait information in PGPROC object, too */
+   MyProc->heldLocks = myProcHeldLocks;
    MyProc->waitLock = lock;
    MyProc->waitProcLock = proclock;
    MyProc->waitLockMode = lockmode;