diff --git a/ChangeLog b/ChangeLog index cc18cadec..7209023eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2008-02-28 Badlop + + * src/ejabberd_app.erl (prep_stop): Stop modules when stopping + ejabberd (EJAB-536) + * src/mod_caps.erl (stop): Probably not needed to stop supervisor + child (EJAB-536) + * src/mod_muc/mod_muc.erl (room_destroyed): Catch message + sending (EJAB-536) + * src/mod_muc/mod_muc_room.erl (init): Ensure rooms are called + when the process dies due to a linked die (EJAB-536) + 2008-02-27 Mickael Remond * src/ejabberd_check.erl: Separate config loading from diff --git a/src/ejabberd_app.erl b/src/ejabberd_app.erl index d400336e2..4c12069d1 100644 --- a/src/ejabberd_app.erl +++ b/src/ejabberd_app.erl @@ -1,7 +1,7 @@ %%%---------------------------------------------------------------------- %%% File : ejabberd_app.erl %%% Author : Alexey Shchepin -%%% Purpose : ejabberd OTP application definition. +%%% Purpose : ejabberd's application callback module %%% Created : 31 Jan 2003 by Alexey Shchepin %%% %%% @@ -29,10 +29,15 @@ -behaviour(application). --export([start/2, stop/1, init/0]). +-export([start/2, prep_stop/1, stop/1, init/0]). -include("ejabberd.hrl"). + +%%% +%%% Application API +%%% + start(normal, _Args) -> ejabberd_loglevel:set(4), application:start(sasl), @@ -57,14 +62,27 @@ start(normal, _Args) -> %eprof:start(), %eprof:profile([self()]), %fprof:trace(start, "/tmp/fprof"), - load_modules(), + start_modules(), Sup; start(_, _) -> {error, badarg}. -stop(_StartArgs) -> +%% Prepare the application for termination. +%% This function is called when an application is about to be stopped, +%% before shutting down the processes of the application. +prep_stop(State) -> + stop_modules(), + State. + +%% All the processes were killed when this function is called +stop(_State) -> ok. + +%%% +%%% Internal functions +%%% + start() -> spawn_link(?MODULE, init, []). @@ -110,7 +128,8 @@ db_init() -> mnesia:start(), mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity). -load_modules() -> +%% Start all the modules in all the hosts +start_modules() -> lists:foreach( fun(Host) -> case ejabberd_config:get_local_option({modules, Host}) of @@ -124,6 +143,21 @@ load_modules() -> end end, ?MYHOSTS). +%% Stop all the modules in all the hosts +stop_modules() -> + lists:foreach( + fun(Host) -> + case ejabberd_config:get_local_option({modules, Host}) of + undefined -> + ok; + Modules -> + lists:foreach( + fun({Module, _Args}) -> + gen_mod:stop_module(Host, Module) + end, Modules) + end + end, ?MYHOSTS). + connect_nodes() -> case ejabberd_config:get_local_option(cluster_nodes) of undefined -> @@ -134,5 +168,3 @@ connect_nodes() -> end, Nodes) end. - - diff --git a/src/mod_caps.erl b/src/mod_caps.erl index 3734982eb..a337832f0 100644 --- a/src/mod_caps.erl +++ b/src/mod_caps.erl @@ -127,8 +127,7 @@ start(Host, Opts) -> stop(Host) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - gen_server:call(Proc, stop), - supervisor:stop_child(ejabberd_sup, Proc). + gen_server:call(Proc, stop). %%==================================================================== %% gen_server callbacks diff --git a/src/mod_muc/mod_muc.erl b/src/mod_muc/mod_muc.erl index 58ce97bb4..90a74b70f 100644 --- a/src/mod_muc/mod_muc.erl +++ b/src/mod_muc/mod_muc.erl @@ -91,8 +91,14 @@ stop(Host) -> gen_server:call(Proc, stop), supervisor:delete_child(ejabberd_sup, Proc). +%% This function is called by a room in three situations: +%% A) The owner of the room destroyed it +%% B) The only participant of a temporary room leaves it +%% C) mod_muc:stop was called, and each room is being terminated +%% In this case, the mod_muc process died before the room processes +%% So the message sending must be catched room_destroyed(Host, Room, Pid, ServerHost) -> - gen_mod:get_module_proc(ServerHost, ?PROCNAME) ! + catch gen_mod:get_module_proc(ServerHost, ?PROCNAME) ! {room_destroyed, {Room, Host}, Pid}, ok. diff --git a/src/mod_muc/mod_muc_room.erl b/src/mod_muc/mod_muc_room.erl index 8c848efa5..43918daa4 100644 --- a/src/mod_muc/mod_muc_room.erl +++ b/src/mod_muc/mod_muc_room.erl @@ -167,6 +167,7 @@ start_link(Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts) -> %% {stop, StopReason} %%---------------------------------------------------------------------- init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, _Nick, DefRoomOpts]) -> + process_flag(trap_exit, true), Shaper = shaper:new(RoomShaper), State = set_affiliation(Creator, owner, #state{host = Host, @@ -182,6 +183,7 @@ init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, _Nick, D [Room, Host, jlib:jid_to_string(Creator)]), {ok, normal_state, State1}; init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts]) -> + process_flag(trap_exit, true), Shaper = shaper:new(RoomShaper), State = set_opts(Opts, #state{host = Host, server_host = ServerHost,