From 5ee9ae963e3a6143975f543761f51b1bc0dc5de8 Mon Sep 17 00:00:00 2001 From: Andrey Borodin Date: Fri, 23 Jul 2021 16:00:31 +0500 Subject: [PATCH] Avoid duplication in relcache and syscache callbacks --- src/backend/utils/cache/inval.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c index dcfd9e8389..692ec8f04f 100644 --- a/src/backend/utils/cache/inval.c +++ b/src/backend/utils/cache/inval.c @@ -1430,17 +1430,32 @@ CacheInvalidateRelmap(Oid databaseId) * Yes, there's a possibility of a false match to zero, but it doesn't seem * worth troubling over, especially since most of the current callees just * flush all cached state anyway. + * Each callback\arg will we called only once, even if it was registered + * many times. */ void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg) { + int i; if (cacheid < 0 || cacheid >= SysCacheSize) elog(FATAL, "invalid cache ID: %d", cacheid); if (syscache_callback_count >= MAX_SYSCACHE_CALLBACKS) elog(FATAL, "out of syscache_callback_list slots"); + for (i = 0; i < syscache_callback_count; i++) + { + if (syscache_callback_list[i].id == cacheid && + syscache_callback_list[i].function == func && + syscache_callback_list[i].arg == arg) + { + elog(DEBUG1, "Duplicate registartion of syscache callback"); + /* Already registered */ + return; + } + } + if (syscache_callback_links[cacheid] == 0) { /* first callback for this cache */ @@ -1472,14 +1487,28 @@ CacheRegisterSyscacheCallback(int cacheid, * * NOTE: InvalidOid will be passed if a cache reset request is received. * In this case the called routines should flush all cached state. + * Each callback\arg will we called only once, even if it was registered + * many times. */ void CacheRegisterRelcacheCallback(RelcacheCallbackFunction func, Datum arg) { + int i; if (relcache_callback_count >= MAX_RELCACHE_CALLBACKS) elog(FATAL, "out of relcache_callback_list slots"); + for (i = 0; i < relcache_callback_count; i++) + { + if (relcache_callback_list[i].function == func && + relcache_callback_list[i].arg == arg) + { + /* Already registered */ + elog(DEBUG1, "Duplicate registartion of relcache callback"); + return; + } + } + relcache_callback_list[relcache_callback_count].function = func; relcache_callback_list[relcache_callback_count].arg = arg; -- 2.24.3 (Apple Git-128)