aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaimo Niskanen <[email protected]>2017-09-14 16:11:27 +0200
committerRaimo Niskanen <[email protected]>2017-09-15 11:54:00 +0200
commit278cc4e5a2552397437999f482bcc4237ed36d35 (patch)
treefd8ccb458d2fa0ac30ab91bc52ca36b4430700a3
parentc2180b0e570baf90cbf567381212bb223fc73d37 (diff)
downloadotp-278cc4e5a2552397437999f482bcc4237ed36d35.tar.gz
otp-278cc4e5a2552397437999f482bcc4237ed36d35.tar.bz2
otp-278cc4e5a2552397437999f482bcc4237ed36d35.zip
Separate in and out in dist ctrl
-rw-r--r--lib/ssl/src/inet_tls_dist.erl8
-rw-r--r--lib/ssl/src/ssl_tls_dist_ctrl.erl69
2 files changed, 51 insertions, 26 deletions
diff --git a/lib/ssl/src/inet_tls_dist.erl b/lib/ssl/src/inet_tls_dist.erl
index 47f400da6f..65dab189a3 100644
--- a/lib/ssl/src/inet_tls_dist.erl
+++ b/lib/ssl/src/inet_tls_dist.erl
@@ -345,11 +345,13 @@ splitnode(Driver, Node, LongOrShortNames) ->
Host = lists:append(Tail),
check_node(Driver, Name, Node, Host, LongOrShortNames);
[_] ->
- error_logger:error_msg("** Nodename ~p illegal, no '@' character **~n",
- [Node]),
+ error_logger:error_msg(
+ "** Nodename ~p illegal, no '@' character **~n",
+ [Node]),
?shutdown(Node);
_ ->
- error_logger:error_msg("** Nodename ~p illegal **~n", [Node]),
+ error_logger:error_msg(
+ "** Nodename ~p illegal **~n", [Node]),
?shutdown(Node)
end.
diff --git a/lib/ssl/src/ssl_tls_dist_ctrl.erl b/lib/ssl/src/ssl_tls_dist_ctrl.erl
index cbb39e71ec..c1d5bc689e 100644
--- a/lib/ssl/src/ssl_tls_dist_ctrl.erl
+++ b/lib/ssl/src/ssl_tls_dist_ctrl.erl
@@ -277,7 +277,7 @@ setup_loop(SslSocket, TickHandler, Sup) ->
Res =
ssl:setopts(
SslSocket,
- [{active, false}, {packet, 4}, inet_tls_dist:nodelay()]),
+ [{packet, 4}, inet_tls_dist:nodelay()]),
From ! {Ref, Res},
setup_loop(SslSocket, TickHandler, Sup);
@@ -285,7 +285,7 @@ setup_loop(SslSocket, TickHandler, Sup) ->
Res =
ssl:setopts(
SslSocket,
- [{active, once}, {packet, 4}, inet_tls_dist:nodelay()]),
+ [{packet, 4}, inet_tls_dist:nodelay()]),
From ! {Ref, Res},
setup_loop(SslSocket, TickHandler, Sup);
@@ -296,30 +296,33 @@ setup_loop(SslSocket, TickHandler, Sup) ->
{Ref, From, {handshake_complete, _Node, DHandle}} ->
From ! {Ref, ok},
%% Handshake complete! Begin dispatching traffic...
+ %%
+ %% Use a dedicated input process to push the
+ %% input-output-flow-control-deadlock problem
+ %% to the SSL implementation.
+ InputHandler =
+ spawn_opt(
+ fun () ->
+ link(Sup),
+ ssl:setopts(SslSocket, [{active, once}]),
+ receive
+ DHandle ->
+ input_loop(DHandle, SslSocket)
+ end
+ end,
+ [link] ++ common_spawn_opts()),
+ ok = ssl:controlling_process(SslSocket, InputHandler),
+ ok = erlang:dist_ctrl_input_handler(DHandle, InputHandler),
+ InputHandler ! DHandle,
+ %%
%% From now on we execute on normal priority
process_flag(priority, normal),
erlang:dist_ctrl_get_data_notification(DHandle),
- loop(DHandle, SslSocket)
+ output_loop(DHandle, SslSocket)
end.
-loop(DHandle, SslSocket) ->
+input_loop(DHandle, SslSocket) ->
receive
- dist_data ->
- %% Outgoing data from this node...
- try send_data(DHandle, SslSocket)
- catch _ : _ -> death_row()
- end,
- loop(DHandle, SslSocket);
-
- {send, From, Ref, Data} ->
- %% This is for testing only!
- %%
- %% Needed by some OTP distribution
- %% test suites...
- sock_send(SslSocket, Data),
- From ! {Ref, ok},
- loop(DHandle, SslSocket);
-
{ssl_closed, SslSocket} ->
%% Connection to remote node terminated...
exit(connection_closed);
@@ -330,13 +333,33 @@ loop(DHandle, SslSocket) ->
%% Incoming data from remote node...
ok = ssl:setopts(SslSocket, [{active, once}]),
try erlang:dist_ctrl_put_data(DHandle, Data)
- catch _ : _ -> death_row()
+ catch _:_ -> death_row()
end,
- loop(DHandle, SslSocket);
+ input_loop(DHandle, SslSocket);
+ _ ->
+ %% Drop garbage message...
+ input_loop(DHandle, SslSocket)
+ end.
+output_loop(DHandle, SslSocket) ->
+ receive
+ dist_data ->
+ %% Outgoing data from this node...
+ try send_data(DHandle, SslSocket)
+ catch _ : _ -> death_row()
+ end,
+ output_loop(DHandle, SslSocket);
+ {send, From, Ref, Data} ->
+ %% This is for testing only!
+ %%
+ %% Needed by some OTP distribution
+ %% test suites...
+ sock_send(SslSocket, Data),
+ From ! {Ref, ok},
+ output_loop(DHandle, SslSocket);
_ ->
%% Drop garbage message...
- loop(DHandle, SslSocket)
+ output_loop(DHandle, SslSocket)
end.
send_data(DHandle, SslSocket) ->