aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2015-12-15 20:32:39 +0100
committerSverker Eriksson <[email protected]>2016-01-13 19:59:53 +0100
commitfa44f865c3fc6253cf4691cf94839c303a3ee40f (patch)
tree47ec77902253825bceab86035a6c960b801188e2 /lib
parentc612edf4ada1f00b2bdb8404103e0d8307dc8f4c (diff)
downloadotp-fa44f865c3fc6253cf4691cf94839c303a3ee40f.tar.gz
otp-fa44f865c3fc6253cf4691cf94839c303a3ee40f.tar.bz2
otp-fa44f865c3fc6253cf4691cf94839c303a3ee40f.zip
erts: Make erlang:purge_module/1 safe
Problem: erlang:purge_module/1 is not safe in the sense that very bad things may happen if the code to be purged is still referred to by live processes. Introduce erts_internal:purge_module which is the same as the old erlang:purge_module BIF (except it returns false if no such old module). Implement erlang:purge_module in Erlang and let it invoke erts_code_purger for safe purging where all clogging processes first are killed.
Diffstat (limited to 'lib')
-rw-r--r--lib/kernel/test/code_SUITE.erl21
1 files changed, 17 insertions, 4 deletions
diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl
index 071f8d1d3b..772a1e6b14 100644
--- a/lib/kernel/test/code_SUITE.erl
+++ b/lib/kernel/test/code_SUITE.erl
@@ -380,8 +380,23 @@ purge(Config) when is_list(Config) ->
purge_many_exits(Config) when is_list(Config) ->
OldFlag = process_flag(trap_exit, true),
+
code:purge(code_b_test),
{'EXIT',_} = (catch code:purge({})),
+
+ CodePurgeF = fun(M, Exp) -> Exp = code:purge(M) end,
+ purge_many_exits_do(CodePurgeF),
+
+ %% Let's repeat test for erlang:purge_module as it does the same thing
+ %% now in erts-8.0 (except for return value).
+ ErlangPurgeF = fun(M, _Exp) -> erlang:purge_module(M) end,
+ purge_many_exits_do(ErlangPurgeF),
+
+ process_flag(trap_exit, OldFlag),
+ ok.
+
+
+purge_many_exits_do(PurgeF) ->
false = code:purge(code_b_test),
TPids = lists:map(fun (_) ->
{code_b_test:do_spawn(),
@@ -400,7 +415,7 @@ purge_many_exits(Config) when is_list(Config) ->
false = code_b_test:check_exit(Pid1),
true = erlang:is_process_alive(Pid2)
end, TPids),
- true = code:purge(code_b_test),
+ PurgeF(code_b_test, true),
lists:foreach(fun ({Pid1, Pid2}) ->
false = erlang:is_process_alive(Pid1),
true = code_b_test:check_exit(Pid1),
@@ -409,9 +424,7 @@ purge_many_exits(Config) when is_list(Config) ->
end, TPids),
lists:foreach(fun ({_Pid1, Pid2}) ->
receive {'EXIT', Pid2, _} -> ok end
- end, TPids),
- process_flag(trap_exit, OldFlag),
- ok.
+ end, TPids).
soft_purge(suite) -> [];