aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib/src/supervisor.erl
diff options
context:
space:
mode:
authorFred Hebert <[email protected]>2011-08-03 10:47:36 -0400
committerFred Hebert <[email protected]>2011-08-23 14:31:09 -0400
commit4f9b938112a80f1c1e210b1a6af40a42f833cfa2 (patch)
tree9fb8fd96f584107c9592c0be3e603d9020a40b69 /lib/stdlib/src/supervisor.erl
parent62f194499810270b488cc46a5e611f0be77f36a7 (diff)
downloadotp-4f9b938112a80f1c1e210b1a6af40a42f833cfa2.tar.gz
otp-4f9b938112a80f1c1e210b1a6af40a42f833cfa2.tar.bz2
otp-4f9b938112a80f1c1e210b1a6af40a42f833cfa2.zip
fix supervisors restarting temporary children
In the current implementation of supervisors, temporary children should never be restarted. However, when a temporary child is restarted as part of a one_for_all or rest_for_one strategy where the failing process is not the temporary child, the supervisor still tries to restart it. Because the supervisor doesn't keep some of the MFA information of temporary children, this causes the supervisor to hit its restart limit and crash. This patch fixes the behaviour by inserting a clause in terminate_children/2-3 (private function) that will omit temporary children when building a list of killed processes, to avoid having the supervisor trying to restart them again. Only supervisors in need of restarting children used the list, so the change should be of no impact for the functions that called terminate_children/2-3 only to kill all children. The documentation has been modified to make this behaviour more explicit.
Diffstat (limited to 'lib/stdlib/src/supervisor.erl')
-rw-r--r--lib/stdlib/src/supervisor.erl7
1 files changed, 7 insertions, 0 deletions
diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl
index e60706ed05..dc31647eb5 100644
--- a/lib/stdlib/src/supervisor.erl
+++ b/lib/stdlib/src/supervisor.erl
@@ -735,6 +735,13 @@ restart(one_for_all, Child, State) ->
terminate_children(Children, SupName) ->
terminate_children(Children, SupName, []).
+%% Temporary children should not be restarted and thus should
+%% be skipped when building the list of terminated children, although
+%% we do want them to be shut down as many functions from this module
+%% use this function to just clear everything.
+terminate_children([Child = #child{restart_type=temporary} | Children], SupName, Res) ->
+ do_terminate(Child, SupName),
+ terminate_children(Children, SupName, Res);
terminate_children([Child | Children], SupName, Res) ->
NChild = do_terminate(Child, SupName),
terminate_children(Children, SupName, [NChild | Res]);