0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-14 04:10:24 +00:00

Use active,N for the linger loop as well

This commit is contained in:
Loïc Hoguin 2019-12-04 11:33:57 +01:00
parent cd7870df15
commit 8241791a3e
No known key found for this signature in database
GPG key ID: 8A9DF795F6FED764

View file

@ -1432,38 +1432,41 @@ terminate_linger(State=#state{socket=Socket, transport=Transport, opts=Opts}) ->
0 ->
ok;
infinity ->
terminate_linger_loop(State, undefined);
terminate_linger_before_loop(State, undefined, Transport:messages());
Timeout ->
TimerRef = erlang:start_timer(Timeout, self(), linger_timeout),
terminate_linger_loop(State, TimerRef)
terminate_linger_before_loop(State, TimerRef, Transport:messages())
end;
{error, _} ->
ok
end.
terminate_linger_loop(State=#state{socket=Socket, transport=Transport}, TimerRef) ->
Messages = Transport:messages(),
terminate_linger_before_loop(State=#state{socket=Socket, transport=Transport}, TimerRef, Messages) ->
%% We may already have a message in the mailbox when we do this
%% but it's OK because we are shutting down anyway.
%% @todo Use active,N here as well.
case Transport:setopts(Socket, [{active, once}]) of
case Transport:setopts(Socket, [{active, 100}]) of
ok ->
receive
{OK, Socket, _} when OK =:= element(1, Messages) ->
terminate_linger_loop(State, TimerRef);
{Closed, Socket} when Closed =:= element(2, Messages) ->
ok;
{Error, Socket, _} when Error =:= element(3, Messages) ->
ok;
{timeout, TimerRef, linger_timeout} ->
ok;
_ ->
terminate_linger_loop(State, TimerRef)
end;
terminate_linger_loop(State, TimerRef, Messages);
{error, _} ->
ok
end.
terminate_linger_loop(State=#state{socket=Socket}, TimerRef, Messages) ->
receive
{OK, Socket, _} when OK =:= element(1, Messages) ->
terminate_linger_loop(State, TimerRef, Messages);
{Closed, Socket} when Closed =:= element(2, Messages) ->
ok;
{Error, Socket, _} when Error =:= element(3, Messages) ->
ok;
{Passive, Socket} when Passive =:= tcp_passive; Passive =:= ssl_passive ->
terminate_linger_before_loop(State, TimerRef, Messages);
{timeout, TimerRef, linger_timeout} ->
ok;
_ ->
terminate_linger_loop(State, TimerRef, Messages)
end.
%% System callbacks.
-spec system_continue(_, _, #state{}) -> ok.