aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/test/code_SUITE.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2012-01-22 09:53:57 +0100
committerBjörn Gustavsson <[email protected]>2012-01-23 14:28:44 +0100
commit68731828019e14ef46ef6f2b8bd2c6eb87589a43 (patch)
tree430fda75786b9f1f1bdf2c1207943cc8736e0339 /lib/kernel/test/code_SUITE.erl
parent4feb441edfe666ea926b11bb758d34c8b635466c (diff)
downloadotp-68731828019e14ef46ef6f2b8bd2c6eb87589a43.tar.gz
otp-68731828019e14ef46ef6f2b8bd2c6eb87589a43.tar.bz2
otp-68731828019e14ef46ef6f2b8bd2c6eb87589a43.zip
Fix on_load handling in modules loaded by code:load_binary/3
In "13.4 Running a function when a module is loaded" in the Reference Manual, it is said that: A process that calls any function in a module whose on_load function has not yet returned will be suspended until the on_load function has returned. That did not work if the module was loaded using code:load_binary/3. Instead, the callers would get an 'undef' exception.
Diffstat (limited to 'lib/kernel/test/code_SUITE.erl')
-rw-r--r--lib/kernel/test/code_SUITE.erl49
1 files changed, 44 insertions, 5 deletions
diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl
index 10ab3e4370..99b0cd2ffb 100644
--- a/lib/kernel/test/code_SUITE.erl
+++ b/lib/kernel/test/code_SUITE.erl
@@ -30,9 +30,9 @@
load_cached/1, start_node_with_cache/1, add_and_rehash/1,
where_is_file_cached/1, where_is_file_no_cache/1,
purge_stacktrace/1, mult_lib_roots/1, bad_erl_libs/1,
- code_archive/1, code_archive2/1, on_load/1,
- big_boot_embedded/1,
- on_load_embedded/1, on_load_errors/1, native_early_modules/1]).
+ code_archive/1, code_archive2/1, on_load/1, on_load_binary/1,
+ on_load_embedded/1, on_load_errors/1, big_boot_embedded/1,
+ native_early_modules/1]).
-export([init_per_testcase/2, end_per_testcase/2,
init_per_suite/1, end_per_suite/1,
@@ -55,8 +55,8 @@ all() ->
add_and_rehash, where_is_file_no_cache,
where_is_file_cached, purge_stacktrace, mult_lib_roots,
bad_erl_libs, code_archive, code_archive2, on_load,
- on_load_embedded, big_boot_embedded, on_load_errors,
- native_early_modules].
+ on_load_binary, on_load_embedded, on_load_errors,
+ big_boot_embedded, native_early_modules].
groups() ->
[].
@@ -1286,6 +1286,45 @@ on_load_wait_for_all([Ref|T]) ->
end;
on_load_wait_for_all([]) -> ok.
+on_load_binary(_) ->
+ Master = on_load_binary_test_case_process,
+ register(Master, self()),
+
+ %% Construct, compile and pretty-print.
+ Mod = on_load_binary,
+ File = atom_to_list(Mod) ++ ".erl",
+ Forms = [{attribute,1,file,{File,1}},
+ {attribute,1,module,Mod},
+ {attribute,2,export,[{ok,0}]},
+ {attribute,3,on_load,{init,0}},
+ {function,5,init,0,
+ [{clause,5,[],[],
+ [{op,6,'!',
+ {atom,6,Master},
+ {tuple,6,[{atom,6,Mod},{call,6,{atom,6,self},[]}]}},
+ {'receive',7,[{clause,8,[{atom,8,go}],[],[{atom,8,ok}]}]}]}]},
+ {function,11,ok,0,[{clause,11,[],[],[{atom,11,true}]}]}],
+ {ok,Mod,Bin} = compile:forms(Forms, [report]),
+ [io:put_chars(erl_pp:form(F)) || F <- Forms],
+
+ {Pid1,Ref1} = spawn_monitor(fun() ->
+ code:load_binary(Mod, File, Bin),
+ true = on_load_binary:ok()
+ end),
+ receive {Mod,OnLoadPid} -> ok end,
+ {Pid2,Ref2} = spawn_monitor(fun() ->
+ true = on_load_binary:ok()
+ end),
+ erlang:yield(),
+ OnLoadPid ! go,
+ receive {'DOWN',Ref1,process,Pid1,Exit1} -> ok end,
+ receive {'DOWN',Ref2,process,Pid2,Exit2} -> ok end,
+ normal = Exit1,
+ normal = Exit2,
+ true = code:delete(on_load_binary),
+ false = code:purge(on_load_binary),
+ ok.
+
on_load_embedded(Config) when is_list(Config) ->
try
on_load_embedded_1(Config)