diff options
author | Anders Svensson <[email protected]> | 2011-12-13 18:41:39 +0100 |
---|---|---|
committer | Anders Svensson <[email protected]> | 2011-12-16 15:18:04 +0100 |
commit | 719a4747d814913eef9b416da5aa6c638e8d2477 (patch) | |
tree | b1ca2d6ca721baba1ffcfe331f160b5694e394af /lib/diameter/src/base/diameter_watchdog.erl | |
parent | a67091debf20c972dd7ce1a8379fee6673fbe571 (diff) | |
download | otp-719a4747d814913eef9b416da5aa6c638e8d2477.tar.gz otp-719a4747d814913eef9b416da5aa6c638e8d2477.tar.bz2 otp-719a4747d814913eef9b416da5aa6c638e8d2477.zip |
Ensure capabilities exchange can't fail too early
In particular, not before the service process has a monitor on
the watchdog since the watchdog's exit reason is meaningful.
Diffstat (limited to 'lib/diameter/src/base/diameter_watchdog.erl')
-rw-r--r-- | lib/diameter/src/base/diameter_watchdog.erl | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/lib/diameter/src/base/diameter_watchdog.erl b/lib/diameter/src/base/diameter_watchdog.erl index 6dc53d9f31..fb22fd8275 100644 --- a/lib/diameter/src/base/diameter_watchdog.erl +++ b/lib/diameter/src/base/diameter_watchdog.erl @@ -59,10 +59,19 @@ message_data}). %% term passed into diameter_service with message %% start/2 +%% +%% Start a monitor before the watchdog is allowed to proceed to ensure +%% that a failed capabilities exchange produces the desired exit +%% reason. start({_,_} = Type, T) -> - {ok, Pid} = diameter_watchdog_sup:start_child({Type, self(), T}), - Pid. + Ref = make_ref(), + {ok, Pid} = diameter_watchdog_sup:start_child({Ref, {Type, self(), T}}), + try + {erlang:monitor(process, Pid), Pid} + after + Pid ! Ref + end. start_link(T) -> {ok, _} = proc_lib:start_link(?MODULE, @@ -80,14 +89,29 @@ init(T) -> proc_lib:init_ack({ok, self()}), gen_server:enter_loop(?MODULE, [], i(T)). -i({T, Pid, {ConnT, Opts, SvcName, #diameter_service{applications = Apps, - capabilities = Caps} - = Svc}}) -> - {M,S,U} = now(), - random:seed(M,S,U), +i({Ref, {_, Pid, _} = T}) -> + MRef = erlang:monitor(process, Pid), + receive + Ref -> + make_state(T); + {'DOWN', MRef, process, _, _} = D -> + exit({shutdown, D}) + end; + +i({_, Pid, _} = T) -> %% from old code + erlang:monitor(process, Pid), + make_state(T). + +make_state({T, Pid, {ConnT, + Opts, + SvcName, + #diameter_service{applications = Apps, + capabilities = Caps} + = Svc}}) -> + random:seed(now()), putr(restart, {T, Opts, Svc}), %% save seeing it in trace putr(dwr, dwr(Caps)), %% - #watchdog{parent = monitor(Pid), + #watchdog{parent = Pid, transport = monitor(diameter_peer_fsm:start(T, Opts, Svc)), tw = proplists:get_value(watchdog_timer, Opts, |