From 2b3d632e406ba72dfe7a20bd00d1d9463ccdaffc Mon Sep 17 00:00:00 2001 From: AICells <1713699517@qq.com> Date: Sat, 11 Jul 2020 02:11:38 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=20=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/gen_ipc.erl | 175 ++++++++++++------------ src/gen_srv.erl | 349 ++++++++++++++++++++++++++++-------------------- 2 files changed, 294 insertions(+), 230 deletions(-) diff --git a/src/gen_ipc.erl b/src/gen_ipc.erl index 01abe55..aaad9ab 100644 --- a/src/gen_ipc.erl +++ b/src/gen_ipc.erl @@ -484,7 +484,8 @@ system_code_change({CycleData, Module, CurStatus, CurState, IsHib}, _Mod, OldVsn case try Module:code_change(OldVsn, CurStatus, CurState, Extra) catch - throw:Result -> Result + throw:Result -> Result; + _C:_R -> {_R, _R} end of {ok, NewStatus, NewState} -> @@ -527,8 +528,7 @@ call(ServerRef, Request) -> try gen:call(ServerRef, '$gen_call', Request) of {ok, Reply} -> Reply - catch - Class:Reason:Stacktrace -> + catch Class:Reason:Stacktrace -> erlang:raise(Class, {Reason, {?MODULE, call, [ServerRef, Request]}}, Stacktrace) end. @@ -537,16 +537,14 @@ call(ServerRef, Request, infinity) -> try gen:call(ServerRef, '$gen_call', Request, infinity) of {ok, Reply} -> Reply - catch - Class:Reason:Stacktrace -> + catch Class:Reason:Stacktrace -> erlang:raise(Class, {Reason, {?MODULE, call, [ServerRef, Request, infinity]}}, Stacktrace) end; call(ServerRef, Request, {dirty_timeout, T} = Timeout) -> try gen:call(ServerRef, '$gen_call', Request, T) of {ok, Reply} -> Reply - catch - Class:Reason:Stacktrace -> + catch Class:Reason:Stacktrace -> erlang:raise(Class, {Reason, {?MODULE, call, [ServerRef, Request, Timeout]}}, Stacktrace) end; call(ServerRef, Request, {clean_timeout, T} = Timeout) -> @@ -599,7 +597,7 @@ multi_call(Nodes, Name, Request, Timeout) when is_list(Nodes), is_atom(Name), is do_multi_call(Nodes, Name, Request, infinity) -> Tag = make_ref(), - Monitors = send_nodes(Nodes, Name, Tag, Request, []), + Monitors = send_nodes(Nodes, Name, Tag, Request), rec_nodes(Tag, Monitors, Name, undefined); do_multi_call(Nodes, Name, Request, Timeout) -> Tag = make_ref(), @@ -610,7 +608,7 @@ do_multi_call(Nodes, Name, Request, Timeout) -> Mref = erlang:monitor(process, Caller), receive {Caller, Tag} -> - Monitors = send_nodes(Nodes, Name, Tag, Request, []), + Monitors = send_nodes(Nodes, Name, Tag, Request), TimerId = erlang:start_timer(Timeout, self(), ok), Result = rec_nodes(Tag, Monitors, Name, TimerId), exit({self(), Tag, Result}); @@ -628,6 +626,47 @@ do_multi_call(Nodes, Name, Request, Timeout) -> exit(Reason) end. +-spec cast(ServerRef :: serverRef(), Msg :: term()) -> ok. +cast({global, Name}, Msg) -> + try global:send(Name, {'$gen_cast', Msg}), + ok + catch _:_ -> ok + end; +cast({via, RegMod, Name}, Msg) -> + try RegMod:send(Name, {'$gen_cast', Msg}), + ok + catch _:_ -> ok + end; +cast({Name, Node} = Dest, Msg) when is_atom(Name), is_atom(Node) -> + try erlang:send(Dest, {'$gen_cast', Msg}), + ok + catch _:_ -> ok + end; +cast(Dest, Msg) -> + try erlang:send(Dest, {'$gen_cast', Msg}), + ok + catch _:_ -> ok + end. + +%% 异步广播,不返回任何内容,只是发送“ n”祈祷 +abcast(Name, Msg) when is_atom(Name) -> + doAbcast([node() | nodes()], Name, Msg). + +abcast(Nodes, Name, Msg) when is_list(Nodes), is_atom(Name) -> + doAbcast(Nodes, Name, Msg). + +doAbcast(Nodes, Name, Msg) -> + [ + begin + try erlang:send({Name, Node}, {'$gen_cast', Msg}), + ok + catch + _:_ -> ok + end + end || Node <- Nodes + ], + ok. + -spec send_request(ServerRef :: serverRef(), Request :: term()) -> RequestId :: requestId(). send_request(Name, Request) -> gen:send_request(Name, '$gen_call', Request). @@ -650,14 +689,17 @@ wait_response(RequestId, Timeout) -> check_response(Msg, RequestId) -> gen:check_response(Msg, RequestId). -send_nodes([Node | Tail], Name, Tag, Request, Monitors) when is_atom(Node) -> - Monitor = start_monitor(Node, Name), - catch {Name, Node} ! {'$gen_call', {self(), {Tag, Node}}, Request}, - send_nodes(Tail, Name, Tag, Request, [Monitor | Monitors]); -send_nodes([_Node | Tail], Name, Tag, Request, Monitors) -> - send_nodes(Tail, Name, Tag, Request, Monitors); -send_nodes([], _Name, _Tag, _Req, Monitors) -> - Monitors. +send_nodes(Nodes, Name, Tag, Request) -> + [ + begin + Monitor = start_monitor(Node, Name), + try {Name, Node} ! {'$gen_call', {self(), {Tag, Node}}, Request}, + ok + catch _:_ -> ok + end, + Monitor + end || Node <- Nodes, is_atom(Node) + ]. rec_nodes(Tag, Nodes, Name, TimerId) -> rec_nodes(Tag, Nodes, Name, [], [], 2000, TimerId). @@ -756,82 +798,45 @@ start_monitor(Node, Name) when is_atom(Node), is_atom(Name) -> end end. --spec cast(ServerRef :: serverRef(), Msg :: term()) -> ok. -cast({global, Name}, Msg) -> - try global:send(Name, {'$gen_cast', Msg}) of - _ -> ok - catch - _:_ -> ok - end; -cast({via, RegMod, Name}, Msg) -> - try RegMod:send(Name, {'$gen_cast', Msg}) of - _ -> ok - catch - _:_ -> ok - end; -cast({Name, Node} = Dest, Msg) when is_atom(Name), is_atom(Node) -> - try - erlang:send(Dest, {'$gen_cast', Msg}), - ok - catch - error:_ -> ok - end; -cast(Dest, Msg) -> - try - erlang:send(Dest, {'$gen_cast', Msg}), +%% Reply from a status machine callback to whom awaits in call/2 +-spec reply([replyAction(), ...] | replyAction()) -> ok. +reply({reply, {To, Tag}, Reply}) -> + try To ! {Tag, Reply}, ok - catch - error:_ -> ok - end. - -%% 异步广播,不返回任何内容,只是发送“ n”祈祷 -abcast(Name, Msg) when is_atom(Name) -> - doAbcast([node() | nodes()], Name, Msg). - -abcast(Nodes, Name, Msg) when is_list(Nodes), is_atom(Name) -> - doAbcast(Nodes, Name, Msg). - -doAbcast([Node | Nodes], Name, Msg) when is_atom(Node) -> - try - erlang:send({Name, Node}, {'$gen_cast', Msg}), + catch _:_ -> ok - catch - error:_ -> ok - end, - doAbcast(Nodes, Name, Msg); -doAbcast([], _, _) -> abcast. - -%% Reply from a status machine callback to whom awaits in call/2 --spec reply([replyAction()] | replyAction()) -> ok. -reply({reply, From, Reply}) -> - reply(From, Reply); + end; reply(Replies) when is_list(Replies) -> - replies(Replies). - -replies([{reply, From, Reply} | Replies]) -> - reply(From, Reply), - replies(Replies); -replies([]) -> + [ + begin + try To ! {Tag, Reply}, + ok + catch _:_ -> + ok + end + end || {reply, {To, Tag}, Reply} <- Replies + ], ok. -spec reply(From :: from(), Reply :: term()) -> ok. reply({To, Tag}, Reply) -> - catch To ! {Tag, Reply}, - ok. + try To ! {Tag, Reply}, + ok + catch _:_ -> + ok + end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% API helpers end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% gen_event start %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% epmRequest({global, Name}, Msg) -> - try global:send(Name, Msg) of - _ -> ok - catch - _:_ -> ok + try global:send(Name, Msg), + ok + catch _:_ -> ok end; epmRequest({via, RegMod, Name}, Msg) -> - try RegMod:send(Name, Msg) of - _ -> ok - catch - _:_ -> ok + try RegMod:send(Name, Msg), + ok + catch _:_ -> ok end; epmRequest(EpmSrv, Cmd) -> EpmSrv ! Cmd, @@ -849,8 +854,7 @@ epmRpc(EpmSrv, Cmd) -> try gen:call(EpmSrv, '$epm_call', Cmd, infinity) of {ok, Reply} -> Reply - catch - Class:Reason:Stacktrace -> + catch Class:Reason:Stacktrace -> erlang:raise(Class, {Reason, {?MODULE, call, [EpmSrv, Cmd, infinity]}}, Stacktrace) end. @@ -858,8 +862,7 @@ epmRpc(EpmSrv, Cmd, Timeout) -> try gen:call(EpmSrv, '$epm_call', Cmd, Timeout) of {ok, Reply} -> Reply - catch - Class:Reason:Stacktrace -> + catch Class:Reason:Stacktrace -> erlang:raise(Class, {Reason, {?MODULE, call, [EpmSrv, Cmd, Timeout]}}, Stacktrace) end. @@ -2322,9 +2325,9 @@ mod(_) -> "t". format_status(Opt, PDict, _CycleData, Module, CurStatus, CurState) -> case erlang:function_exported(Module, formatStatus, 2) of true -> - try Module:format_status(Opt, [PDict, CurStatus, CurState]) + try Module:formatStatus(Opt, [PDict, CurStatus, CurState]) catch - Result -> Result; + throw:Result -> Result; _:_ -> format_status_default(Opt, {{CurStatus, CurState}, atom_to_list(Module) ++ ":formatStatus/2 crashed"}) end; diff --git a/src/gen_srv.erl b/src/gen_srv.erl index 222a08a..b19f2b1 100644 --- a/src/gen_srv.erl +++ b/src/gen_srv.erl @@ -12,7 +12,7 @@ , stop/1, stop/3 , call/2, call/3 , send_request/2, wait_response/2, check_response/2 - , cast/2, reply/2 + , cast/2, reply/1, reply/2 , abcast/2, abcast/3 , multi_call/2, multi_call/3, multi_call/4 , enter_loop/3, enter_loop/4, enter_loop/5 @@ -60,8 +60,6 @@ | {'global', GlobalName :: term()} | {'via', RegMod :: module(), ViaName :: term()}. --type requestId() :: term(). - -type startOpt() :: {'timeout', Time :: timeout()} | {'spawn_opt', [proc_lib:spawn_option()]} | @@ -90,6 +88,13 @@ -type timeoutOption() :: {abs, Abs :: boolean()}. %% -type timer() :: #{TimeoutName :: atom() => {TimerRef :: reference(), TimeoutMsg :: term()}}. +%% gen:call 发送消息来源进程格式类型 +-type from() :: {To :: pid(), Tag :: term()}. +-type requestId() :: term(). + +-type replyAction() :: + {'reply', From :: from(), Reply :: term()}. + -callback init(Args :: term()) -> {ok, State :: term()} | {ok, State :: term(), action()} | @@ -298,9 +303,15 @@ system_terminate(Reason, _Parent, Debug, [Name, Module, _HibernateAfterTimeout, terminate(exit, Reason, ?STACKTRACE(), Name, Module, CurState, Debug, Timers, []). system_code_change([Name, Module, HibernateAfterTimeout, CurState, Timers, IsHib], _Module, OldVsn, Extra) -> - case catch Module:code_change(OldVsn, CurState, Extra) of + case + try Module:code_change(OldVsn, CurState, Extra) + catch + throw:Result -> Result; + _C:_R -> {_R, _R} + end + of {ok, NewState} -> {ok, [Name, Module, HibernateAfterTimeout, NewState, Timers, IsHib]}; - Else -> Else + Error -> Error end. system_get_state([_Name, _Module, _HibernateAfterTimeout, CurState, _Timers, _IsHib]) -> @@ -318,85 +329,67 @@ system_replace_state(StateFun, [Name, Module, HibernateAfterTimeout, CurState, T %% be monitored. %% If the client is trapping exits and is linked server termination %% is handled here (? Shall we do that here (or rely on timeouts) ?). -%% ----------------------------------------------------------------- -call(Name, Request) -> - case catch gen:call(Name, '$gen_call', Request) of - {ok, Res} -> - Res; - {'EXIT', Reason} -> - exit({Reason, {?MODULE, call, [Name, Request]}}) +-spec call(ServerRef :: serverRef(), Request :: term()) -> Reply :: term(). +call(ServerRef, Request) -> + try gen:call(ServerRef, '$gen_call', Request) of + {ok, Reply} -> + Reply + catch Class:Reason:Stacktrace -> + erlang:raise(Class, {Reason, {?MODULE, call, [ServerRef, Request]}}, Stacktrace) end. -call(Name, Request, Timeout) -> - case catch gen:call(Name, '$gen_call', Request, Timeout) of - {ok, Res} -> - Res; - {'EXIT', Reason} -> - exit({Reason, {?MODULE, call, [Name, Request, Timeout]}}) +-spec call(ServerRef :: serverRef(), Request :: term(), Timeout :: timeout() |{'clean_timeout', T :: timeout()} | {'dirty_timeout', T :: timeout()}) -> Reply :: term(). +call(ServerRef, Request, infinity) -> + try gen:call(ServerRef, '$gen_call', Request, infinity) of + {ok, Reply} -> + Reply + catch Class:Reason:Stacktrace -> + erlang:raise(Class, {Reason, {?MODULE, call, [ServerRef, Request, infinity]}}, Stacktrace) + end; +call(ServerRef, Request, {dirty_timeout, T} = Timeout) -> + try gen:call(ServerRef, '$gen_call', Request, T) of + {ok, Reply} -> + Reply + catch Class:Reason:Stacktrace -> + erlang:raise(Class, {Reason, {?MODULE, call, [ServerRef, Request, Timeout]}}, Stacktrace) + end; +call(ServerRef, Request, {clean_timeout, T} = Timeout) -> + callClean(ServerRef, Request, Timeout, T); +call(ServerRef, Request, {_, _} = Timeout) -> + erlang:error(badarg, [ServerRef, Request, Timeout]); +call(ServerRef, Request, Timeout) -> + callClean(ServerRef, Request, Timeout, Timeout). + +callClean(ServerRef, Request, Timeout, T) -> + %% 通过代理过程呼叫服务器以躲避任何较晚的答复 + Ref = make_ref(), + Self = self(), + Pid = spawn( + fun() -> + Self ! + try gen:call(ServerRef, '$gen_call', Request, T) of + Result -> + {Ref, Result} + catch Class:Reason:Stacktrace -> + {Ref, Class, Reason, Stacktrace} + end + end), + Mref = monitor(process, Pid), + receive + {Ref, Result} -> + demonitor(Mref, [flush]), + case Result of + {ok, Reply} -> + Reply + end; + {Ref, Class, Reason, Stacktrace} -> + demonitor(Mref, [flush]), + erlang:raise(Class, {Reason, {?MODULE, call, [ServerRef, Request, Timeout]}}, Stacktrace); + {'DOWN', Mref, _, _, Reason} -> + %% 从理论上讲,有可能在try-of和!之间杀死代理进程。因此,在这种情况下 + exit(Reason) end. -%% ----------------------------------------------------------------- -%% Send a request to a generic server and return a Key which should be -%% used with wait_response/2 or check_response/2 to fetch the -%% result of the request. - --spec send_request(Name :: serverRef(), Request :: term()) -> requestId(). -send_request(Name, Request) -> - gen:send_request(Name, '$gen_call', Request). - --spec wait_response(RequestId :: requestId(), timeout()) -> - {reply, Reply :: term()} | 'timeout' | {error, {Reason :: term(), serverRef()}}. -wait_response(RequestId, Timeout) -> - gen:wait_response(RequestId, Timeout). - --spec check_response(Msg :: term(), RequestId :: requestId()) -> - {reply, Reply :: term()} | 'no_reply' | {error, {Reason :: term(), serverRef()}}. -check_response(Msg, RequestId) -> - gen:check_response(Msg, RequestId). - -%% ----------------------------------------------------------------- -%% Make a cast to a generic server. -%% ----------------------------------------------------------------- -cast({global, Name}, Request) -> - catch global:send(Name, cast_msg(Request)), - ok; -cast({via, Module, Name}, Request) -> - catch Module:send(Name, cast_msg(Request)), - ok; -cast({Name, Node} = Dest, Request) when is_atom(Name), is_atom(Node) -> - do_cast(Dest, Request); -cast(Dest, Request) when is_atom(Dest) -> - do_cast(Dest, Request); -cast(Dest, Request) when is_pid(Dest) -> - do_cast(Dest, Request). - -do_cast(Dest, Request) -> - do_send(Dest, cast_msg(Request)), - ok. - -cast_msg(Request) -> {'$gen_cast', Request}. - -%% ----------------------------------------------------------------- -%% Send a reply to the client. -%% ----------------------------------------------------------------- -reply({To, Tag}, Reply) -> - catch To ! {Tag, Reply}, - ok. - -%% ----------------------------------------------------------------- -%% Asynchronous broadcast, returns nothing, it's just send 'n' pray -%%----------------------------------------------------------------- -abcast(Name, Request) when is_atom(Name) -> - do_abcast([node() | nodes()], Name, cast_msg(Request)). - -abcast(Nodes, Name, Request) when is_list(Nodes), is_atom(Name) -> - do_abcast(Nodes, Name, cast_msg(Request)). - -do_abcast([Node | Nodes], Name, Msg) when is_atom(Node) -> - do_send({Name, Node}, Msg), - do_abcast(Nodes, Name, Msg); -do_abcast([], _, _) -> abcast. - %%% ----------------------------------------------------------------- %%% Make a call to servers at several nodes. %%% Returns: {[Replies],[BadNodes]} @@ -407,83 +400,151 @@ do_abcast([], _, _) -> abcast. %%% queue, it would probably become confused. Late answers will %%% now arrive to the terminated middleman and so be discarded. %%% ----------------------------------------------------------------- -multi_call(Name, Req) - when is_atom(Name) -> - do_multi_call([node() | nodes()], Name, Req, infinity). -multi_call(Nodes, Name, Req) - when is_list(Nodes), is_atom(Name) -> - do_multi_call(Nodes, Name, Req, infinity). +multi_call(Name, Request) when is_atom(Name) -> + do_multi_call([node() | nodes()], Name, Request, infinity). -multi_call(Nodes, Name, Req, infinity) -> - do_multi_call(Nodes, Name, Req, infinity); -multi_call(Nodes, Name, Req, Timeout) - when is_list(Nodes), is_atom(Name), is_integer(Timeout), Timeout >= 0 -> - do_multi_call(Nodes, Name, Req, Timeout). +multi_call(Nodes, Name, Request) when is_list(Nodes), is_atom(Name) -> + do_multi_call(Nodes, Name, Request, infinity). -%%% --------------------------------------------------- -%%% Send/receive functions -%%% --------------------------------------------------- -do_send(Dest, Msg) -> - try erlang:send(Dest, Msg) - catch - error:_ -> ok - end, - ok. +multi_call(Nodes, Name, Request, infinity) -> + do_multi_call(Nodes, Name, Request, infinity); +multi_call(Nodes, Name, Request, Timeout) when is_list(Nodes), is_atom(Name), is_integer(Timeout), Timeout >= 0 -> + do_multi_call(Nodes, Name, Request, Timeout). -do_multi_call(Nodes, Name, Req, infinity) -> +do_multi_call(Nodes, Name, Request, infinity) -> Tag = make_ref(), - Monitors = send_nodes(Nodes, Name, Tag, Req), + Monitors = send_nodes(Nodes, Name, Tag, Request), rec_nodes(Tag, Monitors, Name, undefined); -do_multi_call(Nodes, Name, Req, Timeout) -> +do_multi_call(Nodes, Name, Request, Timeout) -> Tag = make_ref(), Caller = self(), - Receiver = - spawn( - fun() -> - %% Middleman process. Should be unsensitive to regular - %% exit signals. The sychronization is needed in case - %% the receiver would exit before the caller started - %% the monitor. - process_flag(trap_exit, true), - Mref = erlang:monitor(process, Caller), - receive - {Caller, Tag} -> - Monitors = send_nodes(Nodes, Name, Tag, Req), - TimerId = erlang:start_timer(Timeout, self(), ok), - Result = rec_nodes(Tag, Monitors, Name, TimerId), - exit({self(), Tag, Result}); - {'DOWN', Mref, _, _, _} -> - %% Caller died before sending us the go-ahead. - %% Give up silently. - exit(normal) - end - end), + Receiver = spawn( + fun() -> + process_flag(trap_exit, true), + Mref = erlang:monitor(process, Caller), + receive + {Caller, Tag} -> + Monitors = send_nodes(Nodes, Name, Tag, Request), + TimerId = erlang:start_timer(Timeout, self(), ok), + Result = rec_nodes(Tag, Monitors, Name, TimerId), + exit({self(), Tag, Result}); + {'DOWN', Mref, _, _, _} -> + exit(normal) + end + end + ), Mref = erlang:monitor(process, Receiver), Receiver ! {self(), Tag}, receive {'DOWN', Mref, _, _, {Receiver, Tag, Result}} -> Result; {'DOWN', Mref, _, _, Reason} -> - %% The middleman code failed. Or someone did - %% exit(_, kill) on the middleman process => Reason==killed exit(Reason) end. -send_nodes(Nodes, Name, Tag, Req) -> - send_nodes(Nodes, Name, Tag, Req, []). - -send_nodes([Node | Tail], Name, Tag, Req, Monitors) - when is_atom(Node) -> - Monitor = start_monitor(Node, Name), - %% Handle non-existing names in rec_nodes. - catch {Name, Node} ! {'$gen_call', {self(), {Tag, Node}}, Req}, - send_nodes(Tail, Name, Tag, Req, [Monitor | Monitors]); -send_nodes([_Node | Tail], Name, Tag, Req, Monitors) -> - %% Skip non-atom Node - send_nodes(Tail, Name, Tag, Req, Monitors); -send_nodes([], _Name, _Tag, _Req, Monitors) -> - Monitors. +-spec cast(ServerRef :: serverRef(), Msg :: term()) -> ok. +cast({global, Name}, Msg) -> + try global:send(Name, {'$gen_cast', Msg}), + ok + catch _:_ -> ok + end; +cast({via, RegMod, Name}, Msg) -> + try RegMod:send(Name, {'$gen_cast', Msg}), + ok + catch _:_ -> ok + end; +cast({Name, Node} = Dest, Msg) when is_atom(Name), is_atom(Node) -> + try erlang:send(Dest, {'$gen_cast', Msg}), + ok + catch _:_ -> ok + end; +cast(Dest, Msg) -> + try erlang:send(Dest, {'$gen_cast', Msg}), + ok + catch _:_ -> ok + end. + +%% 异步广播,不返回任何内容,只是发送“ n”祈祷 +abcast(Name, Msg) when is_atom(Name) -> + doAbcast([node() | nodes()], Name, Msg). + +abcast(Nodes, Name, Msg) when is_list(Nodes), is_atom(Name) -> + doAbcast(Nodes, Name, Msg). + +doAbcast(Nodes, Name, Msg) -> + [ + begin + try erlang:send({Name, Node}, {'$gen_cast', Msg}), + ok + catch + _:_ -> ok + end + end || Node <- Nodes + ], + ok. + +%% ----------------------------------------------------------------- +%% Send a reply to the client. +%% ----------------------------------------------------------------- +%% Reply from a status machine callback to whom awaits in call/2 +-spec reply([replyAction(), ...] | replyAction()) -> ok. +reply({reply, {To, Tag}, Reply}) -> + try To ! {Tag, Reply}, + ok + catch _:_ -> + ok + end; +reply(Replies) when is_list(Replies) -> + [ + begin + try To ! {Tag, Reply}, + ok + catch _:_ -> + ok + end + end || {reply, {To, Tag}, Reply} <- Replies + ], + ok. + +-spec reply(From :: from(), Reply :: term()) -> ok. +reply({To, Tag}, Reply) -> + try To ! {Tag, Reply}, + ok + catch _:_ -> + ok + end. + +%% ----------------------------------------------------------------- +%% Send a request to a generic server and return a Key which should be +%% used with wait_response/2 or check_response/2 to fetch the +%% result of the request. + +-spec send_request(Name :: serverRef(), Request :: term()) -> requestId(). +send_request(Name, Request) -> + gen:send_request(Name, '$gen_call', Request). + +-spec wait_response(RequestId :: requestId(), timeout()) -> + {reply, Reply :: term()} | 'timeout' | {error, {Reason :: term(), serverRef()}}. +wait_response(RequestId, Timeout) -> + gen:wait_response(RequestId, Timeout). + +-spec check_response(Msg :: term(), RequestId :: requestId()) -> + {reply, Reply :: term()} | 'no_reply' | {error, {Reason :: term(), serverRef()}}. +check_response(Msg, RequestId) -> + gen:check_response(Msg, RequestId). + +send_nodes(Nodes, Name, Tag, Request) -> + [ + begin + Monitor = start_monitor(Node, Name), + try {Name, Node} ! {'$gen_call', {self(), {Tag, Node}}, Request}, + ok + catch _:_ -> ok + end, + Monitor + end || Node <- Nodes, is_atom(Node) + ]. %% Against old nodes: %% If no reply has been delivered within 2 secs. (per node) check that @@ -807,10 +868,10 @@ listify(Item) when is_list(Item) -> listify(Item) -> [Item]. -listHib(true) -> - [hibernate]; +listHib(false) -> + []; listHib(_) -> - []. +[hibernate]. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% timer deal end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1172,7 +1233,7 @@ format_status(Opt, Module, PDict, State) -> end, case erlang:function_exported(Module, format_status, 2) of true -> - case catch Module:format_status(Opt, [PDict, State]) of + case catch Module:formatStatus(Opt, [PDict, State]) of {'EXIT', _} -> DefStatus; Else -> Else end;