summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Watson <tim@rabbitmq.com>2012-08-30 13:34:17 +0100
committerTim Watson <tim@rabbitmq.com>2012-08-30 13:34:17 +0100
commit6389be116625872fa6f8bde8d071ac2ccd06e81f (patch)
treef99463a380ab7c8020207e0be69b1f13d7157dde
parent2b1256803a3f841c7b374c006c8ab98091f5c534 (diff)
downloadrabbitmq-server-6389be116625872fa6f8bde8d071ac2ccd06e81f.tar.gz
when terminating multiple simple children, we shouldn't rely on the order of 'EXIT' vs 'DOWN' messages
-rw-r--r--src/supervisor2.erl30
1 files changed, 19 insertions, 11 deletions
diff --git a/src/supervisor2.erl b/src/supervisor2.erl
index 3d3623d7..dba9d4b5 100644
--- a/src/supervisor2.erl
+++ b/src/supervisor2.erl
@@ -816,29 +816,37 @@ terminate_simple_children(Child, Dynamics, SupName) ->
{Replies, Timedout} =
lists:foldl(
fun (_Pid, {Replies, Timedout}) ->
- {Reply, Timedout1} =
+ {Pid, Reply, Timedout1} =
receive
TimeoutMsg ->
Remaining = Pids -- [P || {P, _} <- Replies],
[exit(P, kill) || P <- Remaining],
receive {'DOWN', _MRef, process, Pid, Reason} ->
- {{error, Reason}, true}
+ Res = child_res(Child, Reason, Timedout),
+ {Pid, Res, true}
end;
{'DOWN', _MRef, process, Pid, Reason} ->
- {child_res(Child, Reason, Timedout), Timedout};
- {'EXIT', Pid, Reason} ->
- receive {'DOWN', _MRef, process, Pid, _} ->
- {{error, Reason}, Timedout}
- end
+ Res = child_res(Child, Reason, Timedout),
+ {Pid, Res, Timedout}
end,
{[{Pid, Reply} | Replies], Timedout1}
end, {[], false}, Pids),
timeout_stop(Child, TRef, TimeoutMsg, Timedout),
ReportError = shutdown_error_reporter(SupName),
- [case Reply of
- {_Pid, ok} -> ok;
- {Pid, {error, R}} -> ReportError(R, Child#child{pid = Pid})
- end || Reply <- Replies],
+ Report = fun(_, ok) -> ok;
+ (Pid, {error, R}) -> ReportError(R, Child#child{pid = Pid})
+ end,
+ [begin
+ receive
+ {'EXIT', Pid, Reason} ->
+ case Reply of
+ {error, noproc} -> Report(Pid, Reason);
+ _ -> Report(Pid, Reply)
+ end
+ after
+ 0 -> Report(Pid, Reply)
+ end
+ end || {Pid, Reply} <- Replies],
ok.
child_exit_reason(#child{shutdown = brutal_kill}) -> kill;