aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/src/application_controller.erl
diff options
context:
space:
mode:
authorSiri Hansen <[email protected]>2011-11-15 11:27:58 +0100
committerSiri Hansen <[email protected]>2011-11-15 11:27:58 +0100
commit96fcb3f864f787fd3d74f20189eed7a1aba81cb4 (patch)
tree269b3ef8619edfb0a31e9c9c08faaf7edd109b3f /lib/kernel/src/application_controller.erl
parent6acdb64f208e26d78c7f55e6206b75b948e63daa (diff)
downloadotp-96fcb3f864f787fd3d74f20189eed7a1aba81cb4.tar.gz
otp-96fcb3f864f787fd3d74f20189eed7a1aba81cb4.tar.bz2
otp-96fcb3f864f787fd3d74f20189eed7a1aba81cb4.zip
Add env var shutdown_timeout to kernel to avoid deadlock on node shutdown
When a node is shutting down, application_controller will do exit(Pid,shutdown) on all application masters, and wait for {'EXIT',Pid,_}. If, for some reason, the application master does not terminate then application_controller will hang forever waiting for this 'EXIT' message. To overcome this problem, a configurable timer is added to kernel - the enviroment variable 'shutdown_timeout'. If this variable is set to a positive integer T, application_controller will do exit(Pid,kill) after T milli seconds if no 'EXIT' message is received.
Diffstat (limited to 'lib/kernel/src/application_controller.erl')
-rw-r--r--lib/kernel/src/application_controller.erl19
1 files changed, 18 insertions, 1 deletions
diff --git a/lib/kernel/src/application_controller.erl b/lib/kernel/src/application_controller.erl
index 42f527f400..ebfe84463a 100644
--- a/lib/kernel/src/application_controller.erl
+++ b/lib/kernel/src/application_controller.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -1180,10 +1180,27 @@ terminate(Reason, S) ->
_ ->
ok
end,
+ ShutdownTimeout =
+ case application:get_env(kernel, shutdown_timeout) of
+ undefined -> infinity;
+ {ok,T} -> T
+ end,
foreach(fun({_AppName, Id}) when is_pid(Id) ->
+ Ref = erlang:monitor(process, Id),
+ unlink(Id),
exit(Id, shutdown),
receive
+ %% Proc died before link
{'EXIT', Id, _} -> ok
+ after 0 ->
+ receive
+ {'DOWN', Ref, process, Id, _} -> ok
+ after ShutdownTimeout ->
+ exit(Id, kill),
+ receive
+ {'DOWN', Ref, process, Id, _} -> ok
+ end
+ end
end;
(_) -> ok
end,