summaryrefslogtreecommitdiff
path: root/lib/kernel/src/dist_util.erl
diff options
context:
space:
mode:
authorSverker Eriksson <sverker@erlang.org>2017-10-12 16:55:34 +0200
committerSverker Eriksson <sverker@erlang.org>2017-10-12 16:55:34 +0200
commit1d8f12c010f9e31a986f80caae6c7ab749c2a3bb (patch)
tree769c0860ee98885e3933b936b633ffeb3d6e4a9c /lib/kernel/src/dist_util.erl
parented2700c3f517e4575ff15558d5d109ee2904083a (diff)
downloaderlang-1d8f12c010f9e31a986f80caae6c7ab749c2a3bb.tar.gz
kernel: Fix and improve send_tick logic
Problem 1: Tick was not sent to hidden when pending sends. Don't hidden need the tick in order to reply? Problem 2: Written packets (#tick.write) was increased even when tick was suppressed due to pending sends. Code rewritten to handle outgoing and incoming separate.
Diffstat (limited to 'lib/kernel/src/dist_util.erl')
-rw-r--r--lib/kernel/src/dist_util.erl67
1 files changed, 37 insertions, 30 deletions
diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl
index 08bd5946cd..3f35398b1b 100644
--- a/lib/kernel/src/dist_util.erl
+++ b/lib/kernel/src/dist_util.erl
@@ -587,7 +587,7 @@ con_loop({Kernel, Node, Socket, Type, DHandle, MFTick, MFGetstat,
{Kernel, aux_tick} ->
case getstat(DHandle, Socket, MFGetstat) of
{ok, _, _, PendWrite} ->
- send_tick(Socket, PendWrite, MFTick);
+ send_aux_tick(Type, Socket, PendWrite, MFTick);
_ ->
ignore_it
end,
@@ -840,49 +840,56 @@ send_status(#hs_data{socket = Socket, other_node = Node,
%% The detection time interval is thus, by default, 45s < DT < 75s
-%% A HIDDEN node is always (if not a pending write) ticked if
-%% we haven't read anything as a hidden node only ticks when it receives
-%% a TICK !!
+%% A HIDDEN node is always ticked if we haven't read anything
+%% as a (primitive) hidden node only ticks when it receives a TICK !!
send_tick(DHandle, Socket, Tick, Type, MFTick, MFGetstat) ->
#tick{tick = T0,
read = Read,
write = Write,
- ticked = Ticked} = Tick,
+ ticked = Ticked0} = Tick,
T = T0 + 1,
T1 = T rem 4,
case getstat(DHandle, Socket, MFGetstat) of
- {ok, Read, _, _} when Ticked =:= T ->
+ {ok, Read, _, _} when Ticked0 =:= T ->
{error, not_responding};
- {ok, Read, W, Pend} when Type =:= hidden ->
- send_tick(Socket, Pend, MFTick),
- {ok, Tick#tick{write = W + 1,
- tick = T1}};
- {ok, Read, Write, Pend} ->
- send_tick(Socket, Pend, MFTick),
- {ok, Tick#tick{write = Write + 1,
- tick = T1}};
- {ok, R, Write, Pend} ->
- send_tick(Socket, Pend, MFTick),
- {ok, Tick#tick{write = Write + 1,
- read = R,
- tick = T1,
- ticked = T}};
- {ok, Read, W, _} ->
- {ok, Tick#tick{write = W,
- tick = T1}};
- {ok, R, W, _} ->
- {ok, Tick#tick{write = W,
- read = R,
- tick = T1,
- ticked = T}};
+
+ {ok, R, W1, Pend} ->
+ RDiff = R - Read,
+ W2 = case need_to_tick(Type, RDiff, W1-Write, Pend) of
+ true ->
+ MFTick(Socket),
+ W1 + 1;
+ false ->
+ W1
+ end,
+
+ Ticked1 = case RDiff of
+ 0 -> Ticked0;
+ _ -> T
+ end,
+
+ {ok, Tick#tick{write = W2,
+ tick = T1,
+ read = R,
+ ticked = Ticked1}};
+
Error ->
Error
end.
-send_tick(_, Pend, _) when Pend /= false, Pend /= 0 ->
+need_to_tick(_, _, 0, 0) -> % nothing written and empty send queue
+ true;
+need_to_tick(_, _, 0, false) -> % nothing written and empty send queue
+ true;
+need_to_tick(hidden, 0, _, _) -> % nothing read from hidden
+ true;
+need_to_tick(_, _, _, _) ->
+ false.
+
+send_aux_tick(normal, _, Pend, _) when Pend /= false, Pend /= 0 ->
ok; %% Dont send tick if pending write.
-send_tick(Socket, _Pend, MFTick) ->
+send_aux_tick(_Type, Socket, _Pend, MFTick) ->
MFTick(Socket).
%% ------------------------------------------------------------