From 278cc4e5a2552397437999f482bcc4237ed36d35 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Thu, 14 Sep 2017 16:11:27 +0200 Subject: Separate in and out in dist ctrl --- lib/ssl/src/inet_tls_dist.erl | 8 +++-- lib/ssl/src/ssl_tls_dist_ctrl.erl | 69 ++++++++++++++++++++++++++------------- 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) -> -- cgit v1.2.3