From daef32d907aa559819feafddf35d2aabf63bd58d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Mon, 21 Aug 2017 14:40:01 +0200 Subject: Properly clean up timers when terminating --- src/cowboy_children.erl | 25 ++++++++++++++++++++----- 1 file 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 -> -- cgit v1.2.3