]> granicus.if.org Git - postgresql/commitdiff
Refactor some duplicated code in lock.c: create UnGrantLock(), move code
authorNeil Conway <neilc@samurai.com>
Fri, 4 Feb 2005 02:04:53 +0000 (02:04 +0000)
committerNeil Conway <neilc@samurai.com>
Fri, 4 Feb 2005 02:04:53 +0000 (02:04 +0000)
from LockRelease() and LockReleaseAll() into it. From Heikki Linnakangas.

src/backend/storage/lmgr/lock.c

index 7bb89e5a10321fe6accadd1b5342fddbc54b1c9d..76b2ff9b480451ef5ad04ff2d2b456c865734ae5 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.145 2004/12/31 22:01:05 pgsql Exp $
+ *       $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.146 2005/02/04 02:04:53 neilc Exp $
  *
  * NOTES
  *       Outside modules can create a lock table and acquire/release
@@ -166,6 +166,8 @@ static int WaitOnLock(LOCKMETHODID lockmethodid, LOCALLOCK *locallock,
                   ResourceOwner owner);
 static void LockCountMyLocks(SHMEM_OFFSET lockOffset, PGPROC *proc,
                                 int *myHolding);
+static bool UnGrantLock(LOCK *lock, LOCKMODE lockmode,
+                                               PROCLOCK *proclock, LockMethod lockMethodTable);
 
 
 /*
@@ -957,6 +959,65 @@ GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode)
        Assert(lock->nGranted <= lock->nRequested);
 }
 
+/*
+ * UnGrantLock -- opposite of GrantLock. 
+ *
+ * Updates the lock and proclock data structures to show that the lock
+ * is no longer held nor requested by the current holder.
+ *
+ * Returns true if there were any waiters waiting on the lock that
+ * should now be woken up with ProcLockWakeup.
+ */
+static bool
+UnGrantLock(LOCK *lock, LOCKMODE lockmode,
+                       PROCLOCK *proclock, LockMethod lockMethodTable)
+{
+       bool wakeupNeeded = false;
+
+       Assert((lock->nRequested > 0) && (lock->requested[lockmode] > 0));
+       Assert((lock->nGranted > 0) && (lock->granted[lockmode] > 0));
+       Assert(lock->nGranted <= lock->nRequested);
+
+       /*
+        * fix the general lock stats
+        */
+       lock->nRequested--;
+       lock->requested[lockmode]--;
+       lock->nGranted--;
+       lock->granted[lockmode]--;
+
+       if (lock->granted[lockmode] == 0)
+       {
+               /* change the conflict mask.  No more of this lock type. */
+               lock->grantMask &= LOCKBIT_OFF(lockmode);
+       }
+
+       LOCK_PRINT("UnGrantLock: updated", lock, lockmode);
+       Assert((lock->nRequested >= 0) && (lock->requested[lockmode] >= 0));
+       Assert((lock->nGranted >= 0) && (lock->granted[lockmode] >= 0));
+       Assert(lock->nGranted <= lock->nRequested);
+
+       /*
+        * We need only run ProcLockWakeup if the released lock conflicts with
+        * at least one of the lock types requested by waiter(s).  Otherwise
+        * whatever conflict made them wait must still exist.  NOTE: before
+        * MVCC, we could skip wakeup if lock->granted[lockmode] was still
+        * positive. But that's not true anymore, because the remaining
+        * granted locks might belong to some waiter, who could now be
+        * awakened because he doesn't conflict with his own locks.
+        */
+       if (lockMethodTable->conflictTab[lockmode] & lock->waitMask)
+               wakeupNeeded = true;
+
+       /*
+        * Now fix the per-proclock state.
+        */
+       proclock->holdMask &= LOCKBIT_OFF(lockmode);
+       PROCLOCK_PRINT("UnGrantLock: updated", proclock);
+
+       return wakeupNeeded;
+}
+
 /*
  * GrantLockLocal -- update the locallock data structures to show
  *             the lock request has been granted.
@@ -1265,46 +1326,8 @@ LockRelease(LOCKMETHODID lockmethodid, LOCKTAG *locktag,
                RemoveLocalLock(locallock);
                return FALSE;
        }
-       Assert((lock->nRequested > 0) && (lock->requested[lockmode] > 0));
-       Assert((lock->nGranted > 0) && (lock->granted[lockmode] > 0));
-       Assert(lock->nGranted <= lock->nRequested);
-
-       /*
-        * fix the general lock stats
-        */
-       lock->nRequested--;
-       lock->requested[lockmode]--;
-       lock->nGranted--;
-       lock->granted[lockmode]--;
-
-       if (lock->granted[lockmode] == 0)
-       {
-               /* change the conflict mask.  No more of this lock type. */
-               lock->grantMask &= LOCKBIT_OFF(lockmode);
-       }
-
-       LOCK_PRINT("LockRelease: updated", lock, lockmode);
-       Assert((lock->nRequested >= 0) && (lock->requested[lockmode] >= 0));
-       Assert((lock->nGranted >= 0) && (lock->granted[lockmode] >= 0));
-       Assert(lock->nGranted <= lock->nRequested);
-
-       /*
-        * We need only run ProcLockWakeup if the released lock conflicts with
-        * at least one of the lock types requested by waiter(s).  Otherwise
-        * whatever conflict made them wait must still exist.  NOTE: before
-        * MVCC, we could skip wakeup if lock->granted[lockmode] was still
-        * positive. But that's not true anymore, because the remaining
-        * granted locks might belong to some waiter, who could now be
-        * awakened because he doesn't conflict with his own locks.
-        */
-       if (lockMethodTable->conflictTab[lockmode] & lock->waitMask)
-               wakeupNeeded = true;
 
-       /*
-        * Now fix the per-proclock state.
-        */
-       proclock->holdMask &= LOCKBIT_OFF(lockmode);
-       PROCLOCK_PRINT("LockRelease: updated", proclock);
+       wakeupNeeded = UnGrantLock(lock, lockmode, proclock, lockMethodTable);
 
        /*
         * If this was my last hold on this lock, delete my entry in the
@@ -1483,22 +1506,8 @@ LockReleaseAll(LOCKMETHODID lockmethodid, bool allxids)
                        for (i = 1; i <= numLockModes; i++)
                        {
                                if (proclock->holdMask & LOCKBIT_ON(i))
-                               {
-                                       lock->requested[i]--;
-                                       lock->granted[i]--;
-                                       Assert(lock->requested[i] >= 0 && lock->granted[i] >= 0);
-                                       if (lock->granted[i] == 0)
-                                               lock->grantMask &= LOCKBIT_OFF(i);
-                                       lock->nRequested--;
-                                       lock->nGranted--;
-
-                                       /*
-                                        * Read comments in LockRelease
-                                        */
-                                       if (!wakeupNeeded &&
-                                               lockMethodTable->conflictTab[i] & lock->waitMask)
-                                               wakeupNeeded = true;
-                               }
+                                       wakeupNeeded |= UnGrantLock(lock, i, proclock,
+                                                                                               lockMethodTable);
                        }
                }
                Assert((lock->nRequested >= 0) && (lock->nGranted >= 0));