diff options
author | Loïc Hoguin <[email protected]> | 2017-08-21 14:40:01 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2017-08-21 14:40:01 +0200 |
commit | daef32d907aa559819feafddf35d2aabf63bd58d (patch) | |
tree | 126378bd4cad316b5070de4143f23346e7134906 | |
parent | a2facaf2da2c95df32ffdc529bd3bdd9f91c080c (diff) | |
download | cowboy-daef32d907aa559819feafddf35d2aabf63bd58d.tar.gz cowboy-daef32d907aa559819feafddf35d2aabf63bd58d.tar.bz2 cowboy-daef32d907aa559819feafddf35d2aabf63bd58d.zip |
Properly clean up timers when terminating
-rw-r--r-- | src/cowboy_children.erl | 25 |
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 -> |