]> granicus.if.org Git - postgresql/commitdiff
When LockAcquire fails at the stage of creating a proclock object, be
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 12 Sep 2004 18:30:50 +0000 (18:30 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 12 Sep 2004 18:30:50 +0000 (18:30 +0000)
sure to clean up the already-created lock object, if it has no other
references.  Avoids possibly-permanent leak of shared memory.

src/backend/storage/lmgr/lock.c

index 55fba035a91b9cbaeddf8e6c3eb3940b132cc84f..f90a3fd0e841198ca8a36640b4d954cb8033cb9c 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.139 2004/08/29 05:06:48 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.140 2004/09/12 18:30:50 tgl Exp $
  *
  * NOTES
  *       Outside modules can create a lock table and acquire/release
@@ -602,7 +602,23 @@ LockAcquire(LOCKMETHODID lockmethodid, LOCKTAG *locktag,
                                                                                HASH_ENTER, &found);
        if (!proclock)
        {
+               /* Ooops, not enough shmem for the proclock */
+               if (lock->nRequested == 0)
+               {
+                       /*
+                        * There are no other requestors of this lock, so garbage-collect
+                        * the lock object.  We *must* do this to avoid a permanent leak
+                        * of shared memory, because there won't be anything to cause
+                        * anyone to release the lock object later.
+                        */
+                       Assert(SHMQueueEmpty(&(lock->procLocks)));
+                       lock = (LOCK *) hash_search(LockMethodLockHash[lockmethodid],
+                                                                               (void *) &(lock->tag),
+                                                                               HASH_REMOVE, NULL);
+               }
                LWLockRelease(masterLock);
+               if (!lock)                              /* hash remove failed? */
+                       elog(WARNING, "lock table corrupted");
                ereport(ERROR,
                                (errcode(ERRCODE_OUT_OF_MEMORY),
                                 errmsg("out of shared memory"),
@@ -1528,7 +1544,7 @@ LockReleaseAll(LOCKMETHODID lockmethodid, bool allxids)
                        if (!lock)
                        {
                                LWLockRelease(masterLock);
-                               elog(WARNING, "cannot remove lock from HTAB");
+                               elog(WARNING, "lock table corrupted");
                                return FALSE;
                        }
                }