aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2018-03-05 11:36:07 +0100
committerAnders Svensson <[email protected]>2018-03-05 11:36:07 +0100
commit14df443df6312eccfd3774a002f02f0c9f170f9b (patch)
treec9749bdf71c6fd4c6e74fb5dc881129010d7265f /lib
parentf6968db2c08dc96197a0d4af46a020f3a6c9bc6c (diff)
parent5ac73d785185d857000f4ba72dc6fa5266ff80d1 (diff)
downloadotp-14df443df6312eccfd3774a002f02f0c9f170f9b.tar.gz
otp-14df443df6312eccfd3774a002f02f0c9f170f9b.tar.bz2
otp-14df443df6312eccfd3774a002f02f0c9f170f9b.zip
Merge branch 'maint'
Diffstat (limited to 'lib')
-rw-r--r--lib/diameter/src/base/diameter_reg.erl17
-rw-r--r--lib/diameter/src/base/diameter_service.erl20
2 files changed, 26 insertions, 11 deletions
diff --git a/lib/diameter/src/base/diameter_reg.erl b/lib/diameter/src/base/diameter_reg.erl
index 5b7cfab31a..c1762a07e3 100644
--- a/lib/diameter/src/base/diameter_reg.erl
+++ b/lib/diameter/src/base/diameter_reg.erl
@@ -246,8 +246,11 @@ handle_call({add, Uniq, Key}, {Pid, _}, S) ->
handle_call({remove, Key}, {Pid, _}, S) ->
Rec = {Key, Pid},
- ets:delete_object(?TABLE, Rec),
- {reply, true, notify(remove, Rec, S)};
+ {reply, true, try
+ notify(remove, Rec, S)
+ after
+ ets:delete_object(?TABLE, Rec)
+ end};
handle_call({wait, Pat}, {Pid, _} = From, S) ->
NS = add_monitor(Pid, S),
@@ -370,10 +373,12 @@ send({_,_} = From, add, Rec) ->
down(Pid, #state{monitors = Ps} = S) ->
Recs = match('_', Pid),
- ets:match_delete(?TABLE, {'_', Pid}),
- lists:foldl(fun(R,NS) -> notify(remove, R, NS) end,
- flush(Pid, S#state{monitors = sets:del_element(Pid, Ps)}),
- Recs).
+ Acc0 = flush(Pid, S#state{monitors = sets:del_element(Pid, Ps)}),
+ try
+ lists:foldl(fun(R,NS) -> notify(remove, R, NS) end, Acc0, Recs)
+ after
+ ets:match_delete(?TABLE, {'_', Pid})
+ end.
%% flush/3
diff --git a/lib/diameter/src/base/diameter_service.erl b/lib/diameter/src/base/diameter_service.erl
index 31dd92f878..55ebcafcf9 100644
--- a/lib/diameter/src/base/diameter_service.erl
+++ b/lib/diameter/src/base/diameter_service.erl
@@ -554,15 +554,25 @@ terminate(Reason, #state{service_name = Name, local = {PeerT, _, _}} = S) ->
%% wait for watchdog state changes to take care of if. That this
%% takes place after deleting the state entry ensures that the
%% resulting failover by request processes accomplishes nothing.
- ets:foldl(fun(#peer{pid = TPid}, _) ->
- diameter_traffic:peer_down(TPid)
- end,
- ok,
- PeerT),
+ ets:foldl(fun peer_down/2, ok, PeerT),
shutdown == Reason %% application shutdown
andalso shutdown(application, S).
+%% peer_down/1
+%%
+%% Entries with watchdog state SUSPECT are already down: ignore the
+%% expected failure. This assumes the current implementation, but
+%% double the number of lookups (in the typical case) could be the
+%% greater evil if there are many peer connections.
+
+peer_down(#peer{pid = TPid}, _) ->
+ try
+ diameter_traffic:peer_down(TPid)
+ catch
+ error: {badmatch, []} -> ok
+ end.
+
%% ---------------------------------------------------------------------------
%% # code_change/3
%% ---------------------------------------------------------------------------