aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/cache/catcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/cache/catcache.c')
-rw-r--r--src/backend/utils/cache/catcache.c125
1 files changed, 102 insertions, 23 deletions
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 18db7e78e21..2e2e4d9f1f7 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -31,12 +31,13 @@
#endif
#include "storage/lmgr.h"
#include "utils/builtins.h"
+#include "utils/catcache.h"
#include "utils/datum.h"
#include "utils/fmgroids.h"
#include "utils/inval.h"
#include "utils/memutils.h"
#include "utils/rel.h"
-#include "utils/resowner_private.h"
+#include "utils/resowner.h"
#include "utils/syscache.h"
@@ -94,6 +95,8 @@ static CatCTup *CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp,
uint32 hashValue, Index hashIndex,
bool negative);
+static void ReleaseCatCacheWithOwner(HeapTuple tuple, ResourceOwner resowner);
+static void ReleaseCatCacheListWithOwner(CatCList *list, ResourceOwner resowner);
static void CatCacheFreeKeys(TupleDesc tupdesc, int nkeys, int *attnos,
Datum *keys);
static void CatCacheCopyKeys(TupleDesc tupdesc, int nkeys, int *attnos,
@@ -104,6 +107,56 @@ static void CatCacheCopyKeys(TupleDesc tupdesc, int nkeys, int *attnos,
* internal support functions
*/
+/* ResourceOwner callbacks to hold catcache references */
+
+static void ResOwnerReleaseCatCache(Datum res);
+static char *ResOwnerPrintCatCache(Datum res);
+static void ResOwnerReleaseCatCacheList(Datum res);
+static char *ResOwnerPrintCatCacheList(Datum res);
+
+static const ResourceOwnerDesc catcache_resowner_desc =
+{
+ /* catcache references */
+ .name = "catcache reference",
+ .release_phase = RESOURCE_RELEASE_AFTER_LOCKS,
+ .release_priority = RELEASE_PRIO_CATCACHE_REFS,
+ .ReleaseResource = ResOwnerReleaseCatCache,
+ .DebugPrint = ResOwnerPrintCatCache
+};
+
+static const ResourceOwnerDesc catlistref_resowner_desc =
+{
+ /* catcache-list pins */
+ .name = "catcache list reference",
+ .release_phase = RESOURCE_RELEASE_AFTER_LOCKS,
+ .release_priority = RELEASE_PRIO_CATCACHE_LIST_REFS,
+ .ReleaseResource = ResOwnerReleaseCatCacheList,
+ .DebugPrint = ResOwnerPrintCatCacheList
+};
+
+/* Convenience wrappers over ResourceOwnerRemember/Forget */
+static inline void
+ResourceOwnerRememberCatCacheRef(ResourceOwner owner, HeapTuple tuple)
+{
+ ResourceOwnerRemember(owner, PointerGetDatum(tuple), &catcache_resowner_desc);
+}
+static inline void
+ResourceOwnerForgetCatCacheRef(ResourceOwner owner, HeapTuple tuple)
+{
+ ResourceOwnerForget(owner, PointerGetDatum(tuple), &catcache_resowner_desc);
+}
+static inline void
+ResourceOwnerRememberCatCacheListRef(ResourceOwner owner, CatCList *list)
+{
+ ResourceOwnerRemember(owner, PointerGetDatum(list), &catlistref_resowner_desc);
+}
+static inline void
+ResourceOwnerForgetCatCacheListRef(ResourceOwner owner, CatCList *list)
+{
+ ResourceOwnerForget(owner, PointerGetDatum(list), &catlistref_resowner_desc);
+}
+
+
/*
* Hash and equality functions for system types that are used as cache key
* fields. In some cases, we just call the regular SQL-callable functions for
@@ -1268,7 +1321,7 @@ SearchCatCacheInternal(CatCache *cache,
*/
if (!ct->negative)
{
- ResourceOwnerEnlargeCatCacheRefs(CurrentResourceOwner);
+ ResourceOwnerEnlarge(CurrentResourceOwner);
ct->refcount++;
ResourceOwnerRememberCatCacheRef(CurrentResourceOwner, &ct->tuple);
@@ -1369,7 +1422,7 @@ SearchCatCacheMiss(CatCache *cache,
hashValue, hashIndex,
false);
/* immediately set the refcount to 1 */
- ResourceOwnerEnlargeCatCacheRefs(CurrentResourceOwner);
+ ResourceOwnerEnlarge(CurrentResourceOwner);
ct->refcount++;
ResourceOwnerRememberCatCacheRef(CurrentResourceOwner, &ct->tuple);
break; /* assume only one match */
@@ -1437,6 +1490,12 @@ SearchCatCacheMiss(CatCache *cache,
void
ReleaseCatCache(HeapTuple tuple)
{
+ ReleaseCatCacheWithOwner(tuple, CurrentResourceOwner);
+}
+
+static void
+ReleaseCatCacheWithOwner(HeapTuple tuple, ResourceOwner resowner)
+{
CatCTup *ct = (CatCTup *) (((char *) tuple) -
offsetof(CatCTup, tuple));
@@ -1445,7 +1504,8 @@ ReleaseCatCache(HeapTuple tuple)
Assert(ct->refcount > 0);
ct->refcount--;
- ResourceOwnerForgetCatCacheRef(CurrentResourceOwner, &ct->tuple);
+ if (resowner)
+ ResourceOwnerForgetCatCacheRef(CurrentResourceOwner, &ct->tuple);
if (
#ifndef CATCACHE_FORCE_RELEASE
@@ -1581,7 +1641,7 @@ SearchCatCacheList(CatCache *cache,
dlist_move_head(&cache->cc_lists, &cl->cache_elem);
/* Bump the list's refcount and return it */
- ResourceOwnerEnlargeCatCacheListRefs(CurrentResourceOwner);
+ ResourceOwnerEnlarge(CurrentResourceOwner);
cl->refcount++;
ResourceOwnerRememberCatCacheListRef(CurrentResourceOwner, cl);
@@ -1693,7 +1753,7 @@ SearchCatCacheList(CatCache *cache,
table_close(relation, AccessShareLock);
/* Make sure the resource owner has room to remember this entry. */
- ResourceOwnerEnlargeCatCacheListRefs(CurrentResourceOwner);
+ ResourceOwnerEnlarge(CurrentResourceOwner);
/* Now we can build the CatCList entry. */
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
@@ -1779,11 +1839,18 @@ SearchCatCacheList(CatCache *cache,
void
ReleaseCatCacheList(CatCList *list)
{
+ ReleaseCatCacheListWithOwner(list, CurrentResourceOwner);
+}
+
+static void
+ReleaseCatCacheListWithOwner(CatCList *list, ResourceOwner resowner)
+{
/* Safety checks to ensure we were handed a cache entry */
Assert(list->cl_magic == CL_MAGIC);
Assert(list->refcount > 0);
list->refcount--;
- ResourceOwnerForgetCatCacheListRef(CurrentResourceOwner, list);
+ if (resowner)
+ ResourceOwnerForgetCatCacheListRef(CurrentResourceOwner, list);
if (
#ifndef CATCACHE_FORCE_RELEASE
@@ -2059,31 +2126,43 @@ PrepareToInvalidateCacheTuple(Relation relation,
}
}
+/* ResourceOwner callbacks */
-/*
- * Subroutines for warning about reference leaks. These are exported so
- * that resowner.c can call them.
- */
-void
-PrintCatCacheLeakWarning(HeapTuple tuple)
+static void
+ResOwnerReleaseCatCache(Datum res)
{
+ ReleaseCatCacheWithOwner((HeapTuple) DatumGetPointer(res), NULL);
+}
+
+static char *
+ResOwnerPrintCatCache(Datum res)
+{
+ HeapTuple tuple = (HeapTuple) DatumGetPointer(res);
CatCTup *ct = (CatCTup *) (((char *) tuple) -
offsetof(CatCTup, tuple));
/* Safety check to ensure we were handed a cache entry */
Assert(ct->ct_magic == CT_MAGIC);
- elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
- ct->my_cache->cc_relname, ct->my_cache->id,
- ItemPointerGetBlockNumber(&(tuple->t_self)),
- ItemPointerGetOffsetNumber(&(tuple->t_self)),
- ct->refcount);
+ return psprintf("cache %s (%d), tuple %u/%u has count %d",
+ ct->my_cache->cc_relname, ct->my_cache->id,
+ ItemPointerGetBlockNumber(&(tuple->t_self)),
+ ItemPointerGetOffsetNumber(&(tuple->t_self)),
+ ct->refcount);
}
-void
-PrintCatCacheListLeakWarning(CatCList *list)
+static void
+ResOwnerReleaseCatCacheList(Datum res)
{
- elog(WARNING, "cache reference leak: cache %s (%d), list %p has count %d",
- list->my_cache->cc_relname, list->my_cache->id,
- list, list->refcount);
+ ReleaseCatCacheListWithOwner((CatCList *) DatumGetPointer(res), NULL);
+}
+
+static char *
+ResOwnerPrintCatCacheList(Datum res)
+{
+ CatCList *list = (CatCList *) DatumGetPointer(res);
+
+ return psprintf("cache %s (%d), list %p has count %d",
+ list->my_cache->cc_relname, list->my_cache->id,
+ list, list->refcount);
}