aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Nilsson <[email protected]>2018-03-19 11:42:30 +0100
committerHans Nilsson <[email protected]>2018-03-19 11:42:30 +0100
commitaa5a6ddb3ef4e3f36f49150e57fec2896e9314f2 (patch)
tree0c213786b06eb91038580b918356546af67ffd2c
parentfd2f39ce26eb8afd51bcf0fac765ec381de663dc (diff)
parent4d5218efec5049c243a5faeac70fd473c028d87f (diff)
downloadotp-aa5a6ddb3ef4e3f36f49150e57fec2896e9314f2.tar.gz
otp-aa5a6ddb3ef4e3f36f49150e57fec2896e9314f2.tar.bz2
otp-aa5a6ddb3ef4e3f36f49150e57fec2896e9314f2.zip
Merge branch 'hans/ssh/faster_app_stop/OTP-14988'
* hans/ssh/faster_app_stop/OTP-14988: ssh: Remove deadlock in supervisor tree ssh: Remove spawn in ssh_system_sup:stop_system/1 ssh: Removed unused sshc_sup:stop_child/1
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl57
-rw-r--r--lib/ssh/src/ssh_system_sup.erl4
-rw-r--r--lib/ssh/src/sshc_sup.erl9
3 files changed, 36 insertions, 34 deletions
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index e11d3adee4..852e70d9e2 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -1168,7 +1168,6 @@ handle_event({call,From}, stop, StateName, D0) ->
{Repls,D} = send_replies(Replies, D0),
{stop_and_reply, normal, [{reply,From,ok}|Repls], D#data{connection_state=Connection}};
-
handle_event({call,_}, _, StateName, _) when not ?CONNECTED(StateName) ->
{keep_state_and_data, [postpone]};
@@ -1450,37 +1449,43 @@ handle_event(Type, Ev, StateName, D) ->
-spec terminate(any(),
state_name(),
#data{}
- ) -> finalize_termination_result() .
+ ) -> term().
%% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
terminate(normal, StateName, State) ->
- finalize_termination(StateName, State);
+ stop_subsystem(State),
+ close_transport(State);
terminate({shutdown,{init,Reason}}, StateName, State) ->
error_logger:info_report(io_lib:format("Erlang ssh in connection handler init: ~p~n",[Reason])),
- finalize_termination(StateName, State);
+ stop_subsystem(State),
+ close_transport(State);
terminate(shutdown, StateName, State0) ->
%% Terminated by supervisor
State = send_msg(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
- description = "Application shutdown"},
- State0),
- finalize_termination(StateName, State);
+ description = "Application shutdown"},
+ State0),
+ close_transport(State);
terminate({shutdown,_R}, StateName, State) ->
- finalize_termination(StateName, State);
+ %% Internal termination
+ stop_subsystem(State),
+ close_transport(State);
terminate(kill, StateName, State) ->
- finalize_termination(StateName, State);
+ stop_subsystem(State),
+ close_transport(State);
terminate(Reason, StateName, State0) ->
%% Others, e.g undef, {badmatch,_}
log_error(Reason),
State = send_msg(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
- description = "Internal error"},
+ description = "Internal error"},
State0),
- finalize_termination(StateName, State).
+ stop_subsystem(State),
+ close_transport(State).
%%--------------------------------------------------------------------
@@ -1555,21 +1560,25 @@ start_the_connection_child(UserPid, Role, Socket, Options0) ->
%%--------------------------------------------------------------------
%% Stopping
--type finalize_termination_result() :: ok .
-
-finalize_termination(_StateName, #data{transport_cb = Transport,
- connection_state = Connection,
- socket = Socket}) ->
- case Connection of
- #connection{system_supervisor = SysSup,
- sub_system_supervisor = SubSysSup} when is_pid(SubSysSup) ->
- ssh_system_sup:stop_subsystem(SysSup, SubSysSup);
- _ ->
- do_nothing
- end,
- (catch Transport:close(Socket)),
+
+stop_subsystem(#data{connection_state =
+ #connection{system_supervisor = SysSup,
+ sub_system_supervisor = SubSysSup}}) when is_pid(SubSysSup) ->
+ ssh_system_sup:stop_subsystem(SysSup, SubSysSup);
+stop_subsystem(_) ->
ok.
+
+close_transport(#data{transport_cb = Transport,
+ socket = Socket}) ->
+ try
+ Transport:close(Socket)
+ of
+ _ -> ok
+ catch
+ _:_ -> ok
+ end.
+
%%--------------------------------------------------------------------
%% "Invert" the Role
peer_role(client) -> server;
diff --git a/lib/ssh/src/ssh_system_sup.erl b/lib/ssh/src/ssh_system_sup.erl
index 17f990c5d8..469f9560e9 100644
--- a/lib/ssh/src/ssh_system_sup.erl
+++ b/lib/ssh/src/ssh_system_sup.erl
@@ -88,11 +88,11 @@ stop_listener(Address, Port, Profile) ->
stop_system(SysSup) ->
- spawn(fun() -> sshd_sup:stop_child(SysSup) end),
+ catch sshd_sup:stop_child(SysSup),
ok.
stop_system(Address, Port, Profile) ->
- spawn(fun() -> sshd_sup:stop_child(Address, Port, Profile) end),
+ catch sshd_sup:stop_child(Address, Port, Profile),
ok.
diff --git a/lib/ssh/src/sshc_sup.erl b/lib/ssh/src/sshc_sup.erl
index fd4d8a3c07..f4b39dbbdc 100644
--- a/lib/ssh/src/sshc_sup.erl
+++ b/lib/ssh/src/sshc_sup.erl
@@ -27,7 +27,7 @@
-behaviour(supervisor).
--export([start_link/0, start_child/1, stop_child/1]).
+-export([start_link/0, start_child/1]).
%% Supervisor callback
-export([init/1]).
@@ -43,13 +43,6 @@ start_link() ->
start_child(Args) ->
supervisor:start_child(?MODULE, Args).
-stop_child(Client) ->
- spawn(fun() ->
- ClientSup = whereis(?SSHC_SUP),
- supervisor:terminate_child(ClientSup, Client)
- end),
- ok.
-
%%%=========================================================================
%%% Supervisor callback
%%%=========================================================================