summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJean-Sébastien Pédron <jean-sebastien@rabbitmq.com>2020-04-08 14:56:16 +0200
committerJean-Sébastien Pédron <jean-sebastien@rabbitmq.com>2020-04-09 10:21:19 +0200
commit9f4b27736ab7569f952828963ef3371aa95d3ac9 (patch)
treea7edc99866ef8d42f5fbae3266da0aa0d9cbbba4 /src
parent91d17eb28a81b682b3ce4a4a388d5269e04ddf75 (diff)
downloadrabbitmq-server-git-9f4b27736ab7569f952828963ef3371aa95d3ac9.tar.gz
rabbit_feature_flags: Fix concurrent registry module reload
By calling code:delete() ourselves, we created a time window where there is no registry module loaded between that call and the following code:load_binary(). This meant that a concurrent access to the registry would trigger a load of the initial uninitialized registry module from disk. That module would then trigger a reload itself, leading to possible deadlock. In fact, in code:load_binary(), the code server already takes care of replacing the module atomically. We don't need to do anything.
Diffstat (limited to 'src')
-rw-r--r--src/rabbit_feature_flags.erl14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/rabbit_feature_flags.erl b/src/rabbit_feature_flags.erl
index fd365fde55..0cddd1b66e 100644
--- a/src/rabbit_feature_flags.erl
+++ b/src/rabbit_feature_flags.erl
@@ -1287,8 +1287,20 @@ load_registry_mod(Mod, Bin) ->
rabbit_log_feature_flags:debug(
"Feature flags: acquired lock before reloading registry module (~p)",
[self()]),
+ %% We want to make sure that the old registry (not the one being
+ %% currently in use) is purged by the code server. It means no
+ %% process lingers on that old code.
+ %%
+ %% We use code:soft_purge() for that (meaning no process is killed)
+ %% and we wait in an infinite loop for that to succeed.
ok = purge_old_registry(Mod),
- true = code:delete(Mod),
+ %% Now we can replace the currently loaded registry by the new one.
+ %% The code server takes care of marking the current registry as old
+ %% and load the new module in an atomic operation.
+ %%
+ %% Therefore there is no chance of a window where there is no
+ %% registry module available, causing the one on disk to be
+ %% reloaded.
Ret = code:load_binary(Mod, FakeFilename, Bin),
rabbit_log_feature_flags:debug(
"Feature flags: releasing lock after reloading registry module (~p)",