From f0010583fd53174b72341d64be3a481cccc4623c Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Fri, 26 Oct 2012 16:07:36 +0200 Subject: [cover] Don't kill remote nodes when connection to main node is lost OTP-10523 Since the will probably be cover compiled modules left in the remote node, we want to keep the cover_server and it's ets tables even if connection to remote node is lost. This way it will not crash (due to ets:insert in non existing table) if functions in cover compiled modules are executed. --- lib/tools/src/cover.erl | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) (limited to 'lib/tools/src') diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl index fb65206938..2154a21ed6 100644 --- a/lib/tools/src/cover.erl +++ b/lib/tools/src/cover.erl @@ -555,7 +555,10 @@ remote_call(Node,Request) -> Return = receive {'DOWN', Ref, _Type, _Object, _Info} -> - {error,node_dead}; + case Request of + {remote,stop} -> ok; + _ -> {error,node_dead} + end; {?SERVER,Reply} -> Reply end, @@ -583,7 +586,6 @@ init_main(Starter) -> ets:new(?BINARY_TABLE, [set, named_table]), ets:new(?COLLECTION_TABLE, [set, public, named_table]), ets:new(?COLLECTION_CLAUSE_TABLE, [set, public, named_table]), - process_flag(trap_exit,true), Starter ! {?SERVER,started}, main_process_loop(#main_state{}). @@ -595,8 +597,8 @@ main_process_loop(State) -> lists:foldl( fun(Node,Acc) -> case rpc:call(Node,cover,remote_start,[ThisNode]) of - {ok,RPid} -> - link(RPid), + {ok,_RPid} -> + erlang:monitor(process,{?SERVER,Node}), [Node|Acc]; Error -> io:format("Could not start cover on ~w: ~p\n", @@ -721,8 +723,8 @@ main_process_loop(State) -> {From, {stop,Nodes}} -> remote_collect('_',Nodes,true), reply(From, ok), - State1 = State#main_state{nodes=State#main_state.nodes--Nodes}, - main_process_loop(State1); + Nodes1 = State#main_state.nodes--Nodes, + main_process_loop(State#main_state{nodes=Nodes1}); {From, {flush,Nodes}} -> remote_collect('_',Nodes,false), @@ -807,13 +809,10 @@ main_process_loop(State) -> end, main_process_loop(S); - {'EXIT',Pid,_Reason} -> - %% Exit is trapped on the main node only, so this will only happen - %% there. I assume that I'm only linked to cover_servers on remote - %% nodes, so this must be one of them crashing. - %% Remove node from list! - State1 = State#main_state{nodes=State#main_state.nodes--[node(Pid)]}, - main_process_loop(State1); + {'DOWN', _MRef, process, {?SERVER,Node}, _Info} -> + %% A remote cover_server is down, remove node from list. + Nodes1 = State#main_state.nodes--[Node], + main_process_loop(State#main_state{nodes=Nodes1}); {From, get_main_node} -> reply(From, node()), @@ -873,7 +872,7 @@ remote_process_loop(State) -> {remote,stop} -> reload_originals(State#remote_state.compiled), unregister(?SERVER), - remote_reply(State#remote_state.main_node, ok); + ok; % not replying since 'DOWN' message will be received anyway {From, get_main_node} -> reply(From, State#remote_state.main_node), @@ -1121,7 +1120,6 @@ remove_myself([Node|Nodes],Acc) -> remove_myself(Nodes,[Node|Acc]); remove_myself([],Acc) -> Acc. - %%%--Handling of modules state data-------------------------------------- @@ -2334,7 +2332,7 @@ pmap(Fun, [E | Rest], Pids, Limit, Cnt, Acc) when Cnt < Limit -> pmap(Fun, Rest, Pids ++ [Pid], Limit, Cnt + 1, Acc); pmap(Fun, List, [Pid | Pids], Limit, Cnt, Acc) -> receive - {'DOWN', _Ref, process, _, _} -> + {'DOWN', _Ref, process, X, _} when is_pid(X) -> pmap(Fun, List, [Pid | Pids], Limit, Cnt - 1, Acc); {res, Pid, Res} -> pmap(Fun, List, Pids, Limit, Cnt, [Res | Acc]) @@ -2343,6 +2341,6 @@ pmap(_Fun, [], [], _Limit, 0, Acc) -> lists:reverse(Acc); pmap(Fun, [], [], Limit, Cnt, Acc) -> receive - {'DOWN', _Ref, process, _, _} -> + {'DOWN', _Ref, process, X, _} when is_pid(X) -> pmap(Fun, [], [], Limit, Cnt - 1, Acc) end. -- cgit v1.2.3