1-module(yes_5).
2-compile(export_all).
3
4?MODULE() ->
5    ok.
6
7do_call(Process, Label, Request, Timeout) ->
8    Node = case Process of
9	       {_S, N} when is_atom(N) ->
10		   N;
11	       _ when is_pid(Process) ->
12		   node(Process)
13	   end,
14    try erlang:monitor(process, Process) of
15	Mref ->
16	    catch erlang:send(Process, {Label, {self(), Mref}, Request},
17			      [noconnect]),
18	    receive
19		{Mref, Reply} ->
20		    erlang:demonitor(Mref, [flush]),
21		    {ok, Reply};
22		{'DOWN', Mref, _, _, noconnection} ->
23		    exit({nodedown, Node});
24		{'DOWN', Mref, _, _, Reason} ->
25		    exit(Reason)
26	    after Timeout ->
27		    erlang:demonitor(Mref, [flush]),
28		    exit(timeout)
29	    end
30    catch
31	error:_ ->
32	    monitor_node(Node, true),
33	    receive
34		{nodedown, Node} ->
35		    monitor_node(Node, false),
36		    exit({nodedown, Node})
37	    after 0 ->
38		    Tag = make_ref(),
39		    Process ! {Label, {self(), Tag}, Request},
40		    ?MODULE:wait_resp(Node, Tag, Timeout)
41	    end
42    end.
43