diff options
author | Sverker Eriksson <[email protected]> | 2015-12-15 20:32:39 +0100 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2016-01-13 19:59:53 +0100 |
commit | fa44f865c3fc6253cf4691cf94839c303a3ee40f (patch) | |
tree | 47ec77902253825bceab86035a6c960b801188e2 /lib/kernel | |
parent | c612edf4ada1f00b2bdb8404103e0d8307dc8f4c (diff) | |
download | otp-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/kernel')
-rw-r--r-- | lib/kernel/test/code_SUITE.erl | 21 |
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) -> []; |