From 4b69622d72046f26e17a9e3500a924219685032e Mon Sep 17 00:00:00 2001
From: vans163 <vans_163@yahoo.com>
Date: Thu, 1 Sep 2016 12:06:10 -0400
Subject: 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.
---
 src/rebar_agent.erl | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

(limited to 'src')

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].
-- 
cgit v1.1