aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/src
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2016-07-04 11:56:20 +0200
committerLukas Larsson <[email protected]>2016-08-12 11:35:09 +0200
commit53a487cd5019e7f7e3abee6b4a5e2d0b05aa34c6 (patch)
tree84d36c55f2b30345dd553f38f4bad1de75c3384d /lib/kernel/src
parent30e1d890e37ffd57bfbcf043b3b982c781139418 (diff)
downloadotp-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.erl6
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) ->