From b4b7e8a7a694b3473dcecdbf117e007ad22b8fb1 Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Sat, 11 Jun 2016 12:05:55 +0200 Subject: Redo transport config server as a gen_server To properly handle system messages. Initially implemented in commit 5ca5fb71. --- lib/diameter/src/base/diameter_config.erl | 59 +++++++++++++------------------ 1 file changed, 24 insertions(+), 35 deletions(-) (limited to 'lib/diameter') diff --git a/lib/diameter/src/base/diameter_config.erl b/lib/diameter/src/base/diameter_config.erl index 73b828536b..3074b65e02 100644 --- a/lib/diameter/src/base/diameter_config.erl +++ b/lib/diameter/src/base/diameter_config.erl @@ -61,8 +61,7 @@ code_change/3]). %% callbacks --export([sync/1, %% diameter_sync requests - remove/0]). %% transport server termination +-export([sync/1]). %% diameter_sync requests %% debug -export([state/0, @@ -72,7 +71,8 @@ -include("diameter_internal.hrl"). %% Server state. --record(state, {id = diameter_lib:now()}). +-record(state, {id = diameter_lib:now(), + role :: server | transport}). %% Registered name of the server. -define(SERVER, ?MODULE). @@ -292,7 +292,7 @@ uptime() -> %% ?SERVER start. init([]) -> - {ok, #state{}}; + {ok, #state{role = server}}; %% Child start as a consequence of add_transport. init({SvcName, Type, Opts}) -> @@ -302,31 +302,16 @@ init({SvcName, Type, Opts}) -> ?FAILURE(Reason) -> {error, Reason} end, proc_lib:init_ack({ok, self(), Res}), - sleep(Res). + loop(Res). -%% sleep/1 +%% loop/1 -sleep({ok, _}) -> - sleep(); +loop({ok, _}) -> + gen_server:enter_loop(?MODULE, [], #state{role = transport}); -sleep({error, _}) -> +loop({error, _}) -> ok. %% die -%% sleep/0 - -sleep() -> - proc_lib:hibernate(?MODULE, remove, []). - -%% remove/0 - -remove() -> - receive - {?MODULE, stop} -> - ok; - _ -> - sleep() - end. - %%% ---------------------------------------------------------- %%% # handle_call/2 %%% ---------------------------------------------------------- @@ -334,8 +319,8 @@ remove() -> handle_call(state, _, State) -> {reply, State, State}; -handle_call(uptime, _, #state{id = Time} = State) -> - {reply, diameter_lib:now_diff(Time), State}; +handle_call(uptime, _, #state{id = Time} = S) -> + {reply, diameter_lib:now_diff(Time), S}; handle_call(Req, From, State) -> ?UNEXPECTED([Req, From]), @@ -354,30 +339,34 @@ handle_cast(Msg, State) -> %%% # handle_info/2 %%% ---------------------------------------------------------- +%% remove_transport is telling published child to die. +handle_info(stop, #state{role = transport} = S) -> + {stop, normal, S}; + %% A service process has died. This is most likely a consequence of %% stop_service, in which case the restart will find no config for the %% service and do nothing. The entry keyed on the monitor ref is only %% removed as a result of the 'DOWN' notification however. -handle_info({'DOWN', MRef, process, _, Reason}, State) -> +handle_info({'DOWN', MRef, process, _, Reason}, #state{role = server} = S) -> [#monitor{service = SvcName} = T] = select([{#monitor{mref = MRef, _ = '_'}, [], ['$_']}]), queue_restart(Reason, SvcName), delete_object(T), - {noreply, State}; + {noreply, S}; -handle_info({monitor, SvcName, Pid}, State) -> +handle_info({monitor, SvcName, Pid}, #state{role = server} = S) -> monitor(Pid, SvcName), - {noreply, State}; + {noreply, S}; -handle_info({restart, SvcName}, State) -> +handle_info({restart, SvcName}, #state{role = server} = S) -> restart(SvcName), - {noreply, State}; + {noreply, S}; -handle_info(restart, State) -> +handle_info(restart, #state{role = server} = S) -> restart(), - {noreply, State}; + {noreply, S}; handle_info(Info, State) -> ?UNEXPECTED([Info]), @@ -667,7 +656,7 @@ remove(SvcName, L) -> stop_child(Ref) -> case diameter_reg:match(?TRANSPORT_KEY(Ref)) of [{_, Pid}] -> %% tell the transport-specific child to die - Pid ! {?MODULE, stop}; + Pid ! stop; [] -> %% already removed/dead ok end. -- cgit v1.2.3