* 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)

SVN Revision: 1212
This commit is contained in:
Badlop 2008-02-28 00:30:23 +00:00
parent 868182d1c8
commit 22a5bce9de
5 changed files with 60 additions and 10 deletions

View File

@ -1,3 +1,14 @@
2008-02-28 Badlop <badlop@process-one.net>
* 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 <mremond@process-one.net> 2008-02-27 Mickael Remond <mremond@process-one.net>
* src/ejabberd_check.erl: Separate config loading from * src/ejabberd_check.erl: Separate config loading from

View File

@ -1,7 +1,7 @@
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
%%% File : ejabberd_app.erl %%% File : ejabberd_app.erl
%%% Author : Alexey Shchepin <alexey@process-one.net> %%% Author : Alexey Shchepin <alexey@process-one.net>
%%% Purpose : ejabberd OTP application definition. %%% Purpose : ejabberd's application callback module
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
@ -29,10 +29,15 @@
-behaviour(application). -behaviour(application).
-export([start/2, stop/1, init/0]). -export([start/2, prep_stop/1, stop/1, init/0]).
-include("ejabberd.hrl"). -include("ejabberd.hrl").
%%%
%%% Application API
%%%
start(normal, _Args) -> start(normal, _Args) ->
ejabberd_loglevel:set(4), ejabberd_loglevel:set(4),
application:start(sasl), application:start(sasl),
@ -57,14 +62,27 @@ start(normal, _Args) ->
%eprof:start(), %eprof:start(),
%eprof:profile([self()]), %eprof:profile([self()]),
%fprof:trace(start, "/tmp/fprof"), %fprof:trace(start, "/tmp/fprof"),
load_modules(), start_modules(),
Sup; Sup;
start(_, _) -> start(_, _) ->
{error, badarg}. {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. ok.
%%%
%%% Internal functions
%%%
start() -> start() ->
spawn_link(?MODULE, init, []). spawn_link(?MODULE, init, []).
@ -110,7 +128,8 @@ db_init() ->
mnesia:start(), mnesia:start(),
mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity). mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).
load_modules() -> %% Start all the modules in all the hosts
start_modules() ->
lists:foreach( lists:foreach(
fun(Host) -> fun(Host) ->
case ejabberd_config:get_local_option({modules, Host}) of case ejabberd_config:get_local_option({modules, Host}) of
@ -124,6 +143,21 @@ load_modules() ->
end end
end, ?MYHOSTS). 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() -> connect_nodes() ->
case ejabberd_config:get_local_option(cluster_nodes) of case ejabberd_config:get_local_option(cluster_nodes) of
undefined -> undefined ->
@ -134,5 +168,3 @@ connect_nodes() ->
end, Nodes) end, Nodes)
end. end.

View File

@ -127,8 +127,7 @@ start(Host, Opts) ->
stop(Host) -> stop(Host) ->
Proc = gen_mod:get_module_proc(Host, ?PROCNAME), Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
gen_server:call(Proc, stop), gen_server:call(Proc, stop).
supervisor:stop_child(ejabberd_sup, Proc).
%%==================================================================== %%====================================================================
%% gen_server callbacks %% gen_server callbacks

View File

@ -91,8 +91,14 @@ stop(Host) ->
gen_server:call(Proc, stop), gen_server:call(Proc, stop),
supervisor:delete_child(ejabberd_sup, Proc). 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) -> 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}, {room_destroyed, {Room, Host}, Pid},
ok. ok.

View File

@ -167,6 +167,7 @@ start_link(Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts) ->
%% {stop, StopReason} %% {stop, StopReason}
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, _Nick, DefRoomOpts]) -> init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, _Nick, DefRoomOpts]) ->
process_flag(trap_exit, true),
Shaper = shaper:new(RoomShaper), Shaper = shaper:new(RoomShaper),
State = set_affiliation(Creator, owner, State = set_affiliation(Creator, owner,
#state{host = Host, #state{host = Host,
@ -182,6 +183,7 @@ init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, _Nick, D
[Room, Host, jlib:jid_to_string(Creator)]), [Room, Host, jlib:jid_to_string(Creator)]),
{ok, normal_state, State1}; {ok, normal_state, State1};
init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts]) -> init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts]) ->
process_flag(trap_exit, true),
Shaper = shaper:new(RoomShaper), Shaper = shaper:new(RoomShaper),
State = set_opts(Opts, #state{host = Host, State = set_opts(Opts, #state{host = Host,
server_host = ServerHost, server_host = ServerHost,