aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Andersson <[email protected]>2012-07-09 20:54:01 +0200
committerPeter Andersson <[email protected]>2012-07-09 20:54:01 +0200
commite13b9c155d266946be86e52ba9344f43ca8640cc (patch)
treedb0c460f2e5760aaa71c8e230286a6e50805a5e9
parentb6ba818603c8a6f0191fa43aa419f44d41a71436 (diff)
downloadotp-e13b9c155d266946be86e52ba9344f43ca8640cc.tar.gz
otp-e13b9c155d266946be86e52ba9344f43ca8640cc.tar.bz2
otp-e13b9c155d266946be86e52ba9344f43ca8640cc.zip
Fix deadlock problem in connection handling
-rw-r--r--lib/common_test/src/ct_gen_conn.erl15
-rw-r--r--lib/common_test/src/ct_ssh.erl20
-rw-r--r--lib/common_test/src/ct_util.erl23
3 files changed, 44 insertions, 14 deletions
diff --git a/lib/common_test/src/ct_gen_conn.erl b/lib/common_test/src/ct_gen_conn.erl
index 5aab4dd2dd..12d5b5b9fd 100644
--- a/lib/common_test/src/ct_gen_conn.erl
+++ b/lib/common_test/src/ct_gen_conn.erl
@@ -27,7 +27,7 @@
-compile(export_all).
-export([start/4, stop/1]).
--export([call/2, do_within_time/2]).
+-export([call/2, call/3, do_within_time/2]).
-ifdef(debug).
-define(dbg,true).
@@ -97,7 +97,7 @@ start(Name,Address,InitData,CallbackMod) ->
%%%
%%% @doc Close the telnet connection and stop the process managing it.
stop(Pid) ->
- call(Pid,stop).
+ call(Pid,stop,5000).
%%%-----------------------------------------------------------------
%%% @spec log(Heading,Format,Args) -> ok
@@ -176,7 +176,10 @@ do_within_time(Fun,Timeout) ->
%%%=================================================================
%%% Internal functions
-call(Pid,Msg) ->
+call(Pid, Msg) ->
+ call(Pid, Msg, infinity).
+
+call(Pid, Msg, Timeout) ->
MRef = erlang:monitor(process,Pid),
Ref = make_ref(),
Pid ! {Msg,{self(),Ref}},
@@ -191,6 +194,12 @@ call(Pid,Msg) ->
end;
{'DOWN',MRef,process,_,Reason} ->
{error,{process_down,Pid,Reason}}
+ after Timeout ->
+ log("ct_gen_conn",
+ "Connection process ~p not responding. Killing now!",
+ [Pid]),
+ exit(Pid, kill),
+ {error,{process_down,Pid,forced_termination}}
end.
return({To,Ref},Result) ->
diff --git a/lib/common_test/src/ct_ssh.erl b/lib/common_test/src/ct_ssh.erl
index 2e8e46d184..09cd4ef02a 100644
--- a/lib/common_test/src/ct_ssh.erl
+++ b/lib/common_test/src/ct_ssh.erl
@@ -235,7 +235,7 @@ connect(KeyOrName, ConnType, ExtraOpts) ->
disconnect(SSH) ->
case get_handle(SSH) of
{ok,Pid} ->
- try_log(heading(disconnect,SSH), "Handle: ~p", [Pid]),
+ try_log(heading(disconnect,SSH), "Handle: ~p", [Pid], 5000),
case ct_gen_conn:stop(Pid) of
{error,{process_down,Pid,noproc}} ->
{error,already_closed};
@@ -1228,11 +1228,11 @@ terminate(SSHRef, State) ->
case State#state.conn_type of
ssh ->
try_log(heading(disconnect_ssh,State#state.target),
- "SSH Ref: ~p",[SSHRef]),
+ "SSH Ref: ~p",[SSHRef], 5000),
ssh:close(SSHRef);
sftp ->
try_log(heading(disconnect_sftp,State#state.target),
- "SFTP Ref: ~p",[SSHRef]),
+ "SFTP Ref: ~p",[SSHRef], 5000),
ssh_sftp:stop_channel(SSHRef)
end.
@@ -1337,9 +1337,12 @@ get_handle(SSH) ->
%%%-----------------------------------------------------------------
%%%
call(SSH, Msg) ->
+ call(SSH, Msg, infinity).
+
+call(SSH, Msg, Timeout) ->
case get_handle(SSH) of
{ok,Pid} ->
- ct_gen_conn:call(Pid, Msg);
+ ct_gen_conn:call(Pid, Msg, Timeout);
Error ->
Error
end.
@@ -1368,11 +1371,16 @@ log(Heading, Str, Args) ->
%%%-----------------------------------------------------------------
%%%
try_log(Heading, Str, Args) ->
- case ct_util:is_silenced(ssh) of
+ try_log(Heading, Str, Args, infinity).
+
+try_log(Heading, Str, Args, Timeout) ->
+ case ct_util:is_silenced(ssh, Timeout) of
true ->
ok;
false ->
- ct_gen_conn:log(Heading, Str, Args)
+ ct_gen_conn:log(Heading, Str, Args);
+ _Error ->
+ ok
end.
%%%-----------------------------------------------------------------
diff --git a/lib/common_test/src/ct_util.erl b/lib/common_test/src/ct_util.erl
index 541921df58..52a2765856 100644
--- a/lib/common_test/src/ct_util.erl
+++ b/lib/common_test/src/ct_util.erl
@@ -36,14 +36,15 @@
save_suite_data_async/3, save_suite_data_async/2,
read_suite_data/1,
delete_suite_data/0, delete_suite_data/1, match_delete_suite_data/1,
- delete_testdata/0, delete_testdata/1, set_testdata/1, get_testdata/1,
+ delete_testdata/0, delete_testdata/1,
+ set_testdata/1, get_testdata/1, get_testdata/2,
set_testdata_async/1, update_testdata/2]).
-export([override_silence_all_connections/0, override_silence_connections/1,
get_overridden_silenced_connections/0,
delete_overridden_silenced_connections/0,
- silence_all_connections/0, silence_connections/1, is_silenced/1,
- reset_silent_connections/0]).
+ silence_all_connections/0, silence_connections/1,
+ is_silenced/1, is_silenced/2, reset_silent_connections/0]).
-export([get_mode/0, create_table/3, read_opts/0]).
@@ -254,6 +255,9 @@ set_testdata_async(TestData) ->
get_testdata(Key) ->
call({get_testdata, Key}).
+get_testdata(Key, Timeout) ->
+ call({get_testdata, Key}, Timeout).
+
set_cwd(Dir) ->
call({set_cwd,Dir}).
@@ -376,7 +380,6 @@ loop(Mode,TestData,StartDir) ->
exit(Reason)
end.
-
close_connections([#conn{handle=Handle,callback=CB}|Conns]) ->
CB:close(Handle),
close_connections(Conns);
@@ -545,7 +548,10 @@ silence_connections(Conns) when is_list(Conns) ->
set_testdata({silent_connections,Conns1}).
is_silenced(Conn) ->
- case get_testdata(silent_connections) of
+ is_silenced(Conn, infinity).
+
+is_silenced(Conn, Timeout) ->
+ case get_testdata(silent_connections, Timeout) of
Conns when is_list(Conns) ->
case lists:keysearch(Conn,1,Conns) of
{value,{Conn,true}} ->
@@ -553,6 +559,8 @@ is_silenced(Conn) ->
_ ->
false
end;
+ Error = {error,_} ->
+ Error;
_ ->
false
end.
@@ -827,6 +835,9 @@ get_profile_data(Profile, Key, StartDir) ->
%%%-----------------------------------------------------------------
%%% Internal functions
call(Msg) ->
+ call(Msg, infinity).
+
+call(Msg, Timeout) ->
case whereis(ct_util_server) of
undefined ->
{error,ct_util_server_not_running};
@@ -840,6 +851,8 @@ call(Msg) ->
Result;
{'DOWN',MRef,process,_,Reason} ->
{error,{ct_util_server_down,Reason}}
+ after
+ Timeout -> {error,timeout}
end
end.