aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/cache
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-01-07 21:16:10 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-01-07 21:16:10 +0000
commit7eb5428199fddf69b24e03c85db3e8873cde605d (patch)
treee3e1dcc6ae0a96454ac874d4b937e3209023676c /src/backend/utils/cache
parent0a8510e0f856127ef35706ee1697383b470de9f1 (diff)
downloadpostgresql-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.c20
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 */