From e13b9c155d266946be86e52ba9344f43ca8640cc Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Mon, 9 Jul 2012 20:54:01 +0200 Subject: Fix deadlock problem in connection handling --- lib/common_test/src/ct_gen_conn.erl | 15 ++++++++++++--- lib/common_test/src/ct_ssh.erl | 20 ++++++++++++++------ lib/common_test/src/ct_util.erl | 23 ++++++++++++++++++----- 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. -- cgit v1.2.3