Browse Source

Merge branch 'fix-server-racecon' of git://github.com/fishcakez/ranch

Loïc Hoguin 12 years ago
parent
commit
18b546fb02
2 changed files with 33 additions and 6 deletions
  1. 10 5
      src/ranch_server.erl
  2. 23 1
      test/acceptor_SUITE.erl

+ 10 - 5
src/ranch_server.erl

@@ -68,7 +68,8 @@ cleanup_listener_opts(Ref) ->
 %% @doc Set a connection supervisor associated with specific listener.
 %% @doc Set a connection supervisor associated with specific listener.
 -spec set_connections_sup(any(), pid()) -> ok.
 -spec set_connections_sup(any(), pid()) -> ok.
 set_connections_sup(Ref, Pid) ->
 set_connections_sup(Ref, Pid) ->
-	gen_server:call(?MODULE, {set_connections_sup, Ref, Pid}).
+	true = gen_server:call(?MODULE, {set_connections_sup, Ref, Pid}),
+	ok.
 
 
 %% @doc Return the connection supervisor used by specific listener.
 %% @doc Return the connection supervisor used by specific listener.
 -spec get_connections_sup(any()) -> pid().
 -spec get_connections_sup(any()) -> pid().
@@ -125,10 +126,14 @@ handle_call({set_new_listener_opts, Ref, MaxConns, Opts}, _, State) ->
 	{reply, ok, State};
 	{reply, ok, State};
 handle_call({set_connections_sup, Ref, Pid}, _,
 handle_call({set_connections_sup, Ref, Pid}, _,
 		State=#state{monitors=Monitors}) ->
 		State=#state{monitors=Monitors}) ->
-	true = ets:insert_new(?TAB, {{conns_sup, Ref}, Pid}),
-	MonitorRef = erlang:monitor(process, Pid),
-	{reply, ok, State#state{
-		monitors=[{{MonitorRef, Pid}, Ref}|Monitors]}};
+	case ets:insert_new(?TAB, {{conns_sup, Ref}, Pid}) of
+		true ->
+			MonitorRef = erlang:monitor(process, Pid),
+			{reply, true,
+				State#state{monitors=[{{MonitorRef, Pid}, Ref}|Monitors]}};
+		false ->
+			{reply, false, State}
+	end;
 handle_call({set_port, Ref, Port}, _, State) ->
 handle_call({set_port, Ref, Port}, _, State) ->
 	true = ets:insert(?TAB, {{port, Ref}, Port}),
 	true = ets:insert(?TAB, {{port, Ref}, Port}),
 	{reply, ok, State};
 	{reply, ok, State};

+ 23 - 1
test/acceptor_SUITE.erl

@@ -49,6 +49,7 @@
 -export([supervisor_clean_child_restart/1]).
 -export([supervisor_clean_child_restart/1]).
 -export([supervisor_conns_alive/1]).
 -export([supervisor_conns_alive/1]).
 -export([supervisor_server_recover_state/1]).
 -export([supervisor_server_recover_state/1]).
+-export([supervisor_clean_conns_sup_restart/1]).
 
 
 %% ct.
 %% ct.
 
 
@@ -77,7 +78,8 @@ groups() ->
 		supervisor_clean_restart,
 		supervisor_clean_restart,
 		supervisor_clean_child_restart,
 		supervisor_clean_child_restart,
 		supervisor_conns_alive,
 		supervisor_conns_alive,
-		supervisor_server_recover_state
+		supervisor_server_recover_state,
+		supervisor_clean_conns_sup_restart
 	]}].
 	]}].
 
 
 init_per_suite(Config) ->
 init_per_suite(Config) ->
@@ -499,6 +501,26 @@ supervisor_server_recover_state(_) ->
 	_ = erlang:trace(all, false, [all]),
 	_ = erlang:trace(all, false, [all]),
 	ok = clean_traces().
 	ok = clean_traces().
 
 
+supervisor_clean_conns_sup_restart(_) ->
+	%% Verify that a conns_sup can not register with the same Name as an already
+	%% registered conns_sup that is still alive. Make sure this does not crash
+	%% the ranch_server.
+	Name = supervisor_clean_conns_sup_restart,
+	{ok, _} = ranch:start_listener(Name,
+		1, ranch_tcp, [{port, 0}], echo_protocol, []),
+	Server = erlang:whereis(ranch_server),
+	ServerMonRef = erlang:monitor(process, Server),
+	%% Exit because Name already registered and is alive.
+	{'EXIT', _}  = (catch ranch_server:set_connections_sup(Name, self())),
+	receive
+		{'DOWN', ServerMonRef, process, Server, _} ->
+			error(ranch_server_down)
+	after
+		1000 ->
+			ok
+	end,
+	ranch:stop_listener(Name).
+
 %% Utility functions.
 %% Utility functions.
 
 
 connect_loop(_, 0, _) ->
 connect_loop(_, 0, _) ->