summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoralisdair sullivan <alisdairsullivan@yahoo.ca>2016-09-02 16:35:26 -0700
committerGitHub <noreply@github.com>2016-09-02 16:35:26 -0700
commit909d1f248d39191a512d8c4179329d6c908fc533 (patch)
tree5b7ca065893e974f382c645eadc1f7c1e0ccd7e1 /src
parent8efcd3b92b9328942d3f50c53cbb95d28bd3a6fd (diff)
parent0f524bb6c2efc687956af85150b322b3ed883b03 (diff)
Merge pull request #1320 from vans163/atomic_compile_and_nif_fix
Atomically load changed erlang modules. Non-atomically load nifs. Reference to https://github.com/erlang/rebar3/pull/1317
Diffstat (limited to 'src')
-rw-r--r--src/rebar_agent.erl34
1 files changed, 32 insertions, 2 deletions
diff --git a/src/rebar_agent.erl b/src/rebar_agent.erl
index 95818d8..8e1c8f6 100644
--- a/src/rebar_agent.erl
+++ b/src/rebar_agent.erl
@@ -109,8 +109,7 @@ refresh_paths(RState) ->
{X,X} ->
?DEBUG("reloading ~p from ~s", [Modules, Path]),
code:replace_path(App, Path),
- [begin code:purge(M), code:delete(M), code:load_file(M) end
- || M <- Modules];
+ reload_modules(Modules);
{_,_} ->
?DEBUG("skipping app ~p, stable copy required", [App])
end
@@ -123,3 +122,34 @@ refresh_state(RState, _Dir) ->
rebar3:init_config(),
[fun(S) -> rebar_state:apply_profiles(S, rebar_state:current_profiles(RState)) end]
).
+
+reload_modules([]) -> noop;
+reload_modules(Modules) ->
+ reload_modules(Modules, erlang:function_exported(code, prepare_loading, 1)).
+
+%% OTP 19 and later -- use atomic loading and ignore unloadable mods
+reload_modules(Modules, true) ->
+ case code:prepare_loading(Modules) of
+ {ok, Prepared} ->
+ [code:purge(M) || M <- Modules],
+ code:finish_loading(Prepared);
+
+ {error, ModRsns} ->
+ Blacklist =
+ lists:foldr(fun({ModError, Error}, Acc) ->
+ case Error of
+ %perhaps cover other cases of failure?
+ on_load_not_allowed ->
+ reload_modules([ModError], false),
+ [ModError|Acc];
+ _ -> [ModError|Acc]
+ end
+ end,
+ [], ModRsns
+ ),
+ reload_modules(Modules -- Blacklist, true)
+ end;
+
+%% Older versions, use a more ad-hoc mechanism.
+reload_modules(Modules, false) ->
+ [begin code:delete(M), code:purge(M), code:load_file(M) end || M <- Modules].