From f664e39374875d486185a59cabdd50971d2631f6 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Tue, 14 Feb 2017 10:25:08 +0300 Subject: [PATCH] Improve modules start/stop procedures --- src/ejabberd_local.erl | 43 +++++----- src/ejabberd_s2s_out.erl | 2 +- src/ejabberd_sm.erl | 41 ++++----- src/mod_announce.erl | 150 +++++++++++++++++++-------------- src/mod_caps.erl | 2 +- src/mod_delegation.erl | 6 +- src/mod_echo.erl | 5 +- src/mod_fail2ban.erl | 4 +- src/mod_http_fileserver.erl | 5 +- src/mod_irc.erl | 6 +- src/mod_last.erl | 2 + src/mod_mix.erl | 1 + src/mod_muc.erl | 3 +- src/mod_muc_log.erl | 6 +- src/mod_multicast.erl | 5 +- src/mod_offline.erl | 18 +--- src/mod_ping.erl | 6 +- src/mod_privilege.erl | 6 +- src/mod_proxy65_service.erl | 1 + src/mod_pubsub.erl | 6 +- src/mod_shared_roster_ldap.erl | 4 +- src/mod_sip_registrar.erl | 1 + src/mod_vcard.erl | 125 +++++++++++++++------------ src/mod_vcard_ldap.erl | 5 +- 24 files changed, 253 insertions(+), 200 deletions(-) diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl index f80d97249..bd9a1b2e4 100644 --- a/src/ejabberd_local.erl +++ b/src/ejabberd_local.erl @@ -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,6 +220,21 @@ init([]) -> handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State}. +handle_cast({register_iq_handler, Host, XMLNS, Module, + Function, Opts}, + State) -> + ets:insert(?IQTABLE, + {{Host, XMLNS}, Module, Function, Opts}), + {noreply, State}; +handle_cast({unregister_iq_handler, Host, XMLNS}, + State) -> + case ets:lookup(?IQTABLE, {Host, XMLNS}) of + [{_, Module, Function, Opts}] -> + gen_iq_handler:stop_iq_handler(Module, Function, Opts); + _ -> ok + end, + ets:delete(?IQTABLE, {Host, XMLNS}), + {noreply, State}; handle_cast(_Msg, State) -> {noreply, State}. handle_info({route, From, To, Packet}, State) -> @@ -232,25 +245,11 @@ handle_info({route, From, To, Packet}, State) -> _ -> ok end, {noreply, State}; -handle_info({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}, - State) -> - case ets:lookup(?IQTABLE, {Host, XMLNS}) of - [{_, Module, Function, Opts}] -> - gen_iq_handler:stop_iq_handler(Module, Function, Opts); - _ -> ok - end, - ets:delete(?IQTABLE, {Host, XMLNS}), - {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) -> diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl index a923860f3..7a85cb48a 100644 --- a/src/ejabberd_s2s_out.erl +++ b/src/ejabberd_s2s_out.erl @@ -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, []). diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 62f250d57..12bfb4e10 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -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,6 +407,21 @@ init([]) -> handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State}. +handle_cast({register_iq_handler, Host, XMLNS, Module, + Function, Opts}, + State) -> + ets:insert(sm_iqtable, + {{Host, XMLNS}, Module, Function, Opts}), + {noreply, State}; +handle_cast({unregister_iq_handler, Host, XMLNS}, + State) -> + case ets:lookup(sm_iqtable, {Host, XMLNS}) of + [{_, Module, Function, Opts}] -> + gen_iq_handler:stop_iq_handler(Module, Function, Opts); + _ -> ok + end, + ets:delete(sm_iqtable, {Host, XMLNS}), + {noreply, State}; handle_cast(_Msg, State) -> {noreply, State}. handle_info({route, From, To, Packet}, State) -> @@ -419,22 +433,9 @@ handle_info({route, From, To, Packet}, State) -> ok end, {noreply, State}; -handle_info({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}, - State) -> - case ets:lookup(sm_iqtable, {Host, XMLNS}) of - [{_, Module, Function, Opts}] -> - gen_iq_handler:stop_iq_handler(Module, Function, Opts); - _ -> ok - end, - ets:delete(sm_iqtable, {Host, XMLNS}), - {noreply, State}; -handle_info(_Info, State) -> {noreply, State}. +handle_info(Info, State) -> + ?WARNING_MSG("unexpected info: ~p", [Info]), + {noreply, State}. terminate(_Reason, _State) -> lists:foreach( diff --git a/src/mod_announce.erl b/src/mod_announce.erl index e8c71f31d..e22a42223 100644 --- a/src/mod_announce.erl +++ b/src/mod_announce.erl @@ -29,13 +29,16 @@ -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">>, @@ -58,7 +63,36 @@ 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 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 diff --git a/src/mod_caps.erl b/src/mod_caps.erl index 391a3ba74..ae7998108 100644 --- a/src/mod_caps.erl +++ b/src/mod_caps.erl @@ -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, diff --git a/src/mod_delegation.erl b/src/mod_delegation.erl index fcc857c29..9abf5a45f 100644 --- a/src/mod_delegation.erl +++ b/src/mod_delegation.erl @@ -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, diff --git a/src/mod_echo.erl b/src/mod_echo.erl index 796c8cb1c..80e41494b 100644 --- a/src/mod_echo.erl +++ b/src/mod_echo.erl @@ -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), diff --git a/src/mod_fail2ban.erl b/src/mod_fail2ban.erl index 2c6ff618c..d76b2f990 100644 --- a/src/mod_fail2ban.erl +++ b/src/mod_fail2ban.erl @@ -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), diff --git a/src/mod_http_fileserver.erl b/src/mod_http_fileserver.erl index f837e8689..7c95d96bd 100644 --- a/src/mod_http_fileserver.erl +++ b/src/mod_http_fileserver.erl @@ -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, diff --git a/src/mod_irc.erl b/src/mod_irc.erl index 5df7588f4..25c7430b2 100644 --- a/src/mod_irc.erl +++ b/src/mod_irc.erl @@ -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@">>), diff --git a/src/mod_last.erl b/src/mod_last.erl index b5d17311e..a7283fdd1 100644 --- a/src/mod_last.erl +++ b/src/mod_last.erl @@ -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, diff --git a/src/mod_mix.erl b/src/mod_mix.erl index 99d18e774..9282d4a16 100644 --- a/src/mod_mix.erl +++ b/src/mod_mix.erl @@ -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), diff --git a/src/mod_muc.erl b/src/mod_muc.erl index 1fe68ebd8..9f39b17fd 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -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, diff --git a/src/mod_muc_log.erl b/src/mod_muc_log.erl index 700f7284e..fb9d22328 100644 --- a/src/mod_muc_log.erl +++ b/src/mod_muc_log.erl @@ -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">>), diff --git a/src/mod_multicast.erl b/src/mod_multicast.erl index 08d993106..7e8e21c31 100644 --- a/src/mod_multicast.erl +++ b/src/mod_multicast.erl @@ -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, diff --git a/src/mod_offline.erl b/src/mod_offline.erl index 61fa65bc5..082386514 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -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) -> diff --git a/src/mod_ping.erl b/src/mod_ping.erl index f59f548cb..1c1d24850 100644 --- a/src/mod_ping.erl +++ b/src/mod_ping.erl @@ -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), diff --git a/src/mod_privilege.erl b/src/mod_privilege.erl index b860d9a39..3783470b2 100644 --- a/src/mod_privilege.erl +++ b/src/mod_privilege.erl @@ -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, diff --git a/src/mod_proxy65_service.erl b/src/mod_proxy65_service.erl index f51b33db2..1b584500b 100644 --- a/src/mod_proxy65_service.erl +++ b/src/mod_proxy65_service.erl @@ -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@">>), diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index 93c9abe7a..8acfdb7ce 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -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), diff --git a/src/mod_shared_roster_ldap.erl b/src/mod_shared_roster_ldap.erl index 49a61a374..feb958105 100644 --- a/src/mod_shared_roster_ldap.erl +++ b/src/mod_shared_roster_ldap.erl @@ -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}, diff --git a/src/mod_sip_registrar.erl b/src/mod_sip_registrar.erl index 83cf77a0d..a6535c0f1 100644 --- a/src/mod_sip_registrar.erl +++ b/src/mod_sip_registrar.erl @@ -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()]}, diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index 66e239280..f05de693f 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -30,14 +30,17 @@ -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"). @@ -61,7 +64,35 @@ -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}. + {ok, #state{host = MyHost, server_host = Host}}. -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. +handle_call(_Call, _From, State) -> + {noreply, State}. -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_cast(Cast, State) -> + ?WARNING_MSG("unexpected cast: ~p", [Cast]), + {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_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); diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl index 3678ebbcd..f7cc87d8e 100644 --- a/src/mod_vcard_ldap.erl +++ b/src/mod_vcard_ldap.erl @@ -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,