diff options
| author | vans163 <vans_163@yahoo.com> | 2016-09-01 12:06:10 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-09-01 12:06:10 -0400 | 
| commit | 4b69622d72046f26e17a9e3500a924219685032e (patch) | |
| tree | 388235a68874e0ad8a8453deff7eae062fcb0a5c | |
| parent | 8efcd3b92b9328942d3f50c53cbb95d28bd3a6fd (diff) | |
Update rebar_agent.erl
https://github.com/erlang/rebar3/pull/1317 
In reference to with support to load erlang code atomically but load nifs non-atomically.
| -rw-r--r-- | src/rebar_agent.erl | 31 | 
1 files changed, 29 insertions, 2 deletions
| diff --git a/src/rebar_agent.erl b/src/rebar_agent.erl index 95818d8..5d6b050 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,31 @@ 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 =  +            (fun Error([], Acc) -> Acc; +                 Error([ {ModError, on_load_not_allowed} |T], Acc) ->  +                    reload_modules([ModError], false), +                    Error(T, Acc); +                 Error([ {ModError, _} |T], Acc) ->  +                    Error(T, [ModError|Acc]) +            end)(ModRsns, []), +            reload_modules(Modules -- Blacklist, true) +    end; + +%% Older versions, use a more ad-hoc mechanism. Specifically has +%% a harder time dealing with NIFs. +reload_modules(Modules, false) -> +    [begin code:purge(M), code:load_file(M) end || M <- Modules]. | 
