aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaimo Niskanen <[email protected]>2019-07-03 11:47:57 +0200
committerRaimo Niskanen <[email protected]>2019-07-03 11:47:57 +0200
commitbf0f197f566b688df0e0c6a5a343019643732d86 (patch)
treef24c634cc140a80f4bbd4a23a75c230bbf487c6e
parent54e8284d883b11a83ec48edb41c9a15d657bae8e (diff)
downloadotp-bf0f197f566b688df0e0c6a5a343019643732d86.tar.gz
otp-bf0f197f566b688df0e0c6a5a343019643732d86.tar.bz2
otp-bf0f197f566b688df0e0c6a5a343019643732d86.zip
Refine the queue code
-rw-r--r--lib/ssl/src/ssl_connection.erl13
-rw-r--r--lib/ssl/src/tls_record.erl18
2 files changed, 25 insertions, 6 deletions
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index af9f0cbf3a..b3b1dc18dc 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -673,7 +673,18 @@ read_application_dist_data(DHandle, Front0, BufferSize, Rear0, Bin0) ->
iovec_from_front(0, Front, Rear, Acc) ->
{lists:reverse(Acc),Front,Rear};
iovec_from_front(Size, [], Rear, Acc) ->
- iovec_from_front(Size, lists:reverse(Rear), [], Acc);
+ case Rear of
+ %% Avoid lists:reverse/1 for simple cases.
+ %% Case clause for [] to avoid infinite loop.
+ [_] ->
+ iovec_from_front(Size, Rear, [], Acc);
+ [Bin2,Bin1] ->
+ iovec_from_front(Size, [Bin1,Bin2], [], Acc);
+ [Bin3,Bin2,Bin1] ->
+ iovec_from_front(Size, [Bin1,Bin2,Bin3], [], Acc);
+ [_,_,_|_] = Rear ->
+ iovec_from_front(Size, lists:reverse(Rear), [], Acc)
+ end;
iovec_from_front(Size, [Bin|Front], Rear, Acc) ->
case Bin of
<<Last:Size/binary>> -> % Just enough
diff --git a/lib/ssl/src/tls_record.erl b/lib/ssl/src/tls_record.erl
index afbf95948d..20598ea702 100644
--- a/lib/ssl/src/tls_record.erl
+++ b/lib/ssl/src/tls_record.erl
@@ -495,11 +495,19 @@ binary_from_front(SplitSize, {Front,Size,Rear}) when SplitSize =< Size ->
binary_from_front(SplitSize, Front, Size, Rear, []).
%%
%% SplitSize > 0 and there is at least SplitSize bytes buffered in Front and Rear
-binary_from_front(SplitSize, [], Size, [_] = Rear, Acc) ->
- %% Optimize a simple case - avoid lists:reverse/1
- binary_from_front(SplitSize, Rear, Size, [], Acc);
-binary_from_front(SplitSize, [], Size, [_|_] = Rear, Acc) ->
- binary_from_front(SplitSize, lists:reverse(Rear), Size, [], Acc);
+binary_from_front(SplitSize, [], Size, Rear, Acc) ->
+ case Rear of
+ %% Avoid lists:reverse/1 for simple cases.
+ %% Case clause for [] to avoid infinite loop.
+ [_] ->
+ binary_from_front(SplitSize, Rear, Size, [], Acc);
+ [Bin2,Bin1] ->
+ binary_from_front(SplitSize, [Bin1,Bin2], Size, [], Acc);
+ [Bin3,Bin2,Bin1] ->
+ binary_from_front(SplitSize, [Bin1,Bin2,Bin3], Size, [], Acc);
+ [_,_,_|_] ->
+ binary_from_front(SplitSize, lists:reverse(Rear), Size, [], Acc)
+ end;
binary_from_front(SplitSize, [Bin|Front], Size, Rear, []) ->
%% Optimize the frequent case when the accumulator is empty
BinSize = byte_size(Bin),