Переглянути джерело

ft: gen_emm 修改

master
SisMaker 4 роки тому
джерело
коміт
53297dbc69
1 змінених файлів з 99 додано та 80 видалено
  1. +99
    -80
      src/gen_emm.erl

+ 99
- 80
src/gen_emm.erl Переглянути файл

@ -11,10 +11,12 @@
, start_monitor/0, start_monitor/1, start_monitor/2
, stop/1, stop/3
, call/3, call/4
, epm_info/3
, send_request/3, wait_response/2, check_response/2
, info_notify/2, call_notify/2
, add_epm/3, add_sup_epm/3, del_epm/3
, swap_epm/3, swap_sup_epm/3, which_epm/1
, swap_epm/3, swap_sup_epm/3
, which_epm/1
%% gen callbacks
, init_it/6
@ -34,6 +36,15 @@
, format_log/1, format_log/2
]).
%% debug
-define(NOT_DEBUG, []).
-define(SYS_DEBUG(Debug, Name, Msg),
case Debug of
?NOT_DEBUG ->
Debug;
_ ->
sys:handle_debug(Debug, fun print_event/3, Name, Msg)
end).
-export_type([handler/0, handler_args/0, add_handler_ret/0,
del_handler_ret/0]).
@ -153,73 +164,104 @@
start() ->
gen:start(?MODULE, nolink, ?MODULE, [], []).
-spec start(serverName() | [startOpt()]) -> startRet().
start(Name) when is_tuple(Name) ->
gen:start(?MODULE, nolink, Name, ?MODULE, [], []);
start(Options) when is_list(Options) ->
gen:start(?MODULE, nolink, ?MODULE, [], Options).
-spec start(ServerName :: serverName() | [startOpt()]) -> startRet().
start(ServerName) when is_tuple(ServerName) ->
gen:start(?MODULE, nolink, ServerName, ?MODULE, [], []);
start(Opts) when is_list(Opts) ->
gen:start(?MODULE, nolink, ?MODULE, [], Opts).
-spec start(serverName(), [startOpt()]) -> startRet().
start(Name, Options) ->
gen:start(?MODULE, nolink, Name, ?MODULE, [], Options).
-spec start(ServerName :: serverName(), Opts :: [startOpt()]) -> startRet().
start(ServerName, Opts) ->
gen:start(?MODULE, nolink, ServerName, ?MODULE, [], Opts).
-spec start_link() -> startRet().
start_link() ->
gen:start(?MODULE, link, ?MODULE, [], []).
-spec start_link(serverName() | [startOpt()]) -> startRet().
start_link(Name) when is_tuple(Name) ->
gen:start(?MODULE, link, Name, ?MODULE, [], []);
start_link(Options) when is_list(Options) ->
gen:start(?MODULE, link, ?MODULE, [], Options).
-spec start_link(ServerName :: serverName() | Opts :: [startOpt()]) -> startRet().
start_link(ServerName) when is_tuple(ServerName) ->
gen:start(?MODULE, link, ServerName, ?MODULE, [], []);
start_link(Opts) when is_list(Opts) ->
gen:start(?MODULE, link, ?MODULE, [], Opts).
-spec start_link(serverName(), [startOpt()]) -> startRet().
start_link(Name, Options) ->
gen:start(?MODULE, link, Name, ?MODULE, [], Options).
-spec start_link(ServerName :: serverName(), Opts :: [startOpt()]) -> startRet().
start_link(ServerName, Opts) ->
gen:start(?MODULE, link, ServerName, ?MODULE, [], Opts).
-spec start_monitor() -> startRet().
start_monitor() ->
gen:start(?MODULE, monitor, ?MODULE, [], []).
-spec start_monitor(serverName() | [startOpt()]) -> startRet().
start_monitor(Name) when is_tuple(Name) ->
gen:start(?MODULE, monitor, Name, ?MODULE, [], []);
start_monitor(Options) when is_list(Options) ->
gen:start(?MODULE, monitor, ?MODULE, [], Options).
-spec start_monitor(ServerName :: serverName() | [startOpt()]) -> startRet().
start_monitor(ServerName) when is_tuple(ServerName) ->
gen:start(?MODULE, monitor, ServerName, ?MODULE, [], []);
start_monitor(Opts) when is_list(Opts) ->
gen:start(?MODULE, monitor, ?MODULE, [], Opts).
-spec start_monitor(ServerName :: serverName(), Opts :: [startOpt()]) -> startRet().
start_monitor(ServerName, Opts) ->
gen:start(?MODULE, monitor, ServerName, ?MODULE, [], Opts).
-spec stop(ServerRef :: serverRef()) -> 'ok'.
stop(ServerRef) ->
gen:stop(ServerRef).
-spec start_monitor(serverName(), [startOpt()]) -> startRet().
start_monitor(Name, Options) ->
gen:start(?MODULE, monitor, Name, ?MODULE, [], Options).
-spec stop(ServerRef :: serverRef(), Reason :: term(), Timeout :: timeout()) -> ok.
stop(ServerRef, Reason, Timeout) ->
gen:stop(ServerRef, Reason, Timeout).
%% -spec init_it(pid(), 'self' | pid(), emgr_name(), module(), [term()], [_]) ->
init_it(Starter, self, Name, Mod, Args, Options) ->
init_it(Starter, self(), Name, Mod, Args, Options);
init_it(Starter, Parent, Name0, _, _, Options) ->
init_it(Starter, self, ServerRef, Mod, Args, Options) ->
init_it(Starter, self(), ServerRef, Mod, Args, Options);
init_it(Starter, Parent, ServerRef, _, _, Options) ->
process_flag(trap_exit, true),
Name = gen:name(Name0),
Name = gen:name(ServerRef),
Debug = gen:debug_options(Name, Options),
HibernateAfterTimeout = gen:hibernate_after(Options),
proc_lib:init_ack(Starter, {ok, self()}),
loop(Parent, Name, [], HibernateAfterTimeout, Debug, false).
receiveIng(Parent, Name, [], HibernateAfterTimeout, Debug, false).
-spec add_epm(serverRef(), handler(), term()) -> term().
add_epm(M, Handler, Args) -> rpc(M, {add_handler, Handler, Args}).
add_epm(M, Handler, Args) ->
rpc(M, {add_handler, Handler, Args}).
-spec add_sup_epm(serverRef(), handler(), term()) -> term().
add_sup_epm(M, Handler, Args) ->
rpc(M, {add_sup_handler, Handler, Args, self()}).
-spec del_epm(serverRef(), handler(), term()) -> term().
del_epm(M, Handler, Args) -> rpc(M, {delete_handler, Handler, Args}).
-spec swap_epm(serverRef(), {handler(), term()}, {handler(), term()}) ->
'ok' | {'error', term()}.
swap_epm(M, {H1, A1}, {H2, A2}) -> rpc(M, {swap_handler, H1, A1, H2, A2}).
-spec swap_sup_epm(serverRef(), {handler(), term()}, {handler(), term()}) ->
'ok' | {'error', term()}.
swap_sup_epm(M, {H1, A1}, {H2, A2}) ->
rpc(M, {swap_sup_handler, H1, A1, H2, A2, self()}).
-spec which_epm(serverRef()) -> [handler()].
which_epm(M) -> rpc(M, which_handlers).
-spec info_notify(serverRef(), term()) -> 'ok'.
info_notify(M, Event) -> send(M, {notify, Event}).
info_notify(M, Event) ->
send(M, {notify, Event}).
-spec call_notify(serverRef(), term()) -> 'ok'.
call_notify(M, Event) -> rpc(M, {sync_notify, Event}).
call_notify(M, Event) ->
rpc(M, {sync_notify, Event}).
-spec call(serverRef(), handler(), term()) -> term().
call(M, Handler, Query) -> call1(M, Handler, Query).
call(M, Handler, Query) ->
call1(M, Handler, Query).
-spec call(serverRef(), handler(), term(), timeout()) -> term().
call(M, Handler, Query, Timeout) -> call1(M, Handler, Query, Timeout).
call(M, Handler, Query, Timeout) ->
call1(M, Handler, Query, Timeout).
epm_info(M, Handler, Query) ->
call1(M, Handler, Query).
-spec send_request(serverRef(), handler(), term()) -> request_id().
send_request(M, Handler, Query) ->
@ -241,28 +283,6 @@ check_response(Msg, RequestId) ->
Return -> Return
end.
-spec del_epm(serverRef(), handler(), term()) -> term().
del_epm(M, Handler, Args) -> rpc(M, {delete_handler, Handler, Args}).
-spec swap_epm(serverRef(), {handler(), term()}, {handler(), term()}) ->
'ok' | {'error', term()}.
swap_epm(M, {H1, A1}, {H2, A2}) -> rpc(M, {swap_handler, H1, A1, H2, A2}).
-spec swap_sup_epm(serverRef(), {handler(), term()}, {handler(), term()}) ->
'ok' | {'error', term()}.
swap_sup_epm(M, {H1, A1}, {H2, A2}) ->
rpc(M, {swap_sup_handler, H1, A1, H2, A2, self()}).
-spec which_epm(serverRef()) -> [handler()].
which_epm(M) -> rpc(M, which_handlers).
-spec stop(serverRef()) -> 'ok'.
stop(M) ->
gen:stop(M).
stop(M, Reason, Timeout) ->
gen:stop(M, Reason, Timeout).
rpc(M, Cmd) ->
{ok, Reply} = gen:call(M, self(), Cmd, infinity),
Reply.
@ -297,83 +317,82 @@ send(M, Cmd) ->
M ! Cmd,
ok.
loop(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, true) ->
loopEntry(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, true) ->
proc_lib:hibernate(?MODULE, wake_hib, [Parent, ServerName, MSL, HibernateAfterTimeout, Debug]);
loop(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, _) ->
fetch_msg(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, false).
loopEntry(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, _) ->
receiveIng(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, false).
wakeupFromHib(Parent, ServerName, MSL, HibernateAfterTimeout, Debug) ->
fetch_msg(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, true).
receiveIng(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, true).
fetch_msg(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, Hib) ->
receiveIng(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, IsHib) ->
receive
{system, From, Req} ->
sys:handle_system_msg(Req, From, Parent, ?MODULE, Debug,
[ServerName, MSL, HibernateAfterTimeout, Hib], Hib);
sys:handle_system_msg(Req, From, Parent, ?MODULE, Debug, [ServerName, MSL, HibernateAfterTimeout, IsHib], IsHib);
{'EXIT', Parent, Reason} ->
terminate_server(Reason, Parent, MSL, ServerName);
Msg when Debug =:= [] ->
handle_msg(Msg, Parent, ServerName, MSL, HibernateAfterTimeout, []);
Msg ->
Debug1 = sys:handle_debug(Debug, fun print_event/3,
ServerName, {in, Msg}),
Debug1 = sys:handle_debug(Debug, fun print_event/3, ServerName, {in, Msg}),
handle_msg(Msg, Parent, ServerName, MSL, HibernateAfterTimeout, Debug1)
after HibernateAfterTimeout ->
loop(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, true)
proc_lib:hibernate(?MODULE, wakeupFromHib, [Parent, ServerName, MSL, HibernateAfterTimeout, Debug])
end.
handle_msg(Msg, Parent, ServerName, MSL, HibernateAfterTimeout, Debug) ->
NewDebug = ?SYS_DEBUG(Debug, ServerName, {in, Msg}),
case Msg of
{notify, Event} ->
{Hib, MSL1} = server_notify(Event, handle_event, MSL, ServerName),
loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, Hib);
loopEntry(Parent, ServerName, MSL1, HibernateAfterTimeout, NewDebug, Hib);
{_From, Tag, {sync_notify, Event}} ->
{Hib, MSL1} = server_notify(Event, handle_event, MSL, ServerName),
reply(Tag, ok),
loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, Hib);
loopEntry(Parent, ServerName, MSL1, HibernateAfterTimeout, NewDebug, Hib);
{'EXIT', From, Reason} ->
MSL1 = handle_exit(From, Reason, MSL, ServerName),
loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, false);
loopEntry(Parent, ServerName, MSL1, HibernateAfterTimeout, NewDebug, false);
{_From, Tag, {call, Handler, Query}} ->
{Hib, Reply, MSL1} = server_call(Handler, Query, MSL, ServerName),
reply(Tag, Reply),
loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, Hib);
loopEntry(Parent, ServerName, MSL1, HibernateAfterTimeout, NewDebug, Hib);
{_From, Tag, {add_handler, Handler, Args}} ->
{Hib, Reply, MSL1} = server_add_handler(Handler, Args, MSL),
reply(Tag, Reply),
loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, Hib);
loopEntry(Parent, ServerName, MSL1, HibernateAfterTimeout, NewDebug, Hib);
{_From, Tag, {add_sup_handler, Handler, Args, SupP}} ->
{Hib, Reply, MSL1} = server_add_sup_handler(Handler, Args, MSL, SupP),
reply(Tag, Reply),
loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, Hib);
loopEntry(Parent, ServerName, MSL1, HibernateAfterTimeout, NewDebug, Hib);
{_From, Tag, {delete_handler, Handler, Args}} ->
{Reply, MSL1} = server_delete_handler(Handler, Args, MSL,
ServerName),
reply(Tag, Reply),
loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, false);
loopEntry(Parent, ServerName, MSL1, HibernateAfterTimeout, NewDebug, false);
{_From, Tag, {swap_handler, Handler1, Args1, Handler2, Args2}} ->
{Hib, Reply, MSL1} = server_swap_handler(Handler1, Args1, Handler2,
Args2, MSL, ServerName),
reply(Tag, Reply),
loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, Hib);
loopEntry(Parent, ServerName, MSL1, HibernateAfterTimeout, NewDebug, Hib);
{_From, Tag, {swap_sup_handler, Handler1, Args1, Handler2, Args2,
Sup}} ->
{Hib, Reply, MSL1} = server_swap_handler(Handler1, Args1, Handler2,
Args2, MSL, Sup, ServerName),
reply(Tag, Reply),
loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, Hib);
loopEntry(Parent, ServerName, MSL1, HibernateAfterTimeout, NewDebug, Hib);
{_From, Tag, stop} ->
catch terminate_server(normal, Parent, MSL, ServerName),
reply(Tag, ok);
{_From, Tag, which_handlers} ->
reply(Tag, the_handlers(MSL)),
loop(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, false);
loopEntry(Parent, ServerName, MSL, HibernateAfterTimeout, NewDebug, false);
{_From, Tag, get_modules} ->
reply(Tag, get_modules(MSL)),
loop(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, false);
loopEntry(Parent, ServerName, MSL, HibernateAfterTimeout, NewDebug, false);
Other ->
{Hib, MSL1} = server_notify(Other, handle_info, MSL, ServerName),
loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, Hib)
loopEntry(Parent, ServerName, MSL1, HibernateAfterTimeout, NewDebug, Hib)
end.
terminate_server(Reason, Parent, MSL, ServerName) ->
@ -428,7 +447,7 @@ terminate_supervised(Pid, Reason, MSL, SName) ->
%% Callback functions for system messages handling.
%%-----------------------------------------------------------------
system_continue(Parent, Debug, [ServerName, MSL, HibernateAfterTimeout, Hib]) ->
loop(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, Hib).
loopEntry(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, Hib).
-spec system_terminate(_, _, _, [_]) -> no_return().
system_terminate(Reason, Parent, _Debug, [ServerName, MSL, _HibernateAfterTimeout, _Hib]) ->

Завантаження…
Відмінити
Зберегти