1*eeb7e5b3SAdam Hornáček%% Copyright (c) 2011-2017, Loïc Hoguin <essen@ninenines.eu> 2*eeb7e5b3SAdam Hornáček%% 3*eeb7e5b3SAdam Hornáček%% Permission to use, copy, modify, and/or distribute this software for any 4*eeb7e5b3SAdam Hornáček%% purpose with or without fee is hereby granted, provided that the above 5*eeb7e5b3SAdam Hornáček%% copyright notice and this permission notice appear in all copies. 6*eeb7e5b3SAdam Hornáček%% 7*eeb7e5b3SAdam Hornáček%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8*eeb7e5b3SAdam Hornáček%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9*eeb7e5b3SAdam Hornáček%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10*eeb7e5b3SAdam Hornáček%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11*eeb7e5b3SAdam Hornáček%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12*eeb7e5b3SAdam Hornáček%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13*eeb7e5b3SAdam Hornáček%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14*eeb7e5b3SAdam Hornáček 15*eeb7e5b3SAdam Hornáček-module(ranch_acceptor). 16*eeb7e5b3SAdam Hornáček 17*eeb7e5b3SAdam Hornáček-export([start_link/3]). 18*eeb7e5b3SAdam Hornáček-export([loop/3]). 19*eeb7e5b3SAdam Hornáček 20*eeb7e5b3SAdam Hornáček-spec start_link(inet:socket(), module(), pid()) 21*eeb7e5b3SAdam Hornáček -> {ok, pid()}. 22*eeb7e5b3SAdam Hornáčekstart_link(LSocket, Transport, ConnsSup) -> 23*eeb7e5b3SAdam Hornáček Pid = spawn_link(?MODULE, loop, [LSocket, Transport, ConnsSup]), 24*eeb7e5b3SAdam Hornáček {ok, Pid}. 25*eeb7e5b3SAdam Hornáček 26*eeb7e5b3SAdam Hornáček-spec loop(inet:socket(), module(), pid()) -> no_return(). 27*eeb7e5b3SAdam Hornáčekloop(LSocket, Transport, ConnsSup) -> 28*eeb7e5b3SAdam Hornáček _ = case Transport:accept(LSocket, infinity) of 29*eeb7e5b3SAdam Hornáček {ok, CSocket} -> 30*eeb7e5b3SAdam Hornáček case Transport:controlling_process(CSocket, ConnsSup) of 31*eeb7e5b3SAdam Hornáček ok -> 32*eeb7e5b3SAdam Hornáček %% This call will not return until process has been started 33*eeb7e5b3SAdam Hornáček %% AND we are below the maximum number of connections. 34*eeb7e5b3SAdam Hornáček ranch_conns_sup:start_protocol(ConnsSup, CSocket); 35*eeb7e5b3SAdam Hornáček {error, _} -> 36*eeb7e5b3SAdam Hornáček Transport:close(CSocket) 37*eeb7e5b3SAdam Hornáček end; 38*eeb7e5b3SAdam Hornáček %% Reduce the accept rate if we run out of file descriptors. 39*eeb7e5b3SAdam Hornáček %% We can't accept anymore anyway, so we might as well wait 40*eeb7e5b3SAdam Hornáček %% a little for the situation to resolve itself. 41*eeb7e5b3SAdam Hornáček {error, emfile} -> 42*eeb7e5b3SAdam Hornáček error_logger:warning_msg("Ranch acceptor reducing accept rate: out of file descriptors~n"), 43*eeb7e5b3SAdam Hornáček receive after 0xFF -> ok end; 44*eeb7e5b3SAdam Hornáček %% We want to crash if the listening socket got closed. 45*eeb7e5b3SAdam Hornáček {error, Reason} when Reason =/= closed -> 46*eeb7e5b3SAdam Hornáček ok 47*eeb7e5b3SAdam Hornáček end, 48*eeb7e5b3SAdam Hornáček flush(), 49*eeb7e5b3SAdam Hornáček ?MODULE:loop(LSocket, Transport, ConnsSup). 50*eeb7e5b3SAdam Hornáček 51*eeb7e5b3SAdam Hornáčekflush() -> 52*eeb7e5b3SAdam Hornáček receive Msg -> 53*eeb7e5b3SAdam Hornáček error_logger:error_msg( 54*eeb7e5b3SAdam Hornáček "Ranch acceptor received unexpected message: ~p~n", 55*eeb7e5b3SAdam Hornáček [Msg]), 56*eeb7e5b3SAdam Hornáček flush() 57*eeb7e5b3SAdam Hornáček after 0 -> 58*eeb7e5b3SAdam Hornáček ok 59*eeb7e5b3SAdam Hornáček end. 60*eeb7e5b3SAdam Hornáček'http://example.com?a=' 61*eeb7e5b3SAdam Hornáček-include("incdir/more_records.hrl"). 62