aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cowboy_children.erl25
1 files changed, 20 insertions, 5 deletions
diff --git a/src/cowboy_children.erl b/src/cowboy_children.erl
index 28fcce4..1927a5a 100644
--- a/src/cowboy_children.erl
+++ b/src/cowboy_children.erl
@@ -99,9 +99,16 @@ shutdown_timeout(Children, Ref, Pid) ->
-spec terminate(children()) -> ok.
terminate(Children) ->
- %% Ask all children to shutdown first.
- _ = [exit(Pid, shutdown) || #child{pid=Pid} <- Children],
- %% Loop until that time or until all children are dead.
+ %% For each child, either ask for it to shut down,
+ %% or cancel its shutdown timer if it already is.
+ %%
+ %% We do not need to flush stray timeout messages out because
+ %% we are either terminating or switching protocols,
+ %% and in the latter case we flush all messages.
+ _ = [case TRef of
+ undefined -> exit(Pid, shutdown);
+ _ -> erlang:cancel_timer(TRef, [{async, true}, {info, false}])
+ end || #child{pid=Pid, timer=TRef} <- Children],
before_terminate_loop(Children).
before_terminate_loop([]) ->
@@ -115,10 +122,18 @@ before_terminate_loop(Children) ->
infinity -> undefined;
_ -> erlang:start_timer(Time, self(), terminate)
end,
+ %% Loop until that time or until all children are dead.
terminate_loop(Children, TRef).
-terminate_loop([], _) ->
- ok;
+terminate_loop([], TRef) ->
+ %% Don't forget to cancel the timer, if any!
+ case TRef of
+ undefined ->
+ ok;
+ _ ->
+ _ = erlang:cancel_timer(TRef, [{async, true}, {info, false}]),
+ ok
+ end;
terminate_loop(Children, TRef) ->
receive
{'EXIT', Pid, _} when TRef =:= undefined ->