aboutsummaryrefslogtreecommitdiffstats
path: root/erts/preloaded/src
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2016-09-15 11:40:39 +0200
committerBjörn Gustavsson <[email protected]>2016-09-15 11:40:39 +0200
commit687eae1e86817403249f03f534a256a28c5d5251 (patch)
tree75369a6be94deb0e0c0ad2287102dbb16c34b026 /erts/preloaded/src
parent060949fb1ee7d1af366372b43dde5add421a5f73 (diff)
parentfde238fb52133a6c7a2a3f2a2e16f1c1bef62394 (diff)
downloadotp-687eae1e86817403249f03f534a256a28c5d5251.tar.gz
otp-687eae1e86817403249f03f534a256a28c5d5251.tar.bz2
otp-687eae1e86817403249f03f534a256a28c5d5251.zip
Merge branch 'maint'
* maint: erts: Add nif_SUITE:t_on_load erts: Improve nif_SUITE:upgrade test Don't leak old code when loading a modules with an on_load function Conflicts: erts/preloaded/ebin/erts_code_purger.beam erts/preloaded/ebin/erts_internal.beam erts/preloaded/src/erts_code_purger.erl
Diffstat (limited to 'erts/preloaded/src')
-rw-r--r--erts/preloaded/src/erts_code_purger.erl39
-rw-r--r--erts/preloaded/src/erts_internal.erl2
2 files changed, 39 insertions, 2 deletions
diff --git a/erts/preloaded/src/erts_code_purger.erl b/erts/preloaded/src/erts_code_purger.erl
index a48aebe4e7..fd214228c7 100644
--- a/erts/preloaded/src/erts_code_purger.erl
+++ b/erts/preloaded/src/erts_code_purger.erl
@@ -22,7 +22,8 @@
%% Purpose : Implement system process erts_code_purger
%% to handle code module purging.
--export([start/0, purge/1, soft_purge/1, pending_purge_lambda/3]).
+-export([start/0, purge/1, soft_purge/1, pending_purge_lambda/3,
+ finish_after_on_load/2]).
-spec start() -> term().
start() ->
@@ -41,6 +42,11 @@ handle_request({soft_purge, Mod, From, Ref}, Reqs) when is_atom(Mod), is_pid(Fro
{Res, NewReqs} = do_soft_purge(Mod, Reqs),
From ! {reply, soft_purge, Res, Ref},
check_requests(NewReqs);
+handle_request({finish_after_on_load, {Mod,Keep}, From, Ref}, Reqs)
+ when is_atom(Mod), is_boolean(Keep), is_pid(From) ->
+ NewReqs = do_finish_after_on_load(Mod, Keep, Reqs),
+ From ! {reply, finish_after_on_load, ok, Ref},
+ check_requests(NewReqs);
handle_request({test_purge, Mod, From, Type, Ref}, Reqs) when is_atom(Mod), is_pid(From) ->
NewReqs = do_test_purge(Mod, From, Type, Ref, Reqs),
check_requests(NewReqs);
@@ -132,6 +138,37 @@ do_soft_purge(Mod, Reqs) ->
{erts_internal:purge_module(Mod, PurgeOp), NewReqs}
end.
+%% finish_after_on_load(Module, Keep)
+%% Finish after running on_load function. If Keep is false,
+%% purge the code for the on_load function.
+
+finish_after_on_load(Mod, Keep) ->
+ Ref = make_ref(),
+ erts_code_purger ! {finish_after_on_load, {Mod,Keep}, self(), Ref},
+ receive
+ {reply, finish_after_on_load, Result, Ref} ->
+ Result
+ end.
+
+do_finish_after_on_load(Mod, Keep, Reqs) ->
+ erlang:finish_after_on_load(Mod, Keep),
+ case Keep of
+ true ->
+ Reqs;
+ false ->
+ case erts_internal:purge_module(Mod, prepare_on_load) of
+ false ->
+ Reqs;
+ true ->
+ {_DidKill, NewReqs} =
+ check_proc_code(erlang:processes(),
+ Mod, true, Reqs),
+ true = erts_internal:purge_module(Mod, complete),
+ NewReqs
+ end
+ end.
+
+
%%
%% check_proc_code(Pids, Mod, Hard, Preqs) - Send asynchronous
%% requests to all processes to perform a check_process_code
diff --git a/erts/preloaded/src/erts_internal.erl b/erts/preloaded/src/erts_internal.erl
index 438fa477e6..fecdfc348c 100644
--- a/erts/preloaded/src/erts_internal.erl
+++ b/erts/preloaded/src/erts_internal.erl
@@ -302,7 +302,7 @@ release_literal_area_switch() ->
-spec purge_module(Module, Op) -> boolean() when
Module :: module(),
- Op :: 'prepare' | 'abort' | 'complete'.
+ Op :: 'prepare' | 'prepare_on_load' | 'abort' | 'complete'.
purge_module(_Module, _Op) ->
erlang:nif_error(undefined).