diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 3bb5ce3..9475fe1 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -794,6 +794,7 @@ LockAcquireExtended(const LOCKTAG *locktag, */ if (!found) { + dlist_push_head(&MyProc->localLocks, &locallock->procLink); locallock->lock = NULL; locallock->proclock = NULL; locallock->hashcode = LockTagHashCode(&(localtag.lock)); @@ -1320,6 +1321,7 @@ RemoveLocalLock(LOCALLOCK *locallock) SpinLockRelease(&FastPathStrongRelationLocks->mutex); } + dlist_delete(&locallock->procLink); if (!hash_search(LockMethodLocalHash, (void *) &(locallock->tag), HASH_REMOVE, NULL)) @@ -2088,7 +2090,7 @@ LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock) void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks) { - HASH_SEQ_STATUS status; + dlist_mutable_iter iter; LockMethod lockMethodTable; int i, numLockModes; @@ -2126,10 +2128,10 @@ LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks) * pointers. Fast-path locks are cleaned up during the locallock table * scan, though. */ - hash_seq_init(&status, LockMethodLocalHash); - - while ((locallock = (LOCALLOCK *) hash_seq_search(&status)) != NULL) + dlist_foreach_modify(iter, &MyProc->localLocks) { + locallock = dlist_container(LOCALLOCK, procLink, iter.cur); + /* * If the LOCALLOCK entry is unused, we must've run out of shared * memory while trying to set up this lock. Just forget the local @@ -2362,16 +2364,16 @@ LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks) void LockReleaseSession(LOCKMETHODID lockmethodid) { - HASH_SEQ_STATUS status; + dlist_mutable_iter iter; LOCALLOCK *locallock; if (lockmethodid <= 0 || lockmethodid >= lengthof(LockMethods)) elog(ERROR, "unrecognized lock method: %d", lockmethodid); - hash_seq_init(&status, LockMethodLocalHash); - - while ((locallock = (LOCALLOCK *) hash_seq_search(&status)) != NULL) + dlist_foreach_modify(iter, &MyProc->localLocks) { + locallock = dlist_container(LOCALLOCK, procLink, iter.cur); + /* Ignore items that are not of the specified lock method */ if (LOCALLOCK_LOCKMETHOD(*locallock) != lockmethodid) continue; @@ -2394,13 +2396,14 @@ LockReleaseCurrentOwner(LOCALLOCK **locallocks, int nlocks) { if (locallocks == NULL) { - HASH_SEQ_STATUS status; + dlist_mutable_iter iter; LOCALLOCK *locallock; - hash_seq_init(&status, LockMethodLocalHash); - - while ((locallock = (LOCALLOCK *) hash_seq_search(&status)) != NULL) + dlist_foreach_modify(iter, &MyProc->localLocks) + { + locallock = dlist_container(LOCALLOCK, procLink, iter.cur); ReleaseLockIfHeld(locallock, false); + } } else { @@ -2493,13 +2496,14 @@ LockReassignCurrentOwner(LOCALLOCK **locallocks, int nlocks) if (locallocks == NULL) { - HASH_SEQ_STATUS status; + dlist_mutable_iter iter; LOCALLOCK *locallock; - hash_seq_init(&status, LockMethodLocalHash); - - while ((locallock = (LOCALLOCK *) hash_seq_search(&status)) != NULL) + dlist_foreach_modify(iter, &MyProc->localLocks) + { + locallock = dlist_container(LOCALLOCK, procLink, iter.cur); LockReassignOwner(locallock, parent); + } } else { @@ -3133,8 +3137,7 @@ LockRefindAndRelease(LockMethod lockMethodTable, PGPROC *proc, void AtPrepare_Locks(void) { - HASH_SEQ_STATUS status; - LOCALLOCK *locallock; + dlist_mutable_iter iter; /* * For the most part, we don't need to touch shared memory for this --- @@ -3142,10 +3145,9 @@ AtPrepare_Locks(void) * Fast-path locks are an exception, however: we move any such locks to * the main table before allowing PREPARE TRANSACTION to succeed. */ - hash_seq_init(&status, LockMethodLocalHash); - - while ((locallock = (LOCALLOCK *) hash_seq_search(&status)) != NULL) + dlist_foreach_modify(iter, &MyProc->localLocks) { + LOCALLOCK *locallock = dlist_container(LOCALLOCK, procLink, iter.cur); TwoPhaseLockRecord record; LOCALLOCKOWNER *lockOwners = locallock->lockOwners; bool haveSessionLock; @@ -3244,8 +3246,7 @@ void PostPrepare_Locks(TransactionId xid) { PGPROC *newproc = TwoPhaseGetDummyProc(xid); - HASH_SEQ_STATUS status; - LOCALLOCK *locallock; + dlist_mutable_iter iter; LOCK *lock; PROCLOCK *proclock; PROCLOCKTAG proclocktag; @@ -3267,10 +3268,9 @@ PostPrepare_Locks(TransactionId xid) * pointing to the same proclock, and we daren't end up with any dangling * pointers. */ - hash_seq_init(&status, LockMethodLocalHash); - - while ((locallock = (LOCALLOCK *) hash_seq_search(&status)) != NULL) + dlist_foreach_modify(iter, &MyProc->localLocks) { + LOCALLOCK *locallock = dlist_container(LOCALLOCK, procLink, iter.cur); LOCALLOCKOWNER *lockOwners = locallock->lockOwners; bool haveSessionLock; bool haveXactLock; diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 89c80fb..a22d73a 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -389,6 +389,7 @@ InitProcess(void) MyProc->lwWaitMode = 0; MyProc->waitLock = NULL; MyProc->waitProcLock = NULL; + dlist_init(&MyProc->localLocks); #ifdef USE_ASSERT_CHECKING { int i; @@ -568,6 +569,7 @@ InitAuxiliaryProcess(void) MyProc->lwWaitMode = 0; MyProc->waitLock = NULL; MyProc->waitProcLock = NULL; + dlist_init(&MyProc->localLocks); #ifdef USE_ASSERT_CHECKING { int i; diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h index 16b927c..20887f4 100644 --- a/src/include/storage/lock.h +++ b/src/include/storage/lock.h @@ -18,6 +18,7 @@ #error "lock.h may not be included from frontend code" #endif +#include "lib/ilist.h" #include "storage/lockdefs.h" #include "storage/backendid.h" #include "storage/lwlock.h" @@ -406,6 +407,7 @@ typedef struct LOCALLOCK /* data */ LOCK *lock; /* associated LOCK object, if any */ PROCLOCK *proclock; /* associated PROCLOCK object, if any */ + dlist_node procLink; /* list link in PGPROC's list of LOCALLOCKs */ uint32 hashcode; /* copy of LOCKTAG's hash value */ int64 nLocks; /* total number of times lock is held */ bool holdsStrongLockCount; /* bumped FastPathStrongRelationLocks */ diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h index d203acb..031e004 100644 --- a/src/include/storage/proc.h +++ b/src/include/storage/proc.h @@ -138,6 +138,7 @@ struct PGPROC /* waitLock and waitProcLock are NULL if not currently waiting. */ LOCK *waitLock; /* Lock object we're sleeping on ... */ PROCLOCK *waitProcLock; /* Per-holder info for awaited lock */ + dlist_head localLocks; /* List of LOCALLOCKs */ LOCKMODE waitLockMode; /* type of lock we're waiting for */ LOCKMASK heldLocks; /* bitmask for lock types already held on this * lock object by this backend */