From 7b65ce787edac68d476b5d0ed34d09b46d115cc7 Mon Sep 17 00:00:00 2001 From: Matvey Arye Date: Tue, 25 Aug 2020 12:03:12 -0400 Subject: [PATCH] Fix recursion in cache processing Previously, cache invalidation could cause recursion in cache processing. PR #1493 fixed this for the cache_invalidate_callback() -> ts_extension_invalidate() call path. But the call path cache_invalidate_callback() -> ts_extension_is_loaded() could still go into recursion. So, this PR moves the recursion-prevention logic into extension_update_state(), which is common to both call paths. Fixes #2200. --- src/extension.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/extension.c b/src/extension.c index 36b9a1ca8cb..a518a79d11a 100644 --- a/src/extension.c +++ b/src/extension.c @@ -139,10 +139,20 @@ extension_set_state(enum ExtensionState newstate) } /* Updates the state based on the current state, returning whether there had been a change. */ -static bool +static void extension_update_state() { - return extension_set_state(extension_current_state()); + static bool in_recursion = false; + /* Since the state of the extension is determined by the snapshot of the transaction there + * is no point processing recursive calls as the outer call will always set the correct state. + * This also prevents deep recursion during `AcceptInvalidationMessages`. + */ + if (in_recursion) + return; + + in_recursion = true; + extension_set_state(extension_current_state()); + in_recursion = false; } Oid @@ -199,18 +209,8 @@ ts_extension_schema_name(void) bool ts_extension_invalidate(Oid relid) { - static bool in_recursion = false; bool invalidate_all = false; - /* Since the state of the extension is determined by the snapshot of the transaction there - * is no point processing recursive calls as the outer call will always set the correct state. - * This also prevents deep recursion during `AcceptInvalidationMessages`. - */ - if (in_recursion) - return false; - - in_recursion = true; - switch (extstate) { case EXTENSION_STATE_NOT_INSTALLED: @@ -245,7 +245,6 @@ ts_extension_invalidate(Oid relid) elog(ERROR, "unknown state: %d", extstate); break; } - in_recursion = false; return invalidate_all; }