diff options
author | Lukas Larsson <[email protected]> | 2016-07-04 11:56:20 +0200 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2016-08-12 11:35:09 +0200 |
commit | 53a487cd5019e7f7e3abee6b4a5e2d0b05aa34c6 (patch) | |
tree | 84d36c55f2b30345dd553f38f4bad1de75c3384d /lib/kernel/src | |
parent | 30e1d890e37ffd57bfbcf043b3b982c781139418 (diff) | |
download | otp-53a487cd5019e7f7e3abee6b4a5e2d0b05aa34c6.tar.gz otp-53a487cd5019e7f7e3abee6b4a5e2d0b05aa34c6.tar.bz2 otp-53a487cd5019e7f7e3abee6b4a5e2d0b05aa34c6.zip |
erts/kernel: Fix code loading deadlock during init:stop
When init:stop is called it walks the application hierarchy
and terminates each process. Some of these processes may do
something while terminating and sometimes that something
needs to load some new code in order to work. When this happens
the code_server could just be in the process of terminating
or the erl_prim_loader could be active. In both these cases
the request to load the new code would cause a deadlock in the
termination of the system.
This commit fixes this by init rejecting attempts to load new code
when init:stop has been called and fixing a termination race in
the code_server.
This however means that the process that tried to do something
when told to terminate (for instance logging that it is terminating)
will crash instead of loading the code.
Diffstat (limited to 'lib/kernel/src')
-rw-r--r-- | lib/kernel/src/code_server.erl | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl index 6174136507..c7d0c3299a 100644 --- a/lib/kernel/src/code_server.erl +++ b/lib/kernel/src/code_server.erl @@ -135,10 +135,14 @@ split_paths([], _S, Path, Paths) -> -spec call(term()) -> term(). call(Req) -> + Ref = erlang:monitor(process, ?MODULE), ?MODULE ! {code_call, self(), Req}, receive {?MODULE, Reply} -> - Reply + erlang:demonitor(Ref,[flush]), + Reply; + {'DOWN',Ref,process,_,_} -> + exit({'DOWN',code_server,Req}) end. reply(Pid, Res) -> |