|
|
@ -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]) -> |
|
|
|