Fix crash if LockErrorCleanup() is called twice
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 28 Mar 2025 18:19:17 +0000 (20:19 +0200)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 28 Mar 2025 18:19:17 +0000 (20:19 +0200)
The refactoring in commit 3c0fd64fec removed the clearing of
awaitedLock from LockErrorCleanup(). It's still needed, otherwise
LockErrorCleanup() during abort processing will try to update the
LOCALLOCK struct even after the lock has already been released. Put it
back.

Reported-by: Richard Guo <guofenglinux@gmail.com>
Reported-by: Robins Tharakan <tharakan@gmail.com>
Reported-by: Alexander Lakhin <exclusion@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/CAMbWs4_dNX1SzBmvFdoY-LxJh_4W_BjtVd5i008ihfU-wFF=eg@mail.gmail.com
Discussion: https://www.postgresql.org/message-id/18832-38e5575b1bbd7277@postgresql.org
Discussion: https://www.postgresql.org/message-id/e11a30e5-c0d8-491d-8546-3a1b50c10ad4@gmail.com

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

index 38a5d75bbe1f2a5d4e4ede91c142d1026767d314..002303664aa5c7bace4b87fc42acb971c2e38b97 100644 (file)
@@ -1896,6 +1896,15 @@ GetAwaitedLock(void)
    return awaitedLock;
 }
 
+/*
+ * ResetAwaitedLock -- Forget that we are waiting on a lock.
+ */
+void
+ResetAwaitedLock(void)
+{
+   awaitedLock = NULL;
+}
+
 /*
  * MarkLockClear -- mark an acquired lock as "clear"
  *
index e4ca861a8e6f41f0ff06bb8f4bceee7b26f64a8b..066319afe2b08c46a36a3a205718399dc44d756a 100644 (file)
@@ -814,6 +814,8 @@ LockErrorCleanup(void)
            GrantAwaitedLock();
    }
 
+   ResetAwaitedLock();
+
    LWLockRelease(partitionLock);
 
    RESUME_INTERRUPTS();
index ad4e40badbe8263d78cad70cd660755ad59bb193..6f2108a44e8fbf0b48691ccd678d3ac45ea7b544 100644 (file)
@@ -588,6 +588,7 @@ extern bool LockCheckConflicts(LockMethod lockMethodTable,
 extern void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode);
 extern void GrantAwaitedLock(void);
 extern LOCALLOCK *GetAwaitedLock(void);
+extern void ResetAwaitedLock(void);
 
 extern void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode);
 extern LockData *GetLockStatusData(void);