aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--src/ejabberd_app.erl1
-rw-r--r--src/ejabberd_listener.erl57
-rw-r--r--src/ejabberd_socket.erl2
-rw-r--r--src/ejabberd_sup.erl26
5 files changed, 53 insertions, 43 deletions
diff --git a/ChangeLog b/ChangeLog
index 1938f9f14..f1a23e5cc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2008-10-12 Badlop <badlop@process-one.net>
+
+ * src/ejabberd_app.erl: Start listeners explicitely at server
+ start after everything else (EJAB-303). Implement support in
+ ejabberd for 'independent listeners', which handle their
+ connections themselves: gen_tcp:listen, etc.
+ * src/ejabberd_listener.erl: Likewise
+ * src/ejabberd_socket.erl: Likewise
+ * src/ejabberd_sup.erl: Likewise
+
2008-10-07 Christophe Romain <christophe.romain@process-one.net>
* src/mod_pubsub/mod_pubsub.erl: uncomment pubsub_publish_item hook
diff --git a/src/ejabberd_app.erl b/src/ejabberd_app.erl
index e64c58635..37d6dd7ce 100644
--- a/src/ejabberd_app.erl
+++ b/src/ejabberd_app.erl
@@ -62,6 +62,7 @@ start(normal, _Args) ->
%eprof:profile([self()]),
%fprof:trace(start, "/tmp/fprof"),
start_modules(),
+ ejabberd_listener:start_listeners(),
Sup;
start(_, _) ->
{error, badarg}.
diff --git a/src/ejabberd_listener.erl b/src/ejabberd_listener.erl
index e8bddf00e..b3753cc84 100644
--- a/src/ejabberd_listener.erl
+++ b/src/ejabberd_listener.erl
@@ -29,10 +29,11 @@
-export([start_link/0, init/1, start/3,
init/3,
+ start_listeners/0,
start_listener/3,
- stop_listener/1,
+ stop_listener/2,
add_listener/3,
- delete_listener/1
+ delete_listener/2
]).
-include("ejabberd.hrl").
@@ -42,24 +43,27 @@ start_link() ->
init(_) ->
+ {ok, {{one_for_one, 10, 1}, []}}.
+
+start_listeners() ->
case ejabberd_config:get_local_option(listen) of
undefined ->
ignore;
Ls ->
- {ok, {{one_for_one, 10, 1},
- lists:map(
- fun({Port, Module, Opts}) ->
- {Port,
- {?MODULE, start, [Port, Module, Opts]},
- transient,
- brutal_kill,
- worker,
- [?MODULE]}
- end, Ls)}}
+ lists:map(
+ fun({Port, Module, Opts}) ->
+ start_listener(Port, Module, Opts)
+ end, Ls)
end.
-
start(Port, Module, Opts) ->
+ %% Check if the module is an ejabberd listener or an independent listener
+ case Module:socket_type() of
+ independent -> Module:start_listener(Port, Opts);
+ _ -> start_dependent(Port, Module, Opts)
+ end.
+
+start_dependent(Port, Module, Opts) ->
case includes_deprecated_ssl_option(Opts) of
false ->
{ok, proc_lib:spawn_link(?MODULE, init,
@@ -130,6 +134,21 @@ accept(ListenSocket, Module, Opts) ->
end.
start_listener(Port, Module, Opts) ->
+ start_module_sup(Port, Module),
+ start_listener_sup(Port, Module, Opts).
+
+start_module_sup(_Port, Module) ->
+ Proc1 = gen_mod:get_module_proc("sup", Module),
+ ChildSpec1 =
+ {Proc1,
+ {ejabberd_tmp_sup, start_link, [Proc1, Module]},
+ permanent,
+ infinity,
+ supervisor,
+ [ejabberd_tmp_sup]},
+ catch supervisor:start_child(ejabberd_sup, ChildSpec1).
+
+start_listener_sup(Port, Module, Opts) ->
ChildSpec = {Port,
{?MODULE, start, [Port, Module, Opts]},
transient,
@@ -138,9 +157,13 @@ start_listener(Port, Module, Opts) ->
[?MODULE]},
supervisor:start_child(ejabberd_listeners, ChildSpec).
-stop_listener(Port) ->
+stop_listener(Port, Module) ->
supervisor:terminate_child(ejabberd_listeners, Port),
- supervisor:delete_child(ejabberd_listeners, Port).
+ supervisor:delete_child(ejabberd_listeners, Port),
+
+ Proc1 = gen_mod:get_module_proc("sup", Module),
+ supervisor:terminate_child(ejabberd_sup, Proc1),
+ supervisor:delete_child(ejabberd_sup, Proc1).
add_listener(Port, Module, Opts) ->
Ports = case ejabberd_config:get_local_option(listen) of
@@ -154,7 +177,7 @@ add_listener(Port, Module, Opts) ->
ejabberd_config:add_local_option(listen, Ports2),
start_listener(Port, Module, Opts).
-delete_listener(Port) ->
+delete_listener(Port, Module) ->
Ports = case ejabberd_config:get_local_option(listen) of
undefined ->
[];
@@ -163,5 +186,5 @@ delete_listener(Port) ->
end,
Ports1 = lists:keydelete(Port, 1, Ports),
ejabberd_config:add_local_option(listen, Ports1),
- stop_listener(Port).
+ stop_listener(Port, Module).
diff --git a/src/ejabberd_socket.erl b/src/ejabberd_socket.erl
index 115ffc750..ba706e4e8 100644
--- a/src/ejabberd_socket.erl
+++ b/src/ejabberd_socket.erl
@@ -77,6 +77,8 @@ start(Module, SockMod, Socket, Opts) ->
{error, _Reason} ->
SockMod:close(Socket)
end;
+ independent ->
+ ok;
raw ->
case Module:start({SockMod, Socket}, Opts) of
{ok, Pid} ->
diff --git a/src/ejabberd_sup.erl b/src/ejabberd_sup.erl
index 01efbfd76..8475e2592 100644
--- a/src/ejabberd_sup.erl
+++ b/src/ejabberd_sup.erl
@@ -99,21 +99,6 @@ init([]) ->
infinity,
supervisor,
[ejabberd_tmp_sup]},
- C2SSupervisor =
- {ejabberd_c2s_sup,
- {ejabberd_tmp_sup, start_link, [ejabberd_c2s_sup, ejabberd_c2s]},
- permanent,
- infinity,
- supervisor,
- [ejabberd_tmp_sup]},
- S2SInSupervisor =
- {ejabberd_s2s_in_sup,
- {ejabberd_tmp_sup, start_link,
- [ejabberd_s2s_in_sup, ejabberd_s2s_in]},
- permanent,
- infinity,
- supervisor,
- [ejabberd_tmp_sup]},
S2SOutSupervisor =
{ejabberd_s2s_out_sup,
{ejabberd_tmp_sup, start_link,
@@ -130,14 +115,6 @@ init([]) ->
infinity,
supervisor,
[ejabberd_tmp_sup]},
- HTTPSupervisor =
- {ejabberd_http_sup,
- {ejabberd_tmp_sup, start_link,
- [ejabberd_http_sup, ejabberd_http]},
- permanent,
- infinity,
- supervisor,
- [ejabberd_tmp_sup]},
HTTPPollSupervisor =
{ejabberd_http_poll_sup,
{ejabberd_tmp_sup, start_link,
@@ -171,11 +148,8 @@ init([]) ->
S2S,
Local,
ReceiverSupervisor,
- C2SSupervisor,
- S2SInSupervisor,
S2SOutSupervisor,
ServiceSupervisor,
- HTTPSupervisor,
HTTPPollSupervisor,
IQSupervisor,
FrontendSocketSupervisor,