From 971001e7aa04a4691356f4ae85e00526506c8a6f Mon Sep 17 00:00:00 2001 From: Alexey Shchepin Date: Thu, 2 Feb 2006 05:00:27 +0000 Subject: [PATCH] * src/mod_pubsub/mod_pubsub.erl: Updated to use gen_server behaviour and ejabberd supervision tree * src/mod_muc/mod_muc.erl: Added a supervisor for conference room processes * src/mod_muc/mod_muc_room.erl: Likewise SVN Revision: 496 --- ChangeLog | 13 +- src/mod_echo.erl | 123 ++++++++++++--- src/mod_muc/mod_muc.erl | 282 +++++++++++++++++++++++----------- src/mod_muc/mod_muc_room.erl | 20 ++- src/mod_pubsub/mod_pubsub.erl | 203 ++++++++++++++---------- 5 files changed, 444 insertions(+), 197 deletions(-) diff --git a/ChangeLog b/ChangeLog index b28db2ec6..8def40af1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2006-02-02 Alexey Shchepin + + * src/mod_pubsub/mod_pubsub.erl: Updated to use gen_server + behaviour and ejabberd supervision tree + +2006-02-01 Alexey Shchepin + + * src/mod_muc/mod_muc.erl: Added a supervisor for conference room + processes + * src/mod_muc/mod_muc_room.erl: Likewise + 2006-01-29 Alexey Shchepin * src/odbc/pg.sql: Fixed syntax error @@ -10,7 +21,7 @@ * src/gen_iq_handler.erl: Likewise * src/ejabberd_sup.erl: Added supervisor for ejabberd_receiver - * src/ejabberd_receiver.erl: Updating + * src/ejabberd_receiver.erl: Updated 2006-01-27 Alexey Shchepin diff --git a/src/mod_echo.erl b/src/mod_echo.erl index fd7e7ed37..d37becb6a 100644 --- a/src/mod_echo.erl +++ b/src/mod_echo.erl @@ -10,38 +10,117 @@ -author('alexey@sevcom.net'). -vsn('$Revision$ '). +-behaviour(gen_server). -behaviour(gen_mod). --export([start/2, init/1, stop/1]). +%% API +-export([start_link/2, start/2, stop/1]). + +%% gen_server callbacks +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + terminate/2, code_change/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). +-record(state, {host}). + -define(PROCNAME, ejabberd_mod_echo). +%%==================================================================== +%% API +%%==================================================================== +%%-------------------------------------------------------------------- +%% Function: start_link() -> {ok,Pid} | ignore | {error,Error} +%% Description: Starts the server +%%-------------------------------------------------------------------- +start_link(Host, Opts) -> + Proc = gen_mod:get_module_proc(Host, ?PROCNAME), + gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). + start(Host, Opts) -> - MyHost = gen_mod:get_opt(host, Opts, "echo." ++ Host), - register(gen_mod:get_module_proc(Host, ?PROCNAME), - spawn(?MODULE, init, [MyHost])). - -init(Host) -> - ejabberd_router:register_route(Host), - loop(Host). - -loop(Host) -> - receive - {route, From, To, Packet} -> - ejabberd_router:route(To, From, Packet), - loop(Host); - stop -> - ejabberd_router:unregister_route(Host), - ok; - _ -> - loop(Host) - end. + Proc = gen_mod:get_module_proc(Host, ?PROCNAME), + ChildSpec = + {Proc, + {?MODULE, start_link, [Host, Opts]}, + temporary, + 1000, + worker, + [?MODULE]}, + supervisor:start_child(ejabberd_sup, ChildSpec). stop(Host) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - Proc ! stop, - {wait, Proc}. + gen_server:call(Proc, stop), + supervisor:stop_child(ejabberd_sup, Proc). +%%==================================================================== +%% gen_server callbacks +%%==================================================================== + +%%-------------------------------------------------------------------- +%% Function: init(Args) -> {ok, State} | +%% {ok, State, Timeout} | +%% ignore | +%% {stop, Reason} +%% Description: Initiates the server +%%-------------------------------------------------------------------- +init([Host, Opts]) -> + MyHost = gen_mod:get_opt(host, Opts, "echo." ++ Host), + ejabberd_router:register_route(MyHost), + {ok, #state{host = MyHost}}. + +%%-------------------------------------------------------------------- +%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | +%% {reply, Reply, State, Timeout} | +%% {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, Reply, State} | +%% {stop, Reason, State} +%% Description: Handling call messages +%%-------------------------------------------------------------------- +handle_call(stop, _From, State) -> + {stop, normal, ok, State}. + +%%-------------------------------------------------------------------- +%% Function: handle_cast(Msg, State) -> {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, State} +%% Description: Handling cast messages +%%-------------------------------------------------------------------- +handle_cast(_Msg, State) -> + {noreply, State}. + +%%-------------------------------------------------------------------- +%% Function: handle_info(Info, State) -> {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, State} +%% Description: Handling all non call/cast messages +%%-------------------------------------------------------------------- +handle_info({route, From, To, Packet}, State) -> + ejabberd_router:route(To, From, Packet), + {noreply, State}; +handle_info(_Info, State) -> + {noreply, State}. + +%%-------------------------------------------------------------------- +%% Function: terminate(Reason, State) -> void() +%% Description: This function is called by a gen_server when it is about to +%% terminate. It should be the opposite of Module:init/1 and do any necessary +%% cleaning up. When it returns, the gen_server terminates with Reason. +%% The return value is ignored. +%%-------------------------------------------------------------------- +terminate(_Reason, State) -> + ejabberd_router:unregister_route(State#state.host), + ok. + +%%-------------------------------------------------------------------- +%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} +%% Description: Convert process state when code is changed +%%-------------------------------------------------------------------- +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +%%-------------------------------------------------------------------- +%%% Internal functions +%%-------------------------------------------------------------------- diff --git a/src/mod_muc/mod_muc.erl b/src/mod_muc/mod_muc.erl index b3112472d..742565a64 100644 --- a/src/mod_muc/mod_muc.erl +++ b/src/mod_muc/mod_muc.erl @@ -10,10 +10,12 @@ -author('alexey@sevcom.net'). -vsn('$Revision$ '). +-behaviour(gen_server). -behaviour(gen_mod). --export([start/2, - init/3, +%% API +-export([start_link/2, + start/2, stop/1, room_destroyed/3, store_room/3, @@ -22,6 +24,10 @@ process_iq_disco_items/4, can_use_nick/3]). +%% gen_server callbacks +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + terminate/2, code_change/3]). + -include("ejabberd.hrl"). -include("jlib.hrl"). @@ -30,9 +36,106 @@ -record(muc_online_room, {name_host, pid}). -record(muc_registered, {us_host, nick}). +-record(state, {host, server_host, access}). + -define(PROCNAME, ejabberd_mod_muc). +%%==================================================================== +%% API +%%==================================================================== +%%-------------------------------------------------------------------- +%% Function: start_link() -> {ok,Pid} | ignore | {error,Error} +%% Description: Starts the server +%%-------------------------------------------------------------------- +start_link(Host, Opts) -> + Proc = gen_mod:get_module_proc(Host, ?PROCNAME), + gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). + start(Host, Opts) -> + start_supervisor(Host), + Proc = gen_mod:get_module_proc(Host, ?PROCNAME), + ChildSpec = + {Proc, + {?MODULE, start_link, [Host, Opts]}, + temporary, + 1000, + worker, + [?MODULE]}, + supervisor:start_child(ejabberd_sup, ChildSpec). + +stop(Host) -> + stop_supervisor(Host), + Proc = gen_mod:get_module_proc(Host, ?PROCNAME), + gen_server:call(Proc, stop), + supervisor:delete_child(ejabberd_sup, Proc). + +room_destroyed(Host, Room, ServerHost) -> + gen_mod:get_module_proc(ServerHost, ?PROCNAME) ! + {room_destroyed, {Room, Host}}, + ok. + +store_room(Host, Name, Opts) -> + F = fun() -> + mnesia:write(#muc_room{name_host = {Name, Host}, + opts = Opts}) + end, + mnesia:transaction(F). + +restore_room(Host, Name) -> + case catch mnesia:dirty_read(muc_room, {Name, Host}) of + [#muc_room{opts = Opts}] -> + Opts; + _ -> + error + end. + +forget_room(Host, Name) -> + F = fun() -> + mnesia:delete({muc_room, {Name, Host}}) + end, + mnesia:transaction(F). + +process_iq_disco_items(Host, From, To, #iq{lang = Lang} = IQ) -> + Res = IQ#iq{type = result, + sub_el = [{xmlelement, "query", + [{"xmlns", ?NS_DISCO_ITEMS}], + iq_disco_items(Host, From, Lang)}]}, + ejabberd_router:route(To, + From, + jlib:iq_to_xml(Res)). + +can_use_nick(_Host, _JID, "") -> + false; +can_use_nick(Host, JID, Nick) -> + {LUser, LServer, _} = jlib:jid_tolower(JID), + LUS = {LUser, LServer}, + case catch mnesia:dirty_select( + muc_registered, + [{#muc_registered{us_host = '$1', + nick = Nick, + _ = '_'}, + [{'==', {element, 2, '$1'}, Host}], + ['$_']}]) of + {'EXIT', _Reason} -> + true; + [] -> + true; + [#muc_registered{us_host = {U, _Host}}] -> + U == LUS + end. + +%%==================================================================== +%% gen_server callbacks +%%==================================================================== + +%%-------------------------------------------------------------------- +%% Function: init(Args) -> {ok, State} | +%% {ok, State, Timeout} | +%% ignore | +%% {stop, Reason} +%% Description: Initiates the server +%%-------------------------------------------------------------------- +init([Host, Opts]) -> mnesia:create_table(muc_room, [{disc_copies, [node()]}, {attributes, record_info(fields, muc_room)}]), @@ -45,40 +148,96 @@ start(Host, Opts) -> Access = gen_mod:get_opt(access, Opts, all), AccessCreate = gen_mod:get_opt(access_create, Opts, all), AccessAdmin = gen_mod:get_opt(access_admin, Opts, none), - register(gen_mod:get_module_proc(Host, ?PROCNAME), - spawn(?MODULE, init, - [MyHost, Host, {Access, AccessCreate, AccessAdmin}])). - - - -init(Host, ServerHost, Access) -> catch ets:new(muc_online_room, [named_table, public, {keypos, #muc_online_room.name_host}]), - ejabberd_router:register_route(Host), - load_permanent_rooms(Host, ServerHost, Access), - loop(Host, ServerHost, Access). + ejabberd_router:register_route(MyHost), + load_permanent_rooms(MyHost, Host, {Access, AccessCreate, AccessAdmin}), + {ok, #state{host = MyHost, + server_host = Host, + access = {Access, AccessCreate, AccessAdmin}}}. -loop(Host, ServerHost, Access) -> - receive - {route, From, To, Packet} -> - case catch do_route(Host, ServerHost, Access, From, To, Packet) of - {'EXIT', Reason} -> - ?ERROR_MSG("~p", [Reason]); - _ -> - ok - end, - loop(Host, ServerHost, Access); - {room_destroyed, RoomHost} -> - ets:delete(muc_online_room, RoomHost), - loop(Host, ServerHost, Access); - stop -> - ejabberd_router:unregister_route(Host), - ok; +%%-------------------------------------------------------------------- +%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | +%% {reply, Reply, State, Timeout} | +%% {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, Reply, State} | +%% {stop, Reason, State} +%% Description: Handling call messages +%%-------------------------------------------------------------------- +handle_call(stop, _From, State) -> + {stop, normal, ok, State}. + +%%-------------------------------------------------------------------- +%% Function: handle_cast(Msg, State) -> {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, State} +%% Description: Handling cast messages +%%-------------------------------------------------------------------- +handle_cast(_Msg, State) -> + {noreply, State}. + +%%-------------------------------------------------------------------- +%% Function: handle_info(Info, State) -> {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, State} +%% Description: Handling all non call/cast messages +%%-------------------------------------------------------------------- +handle_info({route, From, To, Packet}, + #state{host = Host, + server_host = ServerHost, + access = Access} = State) -> + case catch do_route(Host, ServerHost, Access, From, To, Packet) of + {'EXIT', Reason} -> + ?ERROR_MSG("~p", [Reason]); _ -> - loop(Host, ServerHost, Access) - end. + ok + end, + {noreply, State}; +handle_info({room_destroyed, RoomHost}, State) -> + ets:delete(muc_online_room, RoomHost), + {noreply, State}; +handle_info(_Info, State) -> + {noreply, State}. +%%-------------------------------------------------------------------- +%% Function: terminate(Reason, State) -> void() +%% Description: This function is called by a gen_server when it is about to +%% terminate. It should be the opposite of Module:init/1 and do any necessary +%% cleaning up. When it returns, the gen_server terminates with Reason. +%% The return value is ignored. +%%-------------------------------------------------------------------- +terminate(_Reason, State) -> + ejabberd_router:unregister_route(State#state.host), + ok. + +%%-------------------------------------------------------------------- +%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} +%% Description: Convert process state when code is changed +%%-------------------------------------------------------------------- +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +%%-------------------------------------------------------------------- +%%% Internal functions +%%-------------------------------------------------------------------- +start_supervisor(Host) -> + Proc = gen_mod:get_module_proc(Host, ejabberd_mod_muc_sup), + ChildSpec = + {Proc, + {ejabberd_tmp_sup, start_link, + [Proc, mod_muc_room]}, + permanent, + infinity, + supervisor, + [ejabberd_tmp_sup]}, + supervisor:start_child(ejabberd_sup, ChildSpec). + +stop_supervisor(Host) -> + Proc = gen_mod:get_module_proc(Host, ejabberd_mod_muc_sup), + supervisor:terminate_child(ejabberd_sup, Proc), + supervisor:delete_child(ejabberd_sup, Proc). do_route(Host, ServerHost, Access, From, To, Packet) -> {AccessRoute, _AccessCreate, _AccessAdmin} = Access, @@ -252,40 +411,6 @@ do_route1(Host, ServerHost, Access, From, To, Packet) -> -room_destroyed(Host, Room, ServerHost) -> - gen_mod:get_module_proc(ServerHost, ?PROCNAME) ! - {room_destroyed, {Room, Host}}, - ok. - -stop(Host) -> - Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - Proc ! stop, - {wait, Proc}. - - -store_room(Host, Name, Opts) -> - F = fun() -> - mnesia:write(#muc_room{name_host = {Name, Host}, - opts = Opts}) - end, - mnesia:transaction(F). - -restore_room(Host, Name) -> - case catch mnesia:dirty_read(muc_room, {Name, Host}) of - [#muc_room{opts = Opts}] -> - Opts; - _ -> - error - end. - - -forget_room(Host, Name) -> - F = fun() -> - mnesia:delete({muc_room, {Name, Host}}) - end, - mnesia:transaction(F). - - load_permanent_rooms(Host, ServerHost, Access) -> case catch mnesia:dirty_select( muc_room, [{#muc_room{name_host = {'_', Host}, _ = '_'}, @@ -321,15 +446,6 @@ iq_disco_info() -> {xmlelement, "feature", [{"var", ?NS_VCARD}], []}]. -process_iq_disco_items(Host, From, To, #iq{lang = Lang} = IQ) -> - Res = IQ#iq{type = result, - sub_el = [{xmlelement, "query", - [{"xmlns", ?NS_DISCO_ITEMS}], - iq_disco_items(Host, From, Lang)}]}, - ejabberd_router:route(To, - From, - jlib:iq_to_xml(Res)). - iq_disco_items(Host, From, Lang) -> lists:zf(fun(#muc_online_room{name_host = {Name, _Host}, pid = Pid}) -> case catch gen_fsm:sync_send_all_state_event( @@ -482,26 +598,6 @@ get_vh_rooms(Host) -> ['$_']}]). -can_use_nick(_Host, _JID, "") -> - false; -can_use_nick(Host, JID, Nick) -> - {LUser, LServer, _} = jlib:jid_tolower(JID), - LUS = {LUser, LServer}, - case catch mnesia:dirty_select( - muc_registered, - [{#muc_registered{us_host = '$1', - nick = Nick, - _ = '_'}, - [{'==', {element, 2, '$1'}, Host}], - ['$_']}]) of - {'EXIT', _Reason} -> - true; - [] -> - true; - [#muc_registered{us_host = {U, _Host}}] -> - U == LUS - end. - update_tables(Host) -> update_muc_room_table(Host), diff --git a/src/mod_muc/mod_muc_room.erl b/src/mod_muc/mod_muc_room.erl index 9cbdc6874..8942b832f 100644 --- a/src/mod_muc/mod_muc_room.erl +++ b/src/mod_muc/mod_muc_room.erl @@ -14,7 +14,9 @@ %% External exports --export([start/6, +-export([start_link/6, + start_link/5, + start/6, start/5, route/4]). @@ -84,11 +86,21 @@ %%% API %%%---------------------------------------------------------------------- start(Host, ServerHost, Access, Room, Creator, Nick) -> - gen_fsm:start(?MODULE, [Host, ServerHost, Access, Room, Creator, Nick], - ?FSMOPTS). + Supervisor = gen_mod:get_module_proc(ServerHost, ejabberd_mod_muc_sup), + supervisor:start_child( + Supervisor, [Host, ServerHost, Access, Room, Creator, Nick]). start(Host, ServerHost, Access, Room, Opts) -> - gen_fsm:start(?MODULE, [Host, ServerHost, Access, Room, Opts], ?FSMOPTS). + Supervisor = gen_mod:get_module_proc(ServerHost, ejabberd_mod_muc_sup), + supervisor:start_child( + Supervisor, [Host, ServerHost, Access, Room, Opts]). + +start_link(Host, ServerHost, Access, Room, Creator, Nick) -> + gen_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, Creator, Nick], + ?FSMOPTS). + +start_link(Host, ServerHost, Access, Room, Opts) -> + gen_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, Opts], ?FSMOPTS). %%%---------------------------------------------------------------------- %%% Callback functions from gen_fsm diff --git a/src/mod_pubsub/mod_pubsub.erl b/src/mod_pubsub/mod_pubsub.erl index c957c9aca..7c3353a56 100644 --- a/src/mod_pubsub/mod_pubsub.erl +++ b/src/mod_pubsub/mod_pubsub.erl @@ -10,15 +10,13 @@ -author('alexey@sevcom.net'). -vsn('$Revision$ '). +-behaviour(gen_server). -behaviour(gen_mod). --export([start/2, - init/4, - loop/2, - stop/1, - system_continue/3, - system_terminate/4, - system_code_change/4]). +%% API +-export([start_link/2, + start/2, + stop/1]). -export([delete_item/3, set_entities/4, @@ -28,9 +26,15 @@ get_node_config/4, set_node_config/4]). +%% gen_server callbacks +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + terminate/2, code_change/3]). + -include("ejabberd.hrl"). -include("jlib.hrl"). +-record(state, {host}). + -define(DICT, dict). -define(MAXITEMS, 20). -define(MAX_PAYLOAD_SIZE, 100000). @@ -45,60 +49,35 @@ -record(item, {id, publisher, payload}). -define(PROCNAME, ejabberd_mod_pubsub). - -start(Host, Opts) -> - mnesia:create_table(pubsub_node, - [{disc_only_copies, [node()]}, - {attributes, record_info(fields, pubsub_node)}]), - MyHost = gen_mod:get_opt(host, Opts, "pubsub." ++ Host), - update_table(MyHost), - mnesia:add_table_index(pubsub_node, host_parent), - ServedHosts = gen_mod:get_opt(served_hosts, Opts, []), - register(gen_mod:get_module_proc(Host, ?PROCNAME), - proc_lib:spawn_link(?MODULE, init, - [MyHost, Host, ServedHosts, self()])). - - -define(MYJID, #jid{user = "", server = Host, resource = "", luser = "", lserver = Host, lresource = ""}). -init(Host, ServerHost, ServedHosts, Parent) -> - ejabberd_router:register_route(Host), - create_new_node(Host, ["pubsub"], ?MYJID), - create_new_node(Host, ["pubsub", "nodes"], ?MYJID), - create_new_node(Host, ["home"], ?MYJID), - create_new_node(Host, ["home", ServerHost], ?MYJID), - lists:foreach(fun(H) -> - create_new_node(Host, ["home", H], ?MYJID) - end, ServedHosts), - ets:new(gen_mod:get_module_proc(Host, pubsub_presence), [set, named_table]), - loop(Host, Parent). +%%==================================================================== +%% API +%%==================================================================== +%%-------------------------------------------------------------------- +%% Function: start_link() -> {ok,Pid} | ignore | {error,Error} +%% Description: Starts the server +%%-------------------------------------------------------------------- +start_link(Host, Opts) -> + Proc = gen_mod:get_module_proc(Host, ?PROCNAME), + gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). -loop(Host, Parent) -> - receive - {route, From, To, Packet} -> - case catch do_route(To#jid.lserver, From, To, Packet) of - {'EXIT', Reason} -> - ?ERROR_MSG("~p", [Reason]); - _ -> - ok - end, - loop(Host, Parent); - {room_destroyed, Room} -> - ets:delete(muc_online_room, Room), - loop(Host, Parent); - stop -> - ejabberd_router:unregister_route(Host), - ok; - reload -> - ?MODULE:loop(Host, Parent); - {system, From, Request} -> - sys:handle_system_msg(Request, From, Parent, ?MODULE, [], Host); - _ -> - loop(Host, Parent) - end. +start(Host, Opts) -> + Proc = gen_mod:get_module_proc(Host, ?PROCNAME), + ChildSpec = + {Proc, + {?MODULE, start_link, [Host, Opts]}, + temporary, + 1000, + worker, + [?MODULE]}, + supervisor:start_child(ejabberd_sup, ChildSpec). -%%% API functions +stop(Host) -> + Proc = gen_mod:get_module_proc(Host, ?PROCNAME), + gen_server:call(Proc, stop), + supervisor:stop_child(ejabberd_sup, Proc). delete_item(From, Node, ItemID) -> delete_item(get_host(), From, Node, ItemID). @@ -124,8 +103,98 @@ get_host() -> timeout end. -%%% Internal functions +%%==================================================================== +%% gen_server callbacks +%%==================================================================== +%%-------------------------------------------------------------------- +%% Function: init(Args) -> {ok, State} | +%% {ok, State, Timeout} | +%% ignore | +%% {stop, Reason} +%% Description: Initiates the server +%%-------------------------------------------------------------------- +init([Host, Opts]) -> + mnesia:create_table(pubsub_node, + [{disc_only_copies, [node()]}, + {attributes, record_info(fields, pubsub_node)}]), + MyHost = gen_mod:get_opt(host, Opts, "pubsub." ++ Host), + update_table(MyHost), + mnesia:add_table_index(pubsub_node, host_parent), + ServedHosts = gen_mod:get_opt(served_hosts, Opts, []), + + + ejabberd_router:register_route(MyHost), + create_new_node(MyHost, ["pubsub"], ?MYJID), + create_new_node(MyHost, ["pubsub", "nodes"], ?MYJID), + create_new_node(MyHost, ["home"], ?MYJID), + create_new_node(MyHost, ["home", Host], ?MYJID), + lists:foreach(fun(H) -> + create_new_node(MyHost, ["home", H], ?MYJID) + end, ServedHosts), + ets:new(gen_mod:get_module_proc(MyHost, pubsub_presence), + [set, named_table]), + {ok, #state{host = MyHost}}. + +%%-------------------------------------------------------------------- +%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | +%% {reply, Reply, State, Timeout} | +%% {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, Reply, State} | +%% {stop, Reason, State} +%% Description: Handling call messages +%%-------------------------------------------------------------------- +handle_call(stop, _From, State) -> + {stop, normal, ok, State}. + +%%-------------------------------------------------------------------- +%% Function: handle_cast(Msg, State) -> {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, State} +%% Description: Handling cast messages +%%-------------------------------------------------------------------- +handle_cast(_Msg, State) -> + {noreply, State}. + +%%-------------------------------------------------------------------- +%% Function: handle_info(Info, State) -> {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, State} +%% Description: Handling all non call/cast messages +%%-------------------------------------------------------------------- +handle_info({route, From, To, Packet}, State) -> + case catch do_route(To#jid.lserver, From, To, Packet) of + {'EXIT', Reason} -> + ?ERROR_MSG("~p", [Reason]); + _ -> + ok + end, + {noreply, State}; +handle_info(_Info, State) -> + {noreply, State}. + +%%-------------------------------------------------------------------- +%% Function: terminate(Reason, State) -> void() +%% Description: This function is called by a gen_server when it is about to +%% terminate. It should be the opposite of Module:init/1 and do any necessary +%% cleaning up. When it returns, the gen_server terminates with Reason. +%% The return value is ignored. +%%-------------------------------------------------------------------- +terminate(_Reason, State) -> + ejabberd_router:unregister_route(State#state.host), + ok. + +%%-------------------------------------------------------------------- +%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} +%% Description: Convert process state when code is changed +%%-------------------------------------------------------------------- +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +%%-------------------------------------------------------------------- +%%% Internal functions +%%-------------------------------------------------------------------- do_route(Host, From, To, Packet) -> {xmlelement, Name, Attrs, Els} = Packet, case To of @@ -236,14 +305,6 @@ do_route(Host, From, To, Packet) -> - -stop(Host) -> - Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - Proc ! stop, - {wait, Proc}. - - - node_to_string(Node) -> string:strip(lists:flatten(lists:map(fun(S) -> [S, "/"] end, Node)), right, $/). @@ -1261,18 +1322,6 @@ broadcast_config_notification(Host, Node, Lang) -> -system_continue(Parent, _, State) -> - loop(State, Parent). - -system_terminate(Reason, Parent, _, State) -> - exit(Reason). - -system_code_change(State, _Mod, Ver, _Extra) -> - {ok, State}. - - - - iq_pubsub_owner(Host, From, Type, Lang, SubEl) -> {xmlelement, _, _, SubEls} = SubEl, case xml:remove_cdata(SubEls) of