diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2006-01-07 21:16:10 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2006-01-07 21:16:10 +0000 |
commit | 7eb5428199fddf69b24e03c85db3e8873cde605d (patch) | |
tree | e3e1dcc6ae0a96454ac874d4b937e3209023676c /src/backend/utils/cache | |
parent | 0a8510e0f856127ef35706ee1697383b470de9f1 (diff) | |
download | postgresql-7eb5428199fddf69b24e03c85db3e8873cde605d.tar.gz postgresql-7eb5428199fddf69b24e03c85db3e8873cde605d.zip |
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.
Diffstat (limited to 'src/backend/utils/cache')
-rw-r--r-- | src/backend/utils/cache/catcache.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 824dbaed02f..6d41ed94525 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -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 */ |