When LockAcquire fails at the stage of creating a proclock object, be

sure to clean up the already-created lock object, if it has no other
references.  Avoids possibly-permanent leak of shared memory.
This commit is contained in:
Tom Lane 2004-09-12 18:30:50 +00:00
parent 493f72606b
commit abc98dcc15

View 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;
}
}