During CatCacheRemoveCList, we must now remove any members that are

dead and have become unreferenced.  Before 8.1, such members were left
for AtEOXact_CatCache() to clean up, but now AtEOXact_CatCache isn't
supposed to have anything to do.  In an assert-enabled build this bug
leads to an assertion failure at transaction end, but in a non-assert
build the dead member is effectively just a small memory leak.
Per report from Jeremy Drake.
This commit is contained in:
Tom Lane 2006-01-07 21:16:10 +00:00
parent 0a8510e0f8
commit 7eb5428199
1 changed files with 19 additions and 1 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.126 2005/11/22 18:17:24 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.127 2006/01/07 21:16:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -356,7 +356,16 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
Assert(ct->my_cache == cache);
if (ct->c_list)
{
/*
* The cleanest way to handle this is to call CatCacheRemoveCList,
* which will recurse back to me, and the recursive call will do the
* work. Set the "dead" flag to make sure it does recurse.
*/
ct->dead = true;
CatCacheRemoveCList(cache, ct->c_list);
return; /* nothing left to do */
}
/* delink from linked lists */
DLRemove(&ct->lrulist_elem);
@ -375,6 +384,8 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
* CatCacheRemoveCList
*
* Unlink and delete the given cache list entry
*
* NB: any dead member entries that become unreferenced are deleted too.
*/
static void
CatCacheRemoveCList(CatCache *cache, CatCList *cl)
@ -391,6 +402,13 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
Assert(ct->c_list == cl);
ct->c_list = NULL;
/* if the member is dead and now has no references, remove it */
if (
#ifndef CATCACHE_FORCE_RELEASE
ct->dead &&
#endif
ct->refcount == 0)
CatCacheRemoveCTup(cache, ct);
}
/* delink from linked list */