]> granicus.if.org Git - ejabberd/commitdiff
Improve modules start/stop procedures
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Tue, 14 Feb 2017 07:25:08 +0000 (10:25 +0300)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Tue, 14 Feb 2017 07:25:08 +0000 (10:25 +0300)
24 files changed:
src/ejabberd_local.erl
src/ejabberd_s2s_out.erl
src/ejabberd_sm.erl
src/mod_announce.erl
src/mod_caps.erl
src/mod_delegation.erl
src/mod_echo.erl
src/mod_fail2ban.erl
src/mod_http_fileserver.erl
src/mod_irc.erl
src/mod_last.erl
src/mod_mix.erl
src/mod_muc.erl
src/mod_muc_log.erl
src/mod_multicast.erl
src/mod_offline.erl
src/mod_ping.erl
src/mod_privilege.erl
src/mod_proxy65_service.erl
src/mod_pubsub.erl
src/mod_shared_roster_ldap.erl
src/mod_sip_registrar.erl
src/mod_vcard.erl
src/mod_vcard_ldap.erl

index f80d9724946984adefa7d63539fef010154082ec..bd9a1b2e4993f444780848751c9a751c2867fc6b 100644 (file)
@@ -152,7 +152,7 @@ register_iq_response_handler(_Host, ID, Module,
                undefined -> ?IQ_TIMEOUT;
                N when is_integer(N), N > 0 -> N
              end,
-    TRef = erlang:start_timer(Timeout, ejabberd_local, ID),
+    TRef = erlang:start_timer(Timeout, ?MODULE, ID),
     mnesia:dirty_write(#iq_response{id = ID,
                                    module = Module,
                                    function = Function,
@@ -161,9 +161,8 @@ register_iq_response_handler(_Host, ID, Module,
 -spec register_iq_handler(binary(), binary(), module(), function(),
                          gen_iq_handler:opts()) -> ok.
 register_iq_handler(Host, XMLNS, Module, Fun, Opts) ->
-    ejabberd_local !
-       {register_iq_handler, Host, XMLNS, Module, Fun, Opts},
-    ok.
+    gen_server:cast(?MODULE,
+                   {register_iq_handler, Host, XMLNS, Module, Fun, Opts}).
 
 -spec unregister_iq_response_handler(binary(), binary()) -> ok.
 unregister_iq_response_handler(_Host, ID) ->
@@ -171,8 +170,7 @@ unregister_iq_response_handler(_Host, ID) ->
 
 -spec unregister_iq_handler(binary(), binary()) -> ok.
 unregister_iq_handler(Host, XMLNS) ->
-    ejabberd_local ! {unregister_iq_handler, Host, XMLNS},
-    ok.
+    gen_server:cast(?MODULE, {unregister_iq_handler, Host, XMLNS}).
 
 -spec bounce_resource_packet(jid(), jid(), stanza()) -> stop.
 bounce_resource_packet(_From, #jid{lresource = <<"">>}, #presence{}) ->
@@ -222,23 +220,13 @@ init([]) ->
 handle_call(_Request, _From, State) ->
     Reply = ok, {reply, Reply, State}.
 
-handle_cast(_Msg, State) -> {noreply, State}.
-
-handle_info({route, From, To, Packet}, State) ->
-    case catch do_route(From, To, Packet) of
-      {'EXIT', Reason} ->
-         ?ERROR_MSG("~p~nwhen processing: ~p",
-                    [Reason, {From, To, Packet}]);
-      _ -> ok
-    end,
-    {noreply, State};
-handle_info({register_iq_handler, Host, XMLNS, Module,
+handle_cast({register_iq_handler, Host, XMLNS, Module,
             Function, Opts},
            State) ->
     ets:insert(?IQTABLE,
               {{Host, XMLNS}, Module, Function, Opts}),
     {noreply, State};
-handle_info({unregister_iq_handler, Host, XMLNS},
+handle_cast({unregister_iq_handler, Host, XMLNS},
            State) ->
     case ets:lookup(?IQTABLE, {Host, XMLNS}) of
       [{_, Module, Function, Opts}] ->
@@ -247,10 +235,21 @@ handle_info({unregister_iq_handler, Host, XMLNS},
     end,
     ets:delete(?IQTABLE, {Host, XMLNS}),
     {noreply, State};
+handle_cast(_Msg, State) -> {noreply, State}.
+
+handle_info({route, From, To, Packet}, State) ->
+    case catch do_route(From, To, Packet) of
+      {'EXIT', Reason} ->
+         ?ERROR_MSG("~p~nwhen processing: ~p",
+                    [Reason, {From, To, Packet}]);
+      _ -> ok
+    end,
+    {noreply, State};
 handle_info({timeout, _TRef, ID}, State) ->
     process_iq_timeout(ID),
     {noreply, State};
-handle_info(_Info, State) ->
+handle_info(Info, State) ->
+    ?WARNING_MSG("unexpected info: ~p", [Info]),
     {noreply, State}.
 
 terminate(_Reason, _State) ->
index a923860f39d93bfb0fe9a7615bb06b5330831ac5..7a85cb48a609fca0b9038481ba88b03412f68033 100644 (file)
@@ -153,7 +153,7 @@ process_downgraded(State, _StreamStart) ->
     send(State, xmpp:serr_unsupported_version()).
 
 %%%===================================================================
-%%% gen_server callbacks
+%%% xmpp_stream_out callbacks
 %%%===================================================================
 tls_options(#{server := LServer}) ->
     ejabberd_s2s:tls_options(LServer, []).
index 62f250d5735d07bd7e2444db0394c124e0d27ac6..12bfb4e1064cfc1c20990b6333469a20d8bc51ae 100644 (file)
@@ -358,14 +358,13 @@ get_vh_session_number(Server) ->
 -spec register_iq_handler(binary(), binary(), atom(), atom(), list()) -> ok.
 
 register_iq_handler(Host, XMLNS, Module, Fun, Opts) ->
-    ejabberd_sm ! {register_iq_handler, Host, XMLNS, Module, Fun, Opts},
-    ok.
+    gen_server:cast(?MODULE,
+                   {register_iq_handler, Host, XMLNS, Module, Fun, Opts}).
 
 -spec unregister_iq_handler(binary(), binary()) -> ok.
 
 unregister_iq_handler(Host, XMLNS) ->
-    ejabberd_sm ! {unregister_iq_handler, Host, XMLNS},
-    ok.
+    gen_server:cast(?MODULE, {unregister_iq_handler, Host, XMLNS}).
 
 %% Why the hell do we have so many similar kicks?
 c2s_handle_info(#{lang := Lang} = State, replaced) ->
@@ -408,24 +407,13 @@ init([]) ->
 handle_call(_Request, _From, State) ->
     Reply = ok, {reply, Reply, State}.
 
-handle_cast(_Msg, State) -> {noreply, State}.
-
-handle_info({route, From, To, Packet}, State) ->
-    case catch do_route(From, To, Packet) of
-       {'EXIT', Reason} ->
-           ?ERROR_MSG("~p~nwhen processing: ~p",
-                      [Reason, {From, To, Packet}]);
-       _ ->
-           ok
-    end,
-    {noreply, State};
-handle_info({register_iq_handler, Host, XMLNS, Module,
+handle_cast({register_iq_handler, Host, XMLNS, Module,
             Function, Opts},
            State) ->
     ets:insert(sm_iqtable,
               {{Host, XMLNS}, Module, Function, Opts}),
     {noreply, State};
-handle_info({unregister_iq_handler, Host, XMLNS},
+handle_cast({unregister_iq_handler, Host, XMLNS},
            State) ->
     case ets:lookup(sm_iqtable, {Host, XMLNS}) of
       [{_, Module, Function, Opts}] ->
@@ -434,7 +422,20 @@ handle_info({unregister_iq_handler, Host, XMLNS},
     end,
     ets:delete(sm_iqtable, {Host, XMLNS}),
     {noreply, State};
-handle_info(_Info, State) -> {noreply, State}.
+handle_cast(_Msg, State) -> {noreply, State}.
+
+handle_info({route, From, To, Packet}, State) ->
+    case catch do_route(From, To, Packet) of
+       {'EXIT', Reason} ->
+           ?ERROR_MSG("~p~nwhen processing: ~p",
+                      [Reason, {From, To, Packet}]);
+       _ ->
+           ok
+    end,
+    {noreply, State};
+handle_info(Info, State) ->
+    ?WARNING_MSG("unexpected info: ~p", [Info]),
+    {noreply, State}.
 
 terminate(_Reason, _State) ->
     lists:foreach(
index e8c71f31d5155bcb0da98a97ad1622b0dacd4d05..e22a4222338f651f87462e5ab87ea86fa92a76c9 100644 (file)
 -module(mod_announce).
 -author('alexey@process-one.net').
 
+-behaviour(gen_server).
 -behaviour(gen_mod).
 
--export([start/2, init/0, stop/1, export/1, import_info/0,
+-export([start/2, stop/1, export/1, import_info/0,
         import_start/2, import/5, announce/3, send_motd/1, disco_identity/5,
         disco_features/5, disco_items/5, depends/2,
         send_announcement_to_all/3, announce_commands/4,
         announce_items/4, mod_opt_type/1]).
+-export([start_link/2, init/1, handle_call/3, handle_cast/2,
+        handle_info/2, terminate/2, code_change/3]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -51,6 +54,8 @@
 -callback is_motd_user(binary(), binary()) -> boolean().
 -callback set_motd_user(binary(), binary()) -> {atomic, any()}.
 
+-record(state, {host :: binary()}).
+
 -define(PROCNAME, ejabberd_announce).
 
 -define(NS_ADMINL(Sub), [<<"http:">>, <<"jabber.org">>, <<"protocol">>,
 
 tokenize(Node) -> str:tokens(Node, <<"/#">>).
 
+%%====================================================================
+%% API
+%%====================================================================
+start_link(Host, Opts) ->
+    Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
+    gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []).
+
+%%====================================================================
+%% gen_mod callbacks
+%%====================================================================
 start(Host, Opts) ->
+    Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
+    Spec = {Proc, {?MODULE, start_link, [Host, Opts]},
+           transient, 2000, worker, [?MODULE]},
+    supervisor:start_child(ejabberd_sup, Spec).
+
+stop(Host) ->
+    Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
+    supervisor:terminate_child(ejabberd_sup, Proc),
+    supervisor:delete_child(ejabberd_sup, Proc),
+    ok.
+
+depends(_Host, _Opts) ->
+    [{mod_adhoc, hard}].
+
+%%====================================================================
+%% gen_server callbacks
+%%====================================================================
+init([Host, Opts]) ->
+    process_flag(trap_exit, true),
     Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
     Mod:init(Host, Opts),
     ejabberd_hooks:add(local_send_to_resource_hook, Host,
@@ -70,65 +104,53 @@ start(Host, Opts) ->
     ejabberd_hooks:add(adhoc_local_commands, Host, ?MODULE, announce_commands, 50),
     ejabberd_hooks:add(c2s_self_presence, Host,
                       ?MODULE, send_motd, 50),
-    Pid = proc_lib:spawn(?MODULE, init, []),
-    register(gen_mod:get_module_proc(Host, ?PROCNAME), Pid),
-    {ok, Pid}.
+    {ok, #state{host = Host}}.
 
-depends(_Host, _Opts) ->
-    [{mod_adhoc, hard}].
+handle_call(_Call, _From, State) ->
+    {noreply, State}.
 
-init() ->
-    loop().
-
-loop() ->
-    receive
+handle_cast(Msg, State) ->
+    case Msg of
        {announce_all, From, To, Packet} ->
-           announce_all(From, To, Packet),
-           loop();
+           announce_all(From, To, Packet);
        {announce_all_hosts_all, From, To, Packet} ->
-           announce_all_hosts_all(From, To, Packet),
-           loop();
+           announce_all_hosts_all(From, To, Packet);
        {announce_online, From, To, Packet} ->
-           announce_online(From, To, Packet),
-           loop();
+           announce_online(From, To, Packet);
        {announce_all_hosts_online, From, To, Packet} ->
-           announce_all_hosts_online(From, To, Packet),
-           loop();
+           announce_all_hosts_online(From, To, Packet);
        {announce_motd, From, To, Packet} ->
-           announce_motd(From, To, Packet),
-           loop();
+           announce_motd(From, To, Packet);
        {announce_all_hosts_motd, From, To, Packet} ->
-           announce_all_hosts_motd(From, To, Packet),
-           loop();
+           announce_all_hosts_motd(From, To, Packet);
        {announce_motd_update, From, To, Packet} ->
-           announce_motd_update(From, To, Packet),
-           loop();
+           announce_motd_update(From, To, Packet);
        {announce_all_hosts_motd_update, From, To, Packet} ->
-           announce_all_hosts_motd_update(From, To, Packet),
-           loop();
+           announce_all_hosts_motd_update(From, To, Packet);
        {announce_motd_delete, From, To, Packet} ->
-           announce_motd_delete(From, To, Packet),
-           loop();
+           announce_motd_delete(From, To, Packet);
        {announce_all_hosts_motd_delete, From, To, Packet} ->
-           announce_all_hosts_motd_delete(From, To, Packet),
-           loop();
+           announce_all_hosts_motd_delete(From, To, Packet);
        _ ->
-           loop()
-    end.
+           ?WARNING_MSG("unexpected cast: ~p", [Msg])
+    end,
+    {noreply, State}.
 
-stop(Host) ->
+handle_info(Info, State) ->
+    ?WARNING_MSG("unexpected info: ~p", [Info]),
+    {noreply, State}.
+
+terminate(_Reason, #state{host = Host}) ->
     ejabberd_hooks:delete(adhoc_local_commands, Host, ?MODULE, announce_commands, 50),
     ejabberd_hooks:delete(adhoc_local_items, Host, ?MODULE, announce_items, 50),
     ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, disco_identity, 50),
     ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, disco_features, 50),
     ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, disco_items, 50),
-    ejabberd_hooks:delete(local_send_to_resource_hook, Host,
-                         ?MODULE, announce, 50),
-    ejabberd_hooks:delete(c2s_self_presence, Host,
-                         ?MODULE, send_motd, 50),
-    Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
-    exit(whereis(Proc), stop),
-    {wait, Proc}.
+    ejabberd_hooks:delete(local_send_to_resource_hook, Host, ?MODULE, announce, 50),
+    ejabberd_hooks:delete(c2s_self_presence, Host, ?MODULE, send_motd, 50).
+
+code_change(_OldVsn, State, _Extra) ->
+    {ok, State}.
 
 %% Announcing via messages to a custom resource
 -spec announce(jid(), jid(), stanza()) -> ok | stop.
@@ -136,31 +158,31 @@ announce(From, #jid{luser = <<>>} = To, #message{} = Packet) ->
     Proc = gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME),
     Res = case To#jid.lresource of
              <<"announce/all">> ->
-                 Proc ! {announce_all, From, To, Packet};
+                 gen_server:cast(Proc, {announce_all, From, To, Packet});
              <<"announce/all-hosts/all">> ->
-                 Proc ! {announce_all_hosts_all, From, To, Packet};
+                 gen_server:cast(Proc, {announce_all_hosts_all, From, To, Packet});
              <<"announce/online">> ->
-                 Proc ! {announce_online, From, To, Packet};
+                 gen_server:cast(Proc, {announce_online, From, To, Packet});
              <<"announce/all-hosts/online">> ->
-                 Proc ! {announce_all_hosts_online, From, To, Packet};
+                 gen_server:cast(Proc, {announce_all_hosts_online, From, To, Packet});
              <<"announce/motd">> ->
-                 Proc ! {announce_motd, From, To, Packet};
+                 gen_server:cast(Proc, {announce_motd, From, To, Packet});
              <<"announce/all-hosts/motd">> ->
-                 Proc ! {announce_all_hosts_motd, From, To, Packet};
+                 gen_server:cast(Proc, {announce_all_hosts_motd, From, To, Packet});
              <<"announce/motd/update">> ->
-                 Proc ! {announce_motd_update, From, To, Packet};
+                 gen_server:cast(Proc, {announce_motd_update, From, To, Packet});
              <<"announce/all-hosts/motd/update">> ->
-                 Proc ! {announce_all_hosts_motd_update, From, To, Packet};
+                 gen_server:cast(Proc, {announce_all_hosts_motd_update, From, To, Packet});
              <<"announce/motd/delete">> ->
-                 Proc ! {announce_motd_delete, From, To, Packet};
+                 gen_server:cast(Proc, {announce_motd_delete, From, To, Packet});
              <<"announce/all-hosts/motd/delete">> ->
-                 Proc ! {announce_all_hosts_motd_delete, From, To, Packet};
+                 gen_server:cast(Proc, {announce_all_hosts_motd_delete, From, To, Packet});
              _ ->
-                 ok
+                 undefined
          end,
     case Res of
-       ok -> ok;
-       _ -> stop
+       ok -> stop;
+       _ -> ok
     end;
 announce(_From, _To, _Packet) ->
     ok.
@@ -521,14 +543,14 @@ handle_adhoc_form(From, #jid{lserver = LServer} = To,
     case {Node, Body} of
        {?NS_ADMIN_DELETE_MOTD, _} ->
            if  Confirm ->
-                   Proc ! {announce_motd_delete, From, To, Packet},
+                   gen_server:cast(Proc, {announce_motd_delete, From, To, Packet}),
                    Response;
                true ->
                    Response
            end;
        {?NS_ADMIN_DELETE_MOTD_ALLHOSTS, _} ->
            if  Confirm ->
-                   Proc ! {announce_all_hosts_motd_delete, From, To, Packet},
+                   gen_server:cast(Proc, {announce_all_hosts_motd_delete, From, To, Packet}),
                    Response;
                true ->
                    Response
@@ -542,28 +564,28 @@ handle_adhoc_form(From, #jid{lserver = LServer} = To,
        %% We don't use direct announce_* functions because it
        %% leads to large delay in response and <iq/> queries processing
        {?NS_ADMIN_ANNOUNCE, _} ->
-           Proc ! {announce_online, From, To, Packet},
+           gen_server:cast(Proc, {announce_online, From, To, Packet}),
            Response;
        {?NS_ADMIN_ANNOUNCE_ALLHOSTS, _} ->         
-           Proc ! {announce_all_hosts_online, From, To, Packet},
+           gen_server:cast(Proc, {announce_all_hosts_online, From, To, Packet}),
            Response;
        {?NS_ADMIN_ANNOUNCE_ALL, _} ->
-           Proc ! {announce_all, From, To, Packet},
+           gen_server:cast(Proc, {announce_all, From, To, Packet}),
            Response;
        {?NS_ADMIN_ANNOUNCE_ALL_ALLHOSTS, _} ->     
-           Proc ! {announce_all_hosts_all, From, To, Packet},
+           gen_server:cast(Proc, {announce_all_hosts_all, From, To, Packet}),
            Response;
        {?NS_ADMIN_SET_MOTD, _} ->
-           Proc ! {announce_motd, From, To, Packet},
+           gen_server:cast(Proc, {announce_motd, From, To, Packet}),
            Response;
        {?NS_ADMIN_SET_MOTD_ALLHOSTS, _} ->         
-           Proc ! {announce_all_hosts_motd, From, To, Packet},
+           gen_server:cast(Proc, {announce_all_hosts_motd, From, To, Packet}),
            Response;
        {?NS_ADMIN_EDIT_MOTD, _} ->
-           Proc ! {announce_motd_update, From, To, Packet},
+           gen_server:cast(Proc, {announce_motd_update, From, To, Packet}),
            Response;
        {?NS_ADMIN_EDIT_MOTD_ALLHOSTS, _} ->        
-           Proc ! {announce_all_hosts_motd_update, From, To, Packet},
+           gen_server:cast(Proc, {announce_all_hosts_motd_update, From, To, Packet}),
            Response;
        Junk ->
            %% This can't happen, as we haven't registered any other
index 391a3ba74f41d56ba791375777113a163876aee9..ae79981080bd4a2cde7d02ab2e99e0707549f4da 100644 (file)
@@ -82,7 +82,6 @@ start(Host, Opts) ->
 
 stop(Host) ->
     Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
-    gen_server:call(Proc, stop),
     supervisor:terminate_child(ejabberd_sup, Proc),
     supervisor:delete_child(ejabberd_sup, Proc).
 
@@ -252,6 +251,7 @@ depends(_Host, _Opts) ->
     [].
 
 init([Host, Opts]) ->
+    process_flag(trap_exit, true),
     Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
     Mod:init(Host, Opts),
     MaxSize = gen_mod:get_opt(cache_size, Opts,
index fcc857c29995a8ac915739516dfd8cc90ed969e6..9abf5a45f489a69d263f48316c49e6ea17f5ecd2 100644 (file)
@@ -64,8 +64,9 @@ start(Host, Opts) ->
 
 stop(Host) ->
     Proc = gen_mod:get_module_proc(Host, ?MODULE),
-    gen_server:call(Proc, stop),
-    supervisor:delete_child(ejabberd_sup, Proc).
+    supervisor:terminate_child(ejabberd_sup, Proc),
+    supervisor:delete_child(ejabberd_sup, Proc),
+    ok.
 
 mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1;
 mod_opt_type(namespaces) -> validate_fun();
@@ -125,6 +126,7 @@ disco_sm_identity(Acc, From, To, Node, Lang) ->
 %%% gen_server callbacks
 %%%===================================================================
 init([Host, _Opts]) ->
+    process_flag(trap_exit, true),
     ejabberd_hooks:add(component_connected, ?MODULE,
                       component_connected, 50),
     ejabberd_hooks:add(component_disconnected, ?MODULE,
index 796c8cb1c6ca9453163f37c9048d9525e22015ee..80e41494b9a0c9aa1a531b2d4e1e13c91ba4f606 100644 (file)
@@ -68,9 +68,9 @@ start(Host, Opts) ->
 
 stop(Host) ->
     Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
-    gen_server:call(Proc, stop),
     supervisor:terminate_child(ejabberd_sup, Proc),
-    supervisor:delete_child(ejabberd_sup, Proc).
+    supervisor:delete_child(ejabberd_sup, Proc),
+    ok.
 
 %%====================================================================
 %% gen_server callbacks
@@ -84,6 +84,7 @@ stop(Host) ->
 %% Description: Initiates the server
 %%--------------------------------------------------------------------
 init([Host, Opts]) ->
+    process_flag(trap_exit, true),
     MyHost = gen_mod:get_opt_host(Host, Opts,
                                  <<"echo.@HOST@">>),
     ejabberd_router:register_route(MyHost, Host),
index 2c6ff618c4cb7860ca2b70877e5734d11fc51ac6..d76b2f9904af7d73d84077537374afa7db937bce 100644 (file)
@@ -119,7 +119,8 @@ start(Host, Opts) ->
 stop(Host) ->
     Proc = gen_mod:get_module_proc(Host, ?MODULE),
     supervisor:terminate_child(ejabberd_sup, Proc),
-    supervisor:delete_child(ejabberd_sup, Proc).
+    supervisor:delete_child(ejabberd_sup, Proc),
+    ok.
 
 depends(_Host, _Opts) ->
     [].
@@ -128,6 +129,7 @@ depends(_Host, _Opts) ->
 %%% gen_server callbacks
 %%%===================================================================
 init([Host, _Opts]) ->
+    process_flag(trap_exit, true),
     ejabberd_hooks:add(c2s_auth_result, Host, ?MODULE, c2s_auth_result, 100),
     ejabberd_hooks:add(c2s_stream_started, Host, ?MODULE, c2s_stream_started, 100),
     erlang:send_after(?CLEAN_INTERVAL, self(), clean),
index f837e868994c6a68cdb2bc969162c6549203a14f..7c95d96bdd722a2d251155f790b38f94e468bcf2 100644 (file)
@@ -102,9 +102,9 @@ start(Host, Opts) ->
 
 stop(Host) ->
     Proc = get_proc_name(Host),
-    gen_server:call(Proc, stop),
     supervisor:terminate_child(ejabberd_sup, Proc),
-    supervisor:delete_child(ejabberd_sup, Proc).
+    supervisor:delete_child(ejabberd_sup, Proc),
+    ok.
 
 depends(_Host, _Opts) ->
     [].
@@ -135,6 +135,7 @@ init([Host, Opts]) ->
        {DocRoot, AccessLog, AccessLogFD, DirectoryIndices,
         CustomHeaders, DefaultContentType, ContentTypes,
         UserAccess} ->
+           process_flag(trap_exit, true),
            {ok, #state{host = Host,
                        accesslog = AccessLog,
                        accesslogfd = AccessLogFD,
index 5df7588f4a0d80e2ee0cc3cdc0431a91fe2dfdcb..25c7430b28eccceba2f88cdaaa22c066107cd450 100644 (file)
@@ -91,8 +91,9 @@ start(Host, Opts) ->
 stop(Host) ->
     stop_supervisor(Host),
     Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
-    gen_server:call(Proc, stop),
-    supervisor:delete_child(ejabberd_sup, Proc).
+    supervisor:terminate_child(ejabberd_sup, Proc),
+    supervisor:delete_child(ejabberd_sup, Proc),
+    ok.
 
 depends(_Host, _Opts) ->
     [].
@@ -109,6 +110,7 @@ depends(_Host, _Opts) ->
 %% Description: Initiates the server
 %%--------------------------------------------------------------------
 init([Host, Opts]) ->
+    process_flag(trap_exit, true),
     ejabberd:start_app(iconv),
     MyHost = gen_mod:get_opt_host(Host, Opts,
                                  <<"irc.@HOST@">>),
index b5d17311e1a49e7b24dab578f118adceb1617e03..a7283fdd164c2a1149b9cf764decde34b1ac6b52 100644 (file)
@@ -80,6 +80,8 @@ stop(Host) ->
                          remove_user, 50),
     ejabberd_hooks:delete(unset_presence_hook, Host,
                          ?MODULE, on_presence_update, 50),
+    ejabberd_hooks:delete(privacy_check_packet, Host, ?MODULE,
+                         privacy_check_packet, 30),
     gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
                                     ?NS_LAST),
     gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
index 99d18e774017d3f521dbb008e2083b17cc258c27..9282d4a168dd8e1534020c20ba509b7e2b91a0dc 100644 (file)
@@ -134,6 +134,7 @@ process_iq(#iq{lang = Lang} = IQ) ->
 %%% gen_server callbacks
 %%%===================================================================
 init([ServerHost, Opts]) ->
+    process_flag(trap_exit, true),
     Host = gen_mod:get_opt_host(ServerHost, Opts, <<"mix.@HOST@">>),
     IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
                              one_queue),
index 1fe68ebd8a93652f155dc225cc583dbd739d3b52..9f39b17fde5f1a6ded55f1996435c8c6b2b1f79f 100644 (file)
@@ -123,7 +123,7 @@ start(Host, Opts) ->
 stop(Host) ->
     Rooms = shutdown_rooms(Host),
     Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
-    gen_server:call(Proc, stop),
+    supervisor:terminate_child(ejabberd_sup, Proc),
     supervisor:delete_child(ejabberd_sup, Proc),
     {wait, Rooms}.
 
@@ -230,6 +230,7 @@ get_online_rooms_by_user(ServerHost, LUser, LServer) ->
 %%====================================================================
 
 init([Host, Opts]) ->
+    process_flag(trap_exit, true),
     IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
                              one_queue),
     MyHost = gen_mod:get_opt_host(Host, Opts,
index 700f7284e9e9aaa9b0ff380969a0636654546c5f..fb9d22328122317e9b1be192019891e5365c7735 100644 (file)
@@ -85,8 +85,9 @@ start(Host, Opts) ->
 
 stop(Host) ->
     Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
-    gen_server:call(Proc, stop),
-    supervisor:delete_child(ejabberd_sup, Proc).
+    supervisor:terminate_child(ejabberd_sup, Proc),
+    supervisor:delete_child(ejabberd_sup, Proc),
+    ok.
 
 add_to_log(Host, Type, Data, Room, Opts) ->
     gen_server:cast(get_proc_name(Host),
@@ -115,6 +116,7 @@ depends(_Host, _Opts) ->
 %% gen_server callbacks
 %%====================================================================
 init([Host, Opts]) ->
+    process_flag(trap_exit, true),
     OutDir = gen_mod:get_opt(outdir, Opts,
                              fun iolist_to_binary/1,
                              <<"www/muc">>),
index 08d993106435e269f4eea249be37e0ec060037d2..7e8e21c3130353ff0a3803c5c4a4c7cf9caf9afd 100644 (file)
@@ -132,15 +132,16 @@ start(LServerS, Opts) ->
 
 stop(LServerS) ->
     Proc = gen_mod:get_module_proc(LServerS, ?PROCNAME),
-    gen_server:call(Proc, stop),
     supervisor:terminate_child(ejabberd_sup, Proc),
-    supervisor:delete_child(ejabberd_sup, Proc).
+    supervisor:delete_child(ejabberd_sup, Proc),
+    ok.
 
 %%====================================================================
 %% gen_server callbacks
 %%====================================================================
 
 init([LServerS, Opts]) ->
+    process_flag(trap_exit, true),
     LServiceS = gen_mod:get_opt_host(LServerS, Opts,
                                     <<"multicast.@HOST@">>),
     Access = gen_mod:get_opt(access, Opts,
index 61fa65bc56433f912095318842e85b71b637efe0..082386514b180d97dfd4ebcbce3d10eb1be5c0b0 100644 (file)
@@ -43,7 +43,6 @@
         stop/1,
         store_packet/4,
         store_offline_msg/5,
-        resend_offline_messages/2,
         c2s_self_presence/1,
         get_sm_features/5,
         get_sm_identity/5,
@@ -138,6 +137,7 @@ depends(_Host, _Opts) ->
 %%====================================================================
 
 init([Host, Opts]) ->
+    process_flag(trap_exit, true),
     Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
     Mod:init(Host, Opts),
     IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
@@ -545,22 +545,6 @@ find_x_expire(TimeStamp, Msg) ->
            never
     end.
 
-resend_offline_messages(User, Server) ->
-    LUser = jid:nodeprep(User),
-    LServer = jid:nameprep(Server),
-    Mod = gen_mod:db_mod(LServer, ?MODULE),
-    case Mod:pop_messages(LUser, LServer) of
-      {ok, Rs} ->
-         lists:foreach(
-           fun(R) ->
-                   case offline_msg_to_route(LServer, R) of
-                       error -> ok;
-                       RouteMsg -> ejabberd_sm ! RouteMsg
-                   end
-           end, lists:keysort(#offline_msg.timestamp, Rs));
-      _ -> ok
-    end.
-
 c2s_self_presence({_Pres, #{resend_offline := false}} = Acc) ->
     Acc;
 c2s_self_presence({#presence{type = available} = NewPres, State} = Acc) ->
index f59f548cb88d7dc52ea89bf345be5ed5b7fff6da..1c1d24850f1d35dbea2bc0c0ffefcdc7017b0e66 100644 (file)
@@ -94,13 +94,15 @@ start(Host, Opts) ->
 
 stop(Host) ->
     Proc = gen_mod:get_module_proc(Host, ?MODULE),
-    gen_server:call(Proc, stop),
-    supervisor:delete_child(?SUPERVISOR, Proc).
+    supervisor:terminate_child(ejabberd_sup, Proc),
+    supervisor:delete_child(?SUPERVISOR, Proc),
+    ok.
 
 %%====================================================================
 %% gen_server callbacks
 %%====================================================================
 init([Host, Opts]) ->
+    process_flag(trap_exit, true),
     SendPings = gen_mod:get_opt(send_pings, Opts,
                                 fun(B) when is_boolean(B) -> B end,
                                ?DEFAULT_SEND_PINGS),
index b860d9a39b43dbb8e2e0a5c664c3fff31683a667..3783470b2cb53397357de2fe7e1a562746a3a866 100644 (file)
@@ -62,8 +62,9 @@ start(Host, Opts) ->
 
 stop(Host) ->
     Proc = gen_mod:get_module_proc(Host, ?MODULE),
-    gen_server:call(Proc, stop),
-    supervisor:delete_child(ejabberd_sup, Proc).
+    supervisor:terminate_child(ejabberd_sup, Proc),
+    supervisor:delete_child(ejabberd_sup, Proc),
+    ok.
 
 mod_opt_type(roster) -> v_roster();
 mod_opt_type(message) -> v_message();
@@ -188,6 +189,7 @@ process_presence_in(Acc) ->
 %%% gen_server callbacks
 %%%===================================================================
 init([Host, _Opts]) ->
+    process_flag(trap_exit, true),
     ejabberd_hooks:add(component_connected, ?MODULE,
                        component_connected, 50),
     ejabberd_hooks:add(component_disconnected, ?MODULE,
index f51b33db2eaa2378ced5851b8662f24d5f9c63a8..1b584500beb1d1904a9db418b0d18d5d48d279c2 100644 (file)
@@ -55,6 +55,7 @@ start_link(Host, Opts) ->
                          [Host, Opts], []).
 
 init([Host, Opts]) ->
+    process_flag(trap_exit, true),
     IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
                              one_queue),
     MyHost = gen_mod:get_opt_host(Host, Opts, <<"proxy.@HOST@">>),
index 93c9abe7abd370abaf6e4fcbc76cd30ce331ba24..8acfdb7ce1dd2ef970856bc411afd1db2b61482d 100644 (file)
@@ -231,8 +231,9 @@ start(Host, Opts) ->
 
 stop(Host) ->
     Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
-    gen_server:call(Proc, stop),
-    supervisor:delete_child(ejabberd_sup, Proc).
+    supervisor:terminate_child(ejabberd_sup, Proc),
+    supervisor:delete_child(ejabberd_sup, Proc),
+    ok.
 
 %%====================================================================
 %% gen_server callbacks
@@ -248,6 +249,7 @@ stop(Host) ->
 -spec init([binary() | [{_,_}],...]) -> {'ok',state()}.
 
 init([ServerHost, Opts]) ->
+    process_flag(trap_exit, true),
     ?DEBUG("pubsub init ~p ~p", [ServerHost, Opts]),
     Host = gen_mod:get_opt_host(ServerHost, Opts, <<"pubsub.@HOST@">>),
     ejabberd_router:register_route(Host, ServerHost),
index 49a61a374b76c58a2f978c67f31150ecf5becad9..feb95810549dc1798f1348fab57ffa2dc9d36bdd 100644 (file)
@@ -104,7 +104,8 @@ start(Host, Opts) ->
 stop(Host) ->
     Proc = gen_mod:get_module_proc(Host, ?MODULE),
     supervisor:terminate_child(ejabberd_sup, Proc),
-    supervisor:delete_child(ejabberd_sup, Proc).
+    supervisor:delete_child(ejabberd_sup, Proc),
+    ok.
 
 depends(_Host, _Opts) ->
     [{mod_roster, hard}].
@@ -237,6 +238,7 @@ process_subscription(Direction, User, Server, JID,
 %% gen_server callbacks
 %%====================================================================
 init([Host, Opts]) ->
+    process_flag(trap_exit, true),
     State = parse_options(Host, Opts),
     cache_tab:new(shared_roster_ldap_user,
                  [{max_size, State#state.user_cache_size}, {lru, false},
index 83cf77a0dac7dc73b7636f1165ea34c9fcdd83c2..a6535c0f1d32b4b30884b6292113388fb4904197 100644 (file)
@@ -177,6 +177,7 @@ ping(SIPSocket) ->
 %%% gen_server callbacks
 %%%===================================================================
 init([]) ->
+    process_flag(trap_exit, true),
     update_table(),
     ejabberd_mnesia:create(?MODULE, sip_session,
                        [{ram_copies, [node()]},
index 66e239280a65242ce389932276a5b1778d273c88..f05de693f2cdbe96c92ac1fc186690f1e9ade8b3 100644 (file)
 -protocol({xep, 54, '1.2'}).
 -protocol({xep, 55, '1.3'}).
 
+-behaviour(gen_server).
 -behaviour(gen_mod).
 
--export([start/2, init/3, stop/1, get_sm_features/5,
+-export([start/2, stop/1, get_sm_features/5,
         process_local_iq/1, process_sm_iq/1, string2lower/1,
         remove_user/2, export/1, import_info/0, import/5, import_start/2,
         depends/2, process_search/1, process_vcard/1, get_vcard/2,
         disco_items/5, disco_features/5, disco_identity/5,
         decode_iq_subel/1, mod_opt_type/1, set_vcard/3, make_vcard_search/4]).
+-export([start_link/2, init/1, handle_call/3, handle_cast/2,
+        handle_info/2, terminate/2, code_change/3]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
 -callback remove_user(binary(), binary()) -> {atomic, any()}.
 -callback is_search_supported(binary()) -> boolean().
 
+-record(state, {host :: binary(), server_host :: binary()}).
+
+%%====================================================================
+%% API
+%%====================================================================
+start_link(Host, Opts) ->
+    Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
+    gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []).
+
+%%====================================================================
+%% gen_mod callbacks
+%%====================================================================
 start(Host, Opts) ->
+    Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
+    Spec = {Proc, {?MODULE, start_link, [Host, Opts]},
+           transient, 2000, worker, [?MODULE]},
+    supervisor:start_child(ejabberd_sup, Spec).
+
+stop(Host) ->
+    Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
+    supervisor:terminate_child(ejabberd_sup, Proc),
+    supervisor:delete_child(ejabberd_sup, Proc),
+    ok.
+
+%%====================================================================
+%% gen_server callbacks
+%%====================================================================
+init([Host, Opts]) ->
+    process_flag(trap_exit, true),
     Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
     Mod:init(Host, Opts),
     ejabberd_hooks:add(remove_user, Host, ?MODULE,
@@ -94,65 +125,55 @@ start(Host, Opts) ->
              process_local_iq_items, IQDisc),
            gen_iq_handler:add_iq_handler(
              ejabberd_local, MyHost, ?NS_DISCO_INFO, mod_disco,
-             process_local_iq_info, IQDisc);
+             process_local_iq_info, IQDisc),
+           case Mod:is_search_supported(Host) of
+               false ->
+                   ?WARNING_MSG("vcard search functionality is "
+                                "not implemented for ~s backend",
+                                [gen_mod:db_type(Host, Opts, ?MODULE)]);
+               true ->
+                   ejabberd_router:register_route(MyHost, Host)
+           end;
        true ->
            ok
     end,
-    Pid = spawn(?MODULE, init, [MyHost, Host, Search]),
-    register(gen_mod:get_module_proc(Host, ?PROCNAME), Pid),
-    {ok, Pid}.
-
-init(Host, ServerHost, Search) ->
-    case Search of
-      false -> loop(Host, ServerHost);
-      _ ->
-         ejabberd_router:register_route(Host, ServerHost),
-         Mod = gen_mod:db_mod(ServerHost, ?MODULE),
-         case Mod:is_search_supported(ServerHost) of
-             false ->
-                 ?WARNING_MSG("vcard search functionality is "
-                              "not implemented for ~s backend",
-                              [gen_mod:db_type(ServerHost, ?MODULE)]);
-              true ->
-                 ejabberd_router:register_route(Host, ServerHost)
-         end,
-         loop(Host, ServerHost)
-    end.
+    {ok, #state{host = MyHost, server_host = Host}}.
 
-loop(Host, ServerHost) ->
-    receive
-      {route, From, To, Packet} ->
-         case catch do_route(From, To, Packet) of
-           {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]);
-           _ -> ok
-         end,
-         loop(Host, ServerHost);
-      stop ->
-           ejabberd_router:unregister_route(Host),
-           ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, disco_items, 100),
-           ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, disco_features, 100),
-           ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, disco_identity, 100),
-           gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_SEARCH),
-           gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
-           gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS),
-           gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO);
-      _ -> loop(Host, ServerHost)
-    end.
+handle_call(_Call, _From, State) ->
+    {noreply, State}.
 
-stop(Host) ->
-    ejabberd_hooks:delete(remove_user, Host, ?MODULE,
-                         remove_user, 50),
-    gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
-                                    ?NS_VCARD),
-    gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
-                                    ?NS_VCARD),
-    ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE,
-                         get_sm_features, 50),
+handle_cast(Cast, State) ->
+    ?WARNING_MSG("unexpected cast: ~p", [Cast]),
+    {noreply, State}.
+
+handle_info({route, From, To, Packet}, State) ->
+    case catch do_route(From, To, Packet) of
+       {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]);
+       _ -> ok
+    end,
+    {noreply, State};
+handle_info(Info, State) ->
+    ?WARNING_MSG("unexpected info: ~p", [Info]),
+    {noreply, State}.
+
+terminate(_Reason, #state{host = MyHost, server_host = Host}) ->
+    ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 50),
+    gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
+    gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD),
+    ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
     Mod = gen_mod:db_mod(Host, ?MODULE),
     Mod:stop(Host),
-    Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
-    Proc ! stop,
-    {wait, Proc}.
+    ejabberd_router:unregister_route(MyHost),
+    ejabberd_hooks:delete(disco_local_items, MyHost, ?MODULE, disco_items, 100),
+    ejabberd_hooks:delete(disco_local_features, MyHost, ?MODULE, disco_features, 100),
+    ejabberd_hooks:delete(disco_local_identity, MyHost, ?MODULE, disco_identity, 100),
+    gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_SEARCH),
+    gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_VCARD),
+    gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS),
+    gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO).
+
+code_change(_OldVsn, State, _Extra) ->
+    {ok, State}.
 
 do_route(From, To, #xmlel{name = <<"iq">>} = El) ->
     ejabberd_router:process_iq(From, To, El);
index 3678ebbcdd7378840fe1d92b59649a14a4c11588..f7cc87d8e3c2c3d3cfd5c3a79587b5aa9f0d3f27 100644 (file)
@@ -85,9 +85,9 @@ init(Host, Opts) ->
 
 stop(Host) ->
     Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
-    gen_server:call(Proc, stop),
     supervisor:terminate_child(ejabberd_sup, Proc),
-    supervisor:delete_child(ejabberd_sup, Proc).
+    supervisor:delete_child(ejabberd_sup, Proc),
+    ok.
 
 is_search_supported(_LServer) ->
     true.
@@ -186,6 +186,7 @@ import(_, _, _) ->
 %%% gen_server callbacks
 %%%===================================================================
 init([Host, Opts]) ->
+    process_flag(trap_exit, true),
     State = parse_options(Host, Opts),
     eldap_pool:start_link(State#state.eldap_id,
                          State#state.servers, State#state.backups,