aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ranch_tcp.erl10
-rw-r--r--test/acceptor_SUITE.erl29
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,