Browse Source

Add cowboy:accept_ack/1 for a cleaner handling of the shoot message

Loïc Hoguin 13 years ago
parent
commit
e550ba7cd3
5 changed files with 19 additions and 9 deletions
  1. 4 3
      README.md
  2. 10 1
      src/cowboy.erl
  3. 1 1
      src/cowboy_acceptor.erl
  4. 1 1
      src/cowboy_http_protocol.erl
  5. 3 3
      src/cowboy_protocol.erl

+ 4 - 3
README.md

@@ -244,9 +244,10 @@ is the pid to the listener's gen_server, managing the connections. Socket is of
 course the client socket; Transport is the module name of the chosen transport
 course the client socket; Transport is the module name of the chosen transport
 handler and Opts is protocol options defined when starting the listener.
 handler and Opts is protocol options defined when starting the listener.
 
 
-After initializing your protocol, it is recommended to wait to receive a message
-containing the atom 'shoot', as it will ensure Cowboy has been able to fully
-initialize the socket. Anything you do past this point is up to you!
+After initializing your protocol, it is recommended to call the
+function cowboy:accept_ack/1 with the ListenerPid as argument,
+as it will ensure Cowboy has been able to fully initialize the socket.
+Anything you do past this point is up to you!
 
 
 If you need to change some socket options, like enabling raw mode for example,
 If you need to change some socket options, like enabling raw mode for example,
 you can call the <em>Transport:setopts/2</em> function. It is the protocol's
 you can call the <em>Transport:setopts/2</em> function. It is the protocol's

+ 10 - 1
src/cowboy.erl

@@ -15,7 +15,7 @@
 %% @doc Cowboy API to start and stop listeners.
 %% @doc Cowboy API to start and stop listeners.
 -module(cowboy).
 -module(cowboy).
 
 
--export([start_listener/6, stop_listener/1, child_spec/6]).
+-export([start_listener/6, stop_listener/1, child_spec/6, accept_ack/1]).
 
 
 %% @doc Start a listener for the given transport and protocol.
 %% @doc Start a listener for the given transport and protocol.
 %%
 %%
@@ -61,6 +61,7 @@ stop_listener(Ref) ->
 	end.
 	end.
 
 
 %% @doc Return a child spec suitable for embedding.
 %% @doc Return a child spec suitable for embedding.
+%%
 %% When you want to embed cowboy in another application, you can use this
 %% When you want to embed cowboy in another application, you can use this
 %% function to create a <em>ChildSpec</em> suitable for use in a supervisor.
 %% function to create a <em>ChildSpec</em> suitable for use in a supervisor.
 %% The parameters are the same as in <em>start_listener/6</em> but rather
 %% The parameters are the same as in <em>start_listener/6</em> but rather
@@ -74,3 +75,11 @@ child_spec(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts)
 	{{cowboy_listener_sup, Ref}, {cowboy_listener_sup, start_link, [
 	{{cowboy_listener_sup, Ref}, {cowboy_listener_sup, start_link, [
 		NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts
 		NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts
 	]}, permanent, 5000, supervisor, [cowboy_listener_sup]}.
 	]}, permanent, 5000, supervisor, [cowboy_listener_sup]}.
+
+%% @doc Acknowledge the accepted connection.
+%%
+%% Effectively used to make sure the socket control has been given to
+%% the protocol process before starting to use it.
+-spec accept_ack(pid()) -> ok.
+accept_ack(ListenerPid) ->
+	receive {shoot, ListenerPid} -> ok end.

+ 1 - 1
src/cowboy_acceptor.erl

@@ -40,7 +40,7 @@ acceptor(LSocket, Transport, Protocol, Opts, MaxConns, ListenerPid, ReqsSup) ->
 			Transport:controlling_process(CSocket, Pid),
 			Transport:controlling_process(CSocket, Pid),
 			{ok, NbConns} = cowboy_listener:add_connection(ListenerPid,
 			{ok, NbConns} = cowboy_listener:add_connection(ListenerPid,
 				default, Pid),
 				default, Pid),
-			Pid ! shoot,
+			Pid ! {shoot, ListenerPid},
 			limit_reqs(ListenerPid, NbConns, MaxConns);
 			limit_reqs(ListenerPid, NbConns, MaxConns);
 		{error, timeout} ->
 		{error, timeout} ->
 			ignore;
 			ignore;

+ 1 - 1
src/cowboy_http_protocol.erl

@@ -77,7 +77,7 @@ init(ListenerPid, Socket, Transport, Opts) ->
 	Timeout = proplists:get_value(timeout, Opts, 5000),
 	Timeout = proplists:get_value(timeout, Opts, 5000),
 	URLDecDefault = {fun cowboy_http:urldecode/2, crash},
 	URLDecDefault = {fun cowboy_http:urldecode/2, crash},
 	URLDec = proplists:get_value(urldecode, Opts, URLDecDefault),
 	URLDec = proplists:get_value(urldecode, Opts, URLDecDefault),
-	receive shoot -> ok end,
+	ok = cowboy:accept_ack(ListenerPid),
 	wait_request(#state{listener=ListenerPid, socket=Socket, transport=Transport,
 	wait_request(#state{listener=ListenerPid, socket=Socket, transport=Transport,
 		dispatch=Dispatch, max_empty_lines=MaxEmptyLines,
 		dispatch=Dispatch, max_empty_lines=MaxEmptyLines,
 		max_line_length=MaxLineLength, timeout=Timeout, urldecode=URLDec}).
 		max_line_length=MaxLineLength, timeout=Timeout, urldecode=URLDec}).

+ 3 - 3
src/cowboy_protocol.erl

@@ -24,9 +24,9 @@
 %% starting the listener. The <em>start_link/4</em> function must follow
 %% starting the listener. The <em>start_link/4</em> function must follow
 %% the supervisor start function specification.
 %% the supervisor start function specification.
 %%
 %%
-%% After initializing your protocol, it is recommended to wait to
-%% receive a message containing the atom 'shoot', as it will ensure
-%% Cowboy has been able to fully initialize the socket.
+%% After initializing your protocol, it is recommended to call the
+%% function cowboy:accept_ack/1 with the ListenerPid as argument,
+%% as it will ensure Cowboy has been able to fully initialize the socket.
 %% Anything you do past this point is up to you!
 %% Anything you do past this point is up to you!
 %%
 %%
 %% If you need to change some socket options, like enabling raw mode
 %% If you need to change some socket options, like enabling raw mode