diff options
-rw-r--r-- | src/ranch_tcp.erl | 10 | ||||
-rw-r--r-- | test/acceptor_SUITE.erl | 29 |
2 files changed, 38 insertions, 1 deletions
diff --git a/src/ranch_tcp.erl b/src/ranch_tcp.erl index bb7ad55..b54ae70 100644 --- a/src/ranch_tcp.erl +++ b/src/ranch_tcp.erl @@ -114,7 +114,15 @@ send(Socket, Packet) -> -spec sendfile(inet:socket(), file:name()) -> {ok, non_neg_integer()} | {error, atom()}. sendfile(Socket, Filename) -> - file:sendfile(Filename, Socket). + try file:sendfile(Filename, Socket) of + Result -> Result + catch + error:{badmatch, {error, enotconn}} -> + %% file:sendfile/2 might fail by throwing a {badmatch, {error, enotconn}} + %% this is because its internal implementation fails with a badmatch in + %% prim_file:sendfile/10 if the socket is not connected. + {error, closed} + end. %% @doc Set options on the given socket. %% @see inet:setopts/2 diff --git a/test/acceptor_SUITE.erl b/test/acceptor_SUITE.erl index e784428..ca8c856 100644 --- a/test/acceptor_SUITE.erl +++ b/test/acceptor_SUITE.erl @@ -41,6 +41,7 @@ -export([tcp_max_connections_and_beyond/1]). -export([tcp_set_max_connections/1]). -export([tcp_infinity_max_connections/1]). +-export([tcp_clean_set_max_connections/1]). -export([tcp_upgrade/1]). %% supervisor. @@ -63,6 +64,7 @@ groups() -> tcp_infinity_max_connections, tcp_max_connections_and_beyond, tcp_set_max_connections, + tcp_clean_set_max_connections, tcp_upgrade ]}, {ssl, [ ssl_accept_error, @@ -323,6 +325,33 @@ tcp_infinity_max_connections(_) -> 10 = receive_loop(connected, 1000), ranch:stop_listener(Name). +tcp_clean_set_max_connections(_) -> + %% This is a regression test to check that setting max connections does not + %% cause any processes to crash. + Name = tcp_clean_set_max_connections, + {ok, ListSupPid} = ranch:start_listener(Name, 4, ranch_tcp, + [{port, 0}, {max_connections, 4}], + notify_and_wait_protocol, [{msg, connected}, {pid, self()}]), + Children = supervisor:which_children(ListSupPid), + {_, AccSupPid, _, _} = lists:keyfind(ranch_acceptors_sup, 1, Children), + 1 = erlang:trace(ListSupPid, true, [procs]), + 1 = erlang:trace(AccSupPid, true, [procs]), + Port = ranch:get_port(tcp_clean_set_max_connections), + N = 20, + ok = connect_loop(Port, N*5, 0), + %% Randomly set max connections. + [spawn(ranch, set_max_connections, [tcp_clean_set_max_connections, Max]) || + Max <- lists:flatten(lists:duplicate(N, [6, 4, 8, infinity]))], + receive + {trace, _, spawn, _, _} -> + error(dirty_set_max_connections) + after + 2000 -> ok + end, + _ = erlang:trace(all, false, [all]), + ok = clean_traces(), + ranch:stop_listener(Name). + tcp_upgrade(_) -> Name = tcp_upgrade, {ok, _} = ranch:start_listener(Name, 1, |