Skip to content
Browse files

Merge branch 'anders/diameter/missed_events/OTP-9824' into maint

* anders/diameter/missed_events/OTP-9824:
  Update watchdog suite
  Ensure capabilities exchange can't fail too early
  • Loading branch information...
2 parents 40d5714 + 8a7b17a commit 0610ab240d5b4bdfe8b5a23f34dcbae81ba9adce Anders Svensson committed
View
20 lib/diameter/src/base/diameter_service.erl
@@ -629,10 +629,6 @@ insert(Tbl, Rec) ->
ets:insert(Tbl, Rec),
Rec.
-monitor(Pid) ->
- erlang:monitor(process, Pid),
- Pid.
-
%% Using the process dictionary for the callback state was initially
%% just a way to make what was horrendous trace (big state record and
%% much else everywhere) somewhat more readable. There's not as much
@@ -814,10 +810,10 @@ start(Ref, Type, Opts, #state{peerT = PeerT,
service = Svc})
when Type == connect;
Type == accept ->
- Pid = monitor(s(Type, Ref, {ConnT,
- Opts,
- SvcName,
- merge_service(Opts, Svc)})),
+ Pid = s(Type, Ref, {ConnT,
+ Opts,
+ SvcName,
+ merge_service(Opts, Svc)}),
insert(PeerT, #peer{pid = Pid,
type = Type,
ref = Ref,
@@ -830,7 +826,13 @@ start(Ref, Type, Opts, #state{peerT = PeerT,
%% callbacks.
s(Type, Ref, T) ->
- diameter_watchdog:start({Type, Ref}, T).
+ case diameter_watchdog:start({Type, Ref}, T) of
+ {_MRef, Pid} ->
+ Pid;
+ Pid when is_pid(Pid) -> %% from old code
+ erlang:monitor(process, Pid),
+ Pid
+ end.
%% merge_service/2
View
40 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,
View
11 lib/diameter/test/diameter_watchdog_SUITE.erl
@@ -306,11 +306,8 @@ watchdog(Type, Ref, TPid, Wd) ->
Opts = [{transport_module, ?MODULE},
{transport_config, TPid},
{watchdog_timer, Wd}],
- monitor(diameter_watchdog:start({Type, Ref},
- {false, Opts, false, ?SERVICE})).
-
-monitor(Pid) ->
- erlang:monitor(process, Pid),
+ {_MRef, Pid} = diameter_watchdog:start({Type, Ref},
+ {false, Opts, false, ?SERVICE}),
Pid.
%% ===========================================================================
@@ -350,6 +347,10 @@ init(_, _, TPid, _) ->
monitor(TPid),
3.
+monitor(Pid) ->
+ erlang:monitor(process, Pid),
+ Pid.
+
%% Generate a unique hostname for the faked peer.
hostname() ->
lists:flatten(io_lib:format("~p-~p-~p", tuple_to_list(now()))).

0 comments on commit 0610ab2

Please sign in to comment.
Something went wrong with that request. Please try again.