diff options
Diffstat (limited to 'erts/emulator/test/code_SUITE_data/call_fun_before_load.erl')
-rw-r--r-- | erts/emulator/test/code_SUITE_data/call_fun_before_load.erl | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/erts/emulator/test/code_SUITE_data/call_fun_before_load.erl b/erts/emulator/test/code_SUITE_data/call_fun_before_load.erl new file mode 100644 index 0000000000..9ede44ebd2 --- /dev/null +++ b/erts/emulator/test/code_SUITE_data/call_fun_before_load.erl @@ -0,0 +1,45 @@ +-module(call_fun_before_load). +-export([run/2]). + +run(ObjFile, Code) -> + Ref = make_ref(), + Self = self(), + {Pid, MRef} = + spawn_monitor( + fun() -> + %% If we're called before being loaded, process_info/2 can't + %% figure out where we are, reporting that we're in an + %% unknown module rather than the current one. + Fun0 = fun(Fun) -> + {current_function, + {?MODULE, _, _}} = + process_info(self(), current_function), + Fun(Fun) + end, + + NumScheds = erlang:system_info(schedulers_online), + Workers = [spawn_link(fun() -> Fun0(Fun0) end) + || _ <- lists:seq(1, NumScheds)], + + %% Give the workers time to start before reloading ourselves. + timer:sleep(100), + + code:load_binary(?MODULE, ObjFile, Code), + + %% Give the workers time to crash before exiting. + timer:sleep(100), + + Self ! {Ref, Workers}, + + ok + end), + receive + {Ref, Workers} -> + erlang:demonitor(MRef, [flush]), + [exit(Worker, kill) || Worker <- Workers], + ok; + {'DOWN', MRef, process, Pid, {{badmatch,_}, _}} -> + ct:fail("Ran newly staged but not yet loaded code.", []); + {'DOWN', MRef, process, Pid, Reason} -> + ct:fail(Reason) + end. |