diff --git a/src/gen_ipc.erl b/src/gen_ipc.erl index d497d14..af369f6 100644 --- a/src/gen_ipc.erl +++ b/src/gen_ipc.erl @@ -42,7 +42,7 @@ , format_status/2 %% Internal callbacks - , wakeupFromHib/11 + , wakeupFromHib/12 %% logger callback , format_log/1 , format_log/2 @@ -235,6 +235,10 @@ -callback handleInfo(EventContent :: term(), Status :: term(), State :: term()) -> eventCallbackResult(). +%% error 回调函数 守护模式下 进程捕捉到错误可以回调次函数 +-callback handleError(Error :: term(), State :: term()) -> + eventCallbackResult(). + %% 内部事件 Onevent 包括actions 设置的定时器超时产生的事件 和 nextE产生的超时事件 但是不是 call cast info 回调函数 以及其他自定义定时事件 的回调函数 %% 并且这里需要注意 其他erlang:start_timer生成超时事件发送的消息 不能和gen_ipc定时器关键字重合 有可能会导致一些问题 -callback handleOnevent(EventType :: term(), EventContent :: term(), Status :: term(), State :: term()) -> @@ -278,6 +282,7 @@ , code_change/4 , handleEnter/3 , handleAfter/3 + , handleError/2 , handleOnevent/4 , handleEpmEvent/3 , handleEpmCall/3 @@ -369,17 +374,18 @@ init_it(Starter, self, ServerRef, Module, Args, Opts) -> init_it(Starter, Parent, ServerRef, Module, Args, Opts) -> Name = gen:name(ServerRef), Debug = gen:debug_options(Name, Opts), + GbhOpts = #gbhOpts{daemon = lists:member(daemon, Opts)}, HibernateAfterTimeout = gen:hibernate_after(Opts), case doModuleInit(Module, Args) of {ok, State} -> proc_lib:init_ack(Starter, {ok, self()}), - loopEntry(Parent, Debug, Module, Name, HibernateAfterTimeout, undefined, State, []); + loopEntry(Parent, Debug, Module, Name, GbhOpts, HibernateAfterTimeout, undefined, State, []); {ok, Status, State} -> proc_lib:init_ack(Starter, {ok, self()}), - loopEntry(Parent, Debug, Module, Name, HibernateAfterTimeout, Status, State, []); + loopEntry(Parent, Debug, Module, Name, GbhOpts, HibernateAfterTimeout, Status, State, []); {ok, Status, State, Actions} -> proc_lib:init_ack(Starter, {ok, self()}), - loopEntry(Parent, Debug, Module, Name, HibernateAfterTimeout, Status, State, listify(Actions)); + loopEntry(Parent, Debug, Module, Name, GbhOpts, HibernateAfterTimeout, Status, State, listify(Actions)); {stop, Reason} -> gen:unregister_name(ServerRef), proc_lib:init_ack(Starter, {error, Reason}), @@ -422,11 +428,12 @@ enter_loop(Module, Status, State, Opts, ServerName, Actions) -> Parent = gen:get_parent(), Name = gen:get_proc_name(ServerName), Debug = gen:debug_options(Name, Opts), + GbhOpts = #gbhOpts{daemon = lists:member(daemon, Opts)}, HibernateAfterTimeout = gen:hibernate_after(Opts), - loopEntry(Parent, Debug, Module, Name, HibernateAfterTimeout, Status, State, Actions). + loopEntry(Parent, Debug, Module, Name, GbhOpts, HibernateAfterTimeout, Status, State, Actions). %% 这里的 init_it/6 和 enter_loop/5,6,7 函数汇聚 -loopEntry(Parent, Debug, Module, Name, HibernateAfterTimeout, CurStatus, CurState, Actions) -> +loopEntry(Parent, Debug, Module, Name, GbhOpts, HibernateAfterTimeout, CurStatus, CurState, Actions) -> %% 如果该进程用于 gen_event 或者该进程需要捕捉退出信号 和 捕捉supervisor进程树的退出信息 则需要设置 process_flag(trap_exit, true) 需要在Actions返回 {trap_exit, true} MewActions = case lists:keyfind(trap_exit, 1, Actions) of @@ -439,24 +446,24 @@ loopEntry(Parent, Debug, Module, Name, HibernateAfterTimeout, CurStatus, CurStat lists:keydelete(trap_exit, 1, Actions) end, - NewDebug = ?SYS_DEBUG(Debug, Name, {enter, CurStatus}), + ?SYS_DEBUG(Debug, Name, {enter, CurStatus}), %% 强制执行{postpone,false}以确保我们的假事件被丢弃 LastActions = MewActions ++ [{isPos, false}], - parseEventAL(Parent, Name, Module, HibernateAfterTimeout, false, #{}, [], #{}, CurStatus, CurState, CurStatus, NewDebug, [{onevent, init_status}], true, LastActions, ?CB_FORM_EVENT). + parseEventAL(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, false, #{}, [], #{}, CurStatus, CurState, CurStatus, Debug, [{onevent, init_status}], true, LastActions, ?CB_FORM_EVENT). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% sys callbacks start %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -system_continue(Parent, Debug, {Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, IsHib}) -> +system_continue(Parent, Debug, {Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, IsHib}) -> if IsHib -> - proc_lib:hibernate(?MODULE, wakeupFromHib, [Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug]); + proc_lib:hibernate(?MODULE, wakeupFromHib, [Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug]); true -> - receiveIng(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, false) + receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, false) end. -system_terminate(Reason, Parent, Debug, {Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, _IsHib}) -> +system_terminate(Reason, Parent, Debug, {Parent, Name, Module, _GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, _IsHib}) -> terminate(exit, Reason, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, []). -system_code_change({Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, IsHib}, _Mod, OldVsn, Extra) -> +system_code_change({Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, IsHib}, _Mod, OldVsn, Extra) -> case try Module:code_change(OldVsn, CurStatus, CurState, Extra) catch @@ -465,19 +472,19 @@ system_code_change({Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHer end of {ok, NewStatus, NewState} -> - {ok, {Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, NewStatus, NewState, IsHib}}; + {ok, {Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, NewStatus, NewState, IsHib}}; Error -> Error end. -system_get_state({_Parent, _Name, _Module, _HibernateAfterTimeout, _IsEnter, _EpmHers, _Postponed, _Timers, CurStatus, CurState, _IsHib}) -> +system_get_state({_Parent, _Name, _Module, _GbhOpts, _HibernateAfterTimeout, _IsEnter, _EpmHers, _Postponed, _Timers, CurStatus, CurState, _IsHib}) -> {ok, {CurStatus, CurState}}. -system_replace_state(StatusFun, {Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, IsHib}) -> +system_replace_state(StatusFun, {Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, IsHib}) -> {NewStatus, NewState} = StatusFun(CurStatus, CurState), - {ok, {NewStatus, NewState}, {Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, NewStatus, NewState, IsHib}}. + {ok, {NewStatus, NewState}, {Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, NewStatus, NewState, IsHib}}. -format_status(Opt, [PDict, SysStatus, Parent, Debug, {Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, _IsHib}]) -> +format_status(Opt, [PDict, SysStatus, Parent, Debug, {Parent, Name, Module, _GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, _IsHib}]) -> Header = gen:format_status_header("Status for gen_ipc", Name), Log = sys:get_log(Debug), [ @@ -1098,237 +1105,239 @@ listify(Item) -> [Item]. %%%========================================================================== %%% Internal callbacks -wakeupFromHib(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug) -> +wakeupFromHib(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug) -> %% 这是一条新消息,唤醒了我们,因此我们必须立即收到它 - receiveIng(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, true). + receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, true). %%%========================================================================== %% Entry point for system_continue/3 -reLoopEntry(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, IsHib) -> +reLoopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, IsHib) -> if IsHib -> - proc_lib:hibernate(?MODULE, wakeupFromHib, [Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug]); + proc_lib:hibernate(?MODULE, wakeupFromHib, [Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug]); true -> - receiveIng(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, false) + receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, false) end. %% 接收新的消息 -receiveIng(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, IsHib) -> +receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, IsHib) -> receive Msg -> case Msg of {'$gen_call', From, Request} -> - matchCallMsg(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, From, Request); + matchCallMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, From, Request); {'$gen_cast', Cast} -> - matchCastMsg(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, Cast); + matchCastMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, Cast); {timeout, TimerRef, TimeoutType} -> case Timers of #{TimeoutType := {TimerRef, TimeoutMsg}} -> NewTimers = maps:remove(TimeoutType, Timers), - matchTimeoutMsg(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, Debug, TimeoutType, TimeoutMsg); + matchTimeoutMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, Debug, TimeoutType, TimeoutMsg); _ -> - matchInfoMsg(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, Msg) + matchInfoMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, Msg) end; {system, PidFrom, Request} -> %% 不返回但尾递归调用 system_continue/3 - sys:handle_system_msg(Request, PidFrom, Parent, ?MODULE, Debug, {Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, IsHib}, IsHib); + sys:handle_system_msg(Request, PidFrom, Parent, ?MODULE, Debug, {Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, IsHib}, IsHib); {'EXIT', PidFrom, Reason} -> case Parent =:= PidFrom of true -> terminate(exit, Reason, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, []); _ -> NewEpmHers = epmStopOne(PidFrom, EpmHers), - matchInfoMsg(Parent, Name, Module, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, Debug, Msg) + matchInfoMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, Debug, Msg) end; {'$epm_call', From, Request} -> - matchEpmCallMsg(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, From, Request); + matchEpmCallMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, From, Request); {'$epm_info', CmdOrEmpHandler, Event} -> - matchEpmInfoMsg(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, CmdOrEmpHandler, Event); + matchEpmInfoMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, CmdOrEmpHandler, Event); _ -> - matchInfoMsg(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, Msg) + matchInfoMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, Msg) end after HibernateAfterTimeout -> - proc_lib:hibernate(?MODULE, wakeupFromHib, [Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug]) + proc_lib:hibernate(?MODULE, wakeupFromHib, [Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug]) end. -matchCallMsg(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, From, Request) -> +matchCallMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, From, Request) -> CurEvent = {{call, From}, Request}, - NewDebug = ?SYS_DEBUG(Debug, Name, {in, CurEvent, CurStatus}), + ?SYS_DEBUG(Debug, Name, {in, CurEvent, CurStatus}), try Module:handleCall(Request, CurStatus, CurState, From) of Result -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, [CurEvent], Result, ?CB_FORM_EVENT, From) + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, [CurEvent], Result, ?CB_FORM_EVENT, From) catch throw:Result -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, [CurEvent], Result, ?CB_FORM_EVENT, From); + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, [CurEvent], Result, ?CB_FORM_EVENT, From); Class:Reason:Strace -> - terminate(Class, Reason, Strace, Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, [CurEvent]) + try_greply(From, {error, {inner_error, {Class, Reason, Strace}}}), + innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, [CurEvent], Class, Reason, Strace) end. -matchCastMsg(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, Cast) -> +matchCastMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, Cast) -> CurEvent = {cast, Cast}, - NewDebug = ?SYS_DEBUG(Debug, Name, {in, CurEvent, CurStatus}), + ?SYS_DEBUG(Debug, Name, {in, CurEvent, CurStatus}), try Module:handleCast(Cast, CurStatus, CurState) of Result -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, [CurEvent], Result, ?CB_FORM_EVENT, false) + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, [CurEvent], Result, ?CB_FORM_EVENT, false) catch throw:Result -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, [CurEvent], Result, ?CB_FORM_EVENT, false); + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, [CurEvent], Result, ?CB_FORM_EVENT, false); Class:Reason:Strace -> - terminate(Class, Reason, Strace, Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, [CurEvent]) + innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, [CurEvent], Class, Reason, Strace) end. -matchInfoMsg(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, Msg) -> +matchInfoMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, Msg) -> CurEvent = {info, Msg}, - NewDebug = ?SYS_DEBUG(Debug, Name, {in, CurEvent, CurStatus}), + ?SYS_DEBUG(Debug, Name, {in, CurEvent, CurStatus}), try Module:handleInfo(Msg, CurStatus, CurState) of Result -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, [CurEvent], Result, ?CB_FORM_EVENT, false) + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, [CurEvent], Result, ?CB_FORM_EVENT, false) catch throw:Result -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, [CurEvent], Result, ?CB_FORM_EVENT, false); + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, [CurEvent], Result, ?CB_FORM_EVENT, false); Class:Reason:Strace -> - terminate(Class, Reason, Strace, Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, [CurEvent]) + innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, [CurEvent], Class, Reason, Strace) end. -matchTimeoutMsg(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, TimeoutType, TimeoutMsg) -> +matchTimeoutMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, TimeoutType, TimeoutMsg) -> CurEvent = {TimeoutType, TimeoutMsg}, - NewDebug = ?SYS_DEBUG(Debug, Name, {in, CurEvent, CurStatus}), + ?SYS_DEBUG(Debug, Name, {in, CurEvent, CurStatus}), try Module:handleOnevent(TimeoutType, TimeoutMsg, CurStatus, CurState) of Result -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, [CurEvent], Result, ?CB_FORM_EVENT, false) + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, [CurEvent], Result, ?CB_FORM_EVENT, false) catch throw:Result -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, [CurEvent], Result, ?CB_FORM_EVENT, false); + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, [CurEvent], Result, ?CB_FORM_EVENT, false); Class:Reason:Strace -> - terminate(Class, Reason, Strace, Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, [CurEvent]) + innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, [CurEvent], Class, Reason, Strace) end. -matchEpmCallMsg(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, From, Request) -> - NewDebug = ?SYS_DEBUG(Debug, Name, {in, Request, CurStatus}), +matchEpmCallMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, From, Request) -> + ?SYS_DEBUG(Debug, Name, {in, Request, CurStatus}), case Request of '$which_handlers' -> reply(From, EpmHers); {'$addEpm', EpmHandler, Args} -> {Reply, NewEpmHers, IsHib} = doAddEpm(EpmHers, EpmHandler, Args, undefined), reply(From, Reply), - reLoopEntry(Parent, Name, Module, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, IsHib); + reLoopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, Debug, IsHib); {'$addSupEpm', EpmHandler, Args, EpmSup} -> {Reply, NewEpmHers, IsHib} = doAddSupEpm(EpmHers, EpmHandler, Args, EpmSup), reply(From, Reply), - reLoopEntry(Parent, Name, Module, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, IsHib); + reLoopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, Debug, IsHib); {'$delEpm', EpmHandler, Args} -> {Reply, NewEpmHers} = doDelEpm(EpmHers, EpmHandler, Args), reply(From, Reply), - receiveIng(Parent, Name, Module, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, false); + receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, Debug, false); {'$swapEpm', EpmId1, Args1, EpmId2, Args2} -> {Reply, NewEpmHers, IsHib} = doSwapEpm(EpmHers, EpmId1, Args1, EpmId2, Args2), reply(From, Reply), - reLoopEntry(Parent, Name, Module, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, IsHib); + reLoopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, Debug, IsHib); {'$swapSupEpm', EpmId1, Args1, EpmId2, Args2, SupPid} -> {Reply, NewEpmHers, IsHib} = doSwapSupEpm(EpmHers, EpmId1, Args1, EpmId2, Args2, SupPid), reply(From, Reply), - reLoopEntry(Parent, Name, Module, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, IsHib); + reLoopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, Debug, IsHib); {'$syncNotify', Event} -> {NewEpmHers, IsHib} = doNotify(EpmHers, handleEvent, Event, false), reply(From, ok), - startEpmCall(Parent, Name, Module, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, handleEpmEvent, Request, IsHib); + startEpmCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, Debug, handleEpmEvent, Request, IsHib); {'$epmCall', EpmHandler, Query} -> {NewEpmHers, IsHib} = doEpmHandle(EpmHers, EpmHandler, handleCall, Query, From), - startEpmCall(Parent, Name, Module, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, handleEpmCall, Request, IsHib) + startEpmCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, Debug, handleEpmCall, Request, IsHib) end. -matchEpmInfoMsg(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, CmdOrEmpHandler, Event) -> - NewDebug = ?SYS_DEBUG(Debug, Name, {in, {CmdOrEmpHandler, Event}, CurStatus}), +matchEpmInfoMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, CmdOrEmpHandler, Event) -> + ?SYS_DEBUG(Debug, Name, {in, {CmdOrEmpHandler, Event}, CurStatus}), case CmdOrEmpHandler of '$infoNotify' -> {NewEpmHers, IsHib} = doNotify(EpmHers, handleEvent, Event, false), - startEpmCall(Parent, Name, Module, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, handleEpmEvent, Event, IsHib); + startEpmCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, Debug, handleEpmEvent, Event, IsHib); EpmHandler -> {NewEpmHers, IsHib} = doEpmHandle(EpmHers, EpmHandler, handleInfo, Event, false), - startEpmCall(Parent, Name, Module, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, handleEpmInfo, Event, IsHib) + startEpmCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, NewEpmHers, Postponed, Timers, CurStatus, CurState, Debug, handleEpmInfo, Event, IsHib) end. -startEpmCall(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, CallbackFun, Event, IsHib) -> +startEpmCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, CallbackFun, Event, IsHib) -> case erlang:function_exported(Module, CallbackFun, 3) of true -> - NewDebug = ?SYS_DEBUG(Debug, Name, {in, Event, CurStatus}), + ?SYS_DEBUG(Debug, Name, {in, Event, CurStatus}), try Module:CallbackFun(Event, CurStatus, CurState) of Result -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, [Event], Result, ?CB_FORM_EVENT, false) + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, [Event], Result, ?CB_FORM_EVENT, false) catch throw:Ret -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, [Event], Ret, ?CB_FORM_EVENT, false); + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, [Event], Ret, ?CB_FORM_EVENT, false); Class:Reason:Strace -> - terminate(Class, Reason, Strace, Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, [Event]) + innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, [Event], Class, Reason, Strace) end; _ -> - reLoopEntry(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, IsHib) + reLoopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, IsHib) end. -startEnterCall(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, CurState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter) -> +startEnterCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, CurState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter) -> try Module:handleEnter(PrevStatus, CurStatus, CurState) of Result -> - handleEnterCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, CurState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, Result) + handleEnterCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, CurState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, Result) catch throw:Result -> - handleEnterCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, CurState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, Result); + handleEnterCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, CurState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, Result); Class:Reason:Strace -> - terminate(Class, Reason, Strace, Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents) + innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Class, Reason, Strace) end. -startAfterCall(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Args) -> +startAfterCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Args) -> try Module:handleAfter(Args, CurStatus, CurState) of Result -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Result, ?CB_FORM_AFTER, false) + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Result, ?CB_FORM_AFTER, false) catch throw:Result -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Result, ?CB_FORM_AFTER, false); + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Result, ?CB_FORM_AFTER, false); Class:Reason:Strace -> - terminate(Class, Reason, Strace, Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents) + innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, {doAfter, Args}, Class, Reason, Strace) end. -startEventCall(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, {Type, Content}) -> +startEventCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, {Type, Content}) -> case Type of 'cast' -> try Module:handleCast(Content, CurStatus, CurState) of Result -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Result, ?CB_FORM_EVENT, false) + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Result, ?CB_FORM_EVENT, false) catch throw:Ret -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Ret, ?CB_FORM_EVENT, false); + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Ret, ?CB_FORM_EVENT, false); Class:Reason:Strace -> - terminate(Class, Reason, Strace, Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents) + innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, {Type, Content}, Class, Reason, Strace) end; 'info' -> try Module:handleInfo(Content, CurStatus, CurState) of Result -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Result, ?CB_FORM_EVENT, false) + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Result, ?CB_FORM_EVENT, false) catch throw:Ret -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Ret, ?CB_FORM_EVENT, false); + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Ret, ?CB_FORM_EVENT, false); Class:Reason:Strace -> - terminate(Class, Reason, Strace, Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents) + innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, {Type, Content}, Class, Reason, Strace) end; {'call', From} -> try Module:handleCall(Content, CurStatus, CurState, From) of Result -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Result, ?CB_FORM_EVENT, From) + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Result, ?CB_FORM_EVENT, From) catch throw:Ret -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Ret, ?CB_FORM_EVENT, From); + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Ret, ?CB_FORM_EVENT, From); Class:Reason:Strace -> - terminate(Class, Reason, Strace, Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents) + try_greply(From, {error, {inner_error, {Class, Reason, Strace}}}), + innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, {Type, Content}, Class, Reason, Strace) end; _ -> try Module:handleOnevent(Type, Content, CurStatus, CurState) of Result -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Result, ?CB_FORM_EVENT, false) + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Result, ?CB_FORM_EVENT, false) catch throw:Ret -> - handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Ret, ?CB_FORM_EVENT, false); + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Ret, ?CB_FORM_EVENT, false); Class:Reason:Strace -> - terminate(Class, Reason, Strace, Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents) + innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, {Type, Content}, Class, Reason, Strace) end end. @@ -1392,24 +1401,24 @@ handleEpmCR(Result, EpmHers, #epmHer{epmId = EpmId} = EpmHer, Event, From) -> end. %% handleEnterCallbackRet -handleEnterCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, CurState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, Result) -> +handleEnterCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, CurState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, Result) -> case Result of {kpS, NewState} -> - dealEnterCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, NewState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, false); + dealEnterCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, NewState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, false); {kpS, NewState, Actions} -> - parseEnterAL(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, NewState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, false, listify(Actions)); + parseEnterAL(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, NewState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, false, listify(Actions)); kpS_S -> - dealEnterCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, CurState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, false); + dealEnterCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, CurState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, false); {kpS_S, Actions} -> - parseEnterAL(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, CurState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, false, listify(Actions)); + parseEnterAL(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, CurState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, false, listify(Actions)); {reS, NewState} -> - dealEnterCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, NewState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, true); + dealEnterCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, NewState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, true); {reS, NewState, Actions} -> - parseEnterAL(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, NewState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, true, listify(Actions)); + parseEnterAL(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, NewState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, true, listify(Actions)); reS_S -> - dealEnterCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, CurState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, true); + dealEnterCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, CurState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, true); {reS_S, Actions} -> - parseEnterAL(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, CurState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, true, listify(Actions)); + parseEnterAL(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, PrevStatus, CurState, CurStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, true, listify(Actions)); stop -> terminate(exit, normal, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents); {stop, Reason} -> @@ -1417,9 +1426,9 @@ handleEnterCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Pos {stop, Reason, NewState} -> terminate(exit, Reason, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, Debug, LeftEvents); {stopReply, Reason, Replies} -> - NewDebug = ?SYS_DEBUG(Debug, Name, {out, Replies}), + ?SYS_DEBUG(Debug, Name, {out, Replies}), try - terminate(exit, Reason, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, LeftEvents) + terminate(exit, Reason, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents) after case Replies of {reply, RFrom, Reply} -> @@ -1430,9 +1439,9 @@ handleEnterCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Pos end end; {stopReply, Reason, Replies, NewState} -> - NewDebug = ?SYS_DEBUG(Debug, Name, {out, Replies}), + ?SYS_DEBUG(Debug, Name, {out, Replies}), try - terminate(exit, Reason, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, NewDebug, LeftEvents) + terminate(exit, Reason, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, Debug, LeftEvents) after case Replies of {reply, RFrom, Reply} -> @@ -1443,65 +1452,65 @@ handleEnterCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Pos end end; _ -> - terminate(error, {bad_handleEnterCR, Result}, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents) + innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, error, {bad_handleEnterCR, Result}, ?STACKTRACE()) end. -handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Result, CallbackForm, From) -> +handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Result, CallbackForm, From) -> case Result of {noreply, NewState} -> - receiveIng(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, Debug, false); + receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, Debug, false); {noreply, NewState, Option} -> case Option of hibernate -> - reLoopEntry(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, Debug, true); + reLoopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, Debug, true); {doAfter, Args} -> - startAfterCall(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, Debug, [], Args); + startAfterCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, Debug, [], Args); _Ret -> - terminate(error, {bad_noreply, _Ret}, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, Debug, []) + innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, error, {bad_noreply, _Ret}, ?STACKTRACE()) end; {reply, Reply, NewState} -> reply(From, Reply), - NewDebug = ?SYS_DEBUG(Debug, Name, {out, Reply, From}), - receiveIng(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, NewDebug, false); + ?SYS_DEBUG(Debug, Name, {out, Reply, From}), + receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, Debug, false); {reply, Reply, NewState, Option} -> reply(From, Reply), - NewDebug = ?SYS_DEBUG(Debug, Name, {out, Reply, From}), + ?SYS_DEBUG(Debug, Name, {out, Reply, From}), case Option of hibernate -> - reLoopEntry(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, NewDebug, true); + reLoopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, Debug, true); {doAfter, Args} -> - startAfterCall(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, NewDebug, [], Args); + startAfterCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, Debug, [], Args); _Ret -> - terminate(error, {bad_reply, _Ret}, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, Debug, []) + innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, error, {bad_reply, _Ret}, ?STACKTRACE()) end; {sreply, Reply, NewStatus, NewState} -> reply(From, Reply), - NewDebug = ?SYS_DEBUG(Debug, Name, {out, Reply, From}), - dealEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, NewStatus, NewDebug, LeftEvents, NewStatus =/= CurStatus); + ?SYS_DEBUG(Debug, Name, {out, Reply, From}), + dealEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, NewStatus, Debug, LeftEvents, NewStatus =/= CurStatus); {sreply, Reply, NewStatus, NewState, Actions} -> reply(From, Reply), - NewDebug = ?SYS_DEBUG(Debug, Name, {out, Reply, From}), - parseEventAL(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, NewStatus, NewDebug, LeftEvents, NewStatus =/= CurStatus, listify(Actions), CallbackForm); + ?SYS_DEBUG(Debug, Name, {out, Reply, From}), + parseEventAL(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, NewStatus, Debug, LeftEvents, NewStatus =/= CurStatus, listify(Actions), CallbackForm); {nextS, NewStatus, NewState} -> - dealEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, NewStatus, Debug, LeftEvents, NewStatus =/= CurStatus); + dealEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, NewStatus, Debug, LeftEvents, NewStatus =/= CurStatus); {nextS, NewStatus, NewState, Actions} -> - parseEventAL(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, NewStatus, Debug, LeftEvents, NewStatus =/= CurStatus, listify(Actions), CallbackForm); + parseEventAL(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, NewStatus, Debug, LeftEvents, NewStatus =/= CurStatus, listify(Actions), CallbackForm); {kpS, NewState} -> - dealEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, CurStatus, Debug, LeftEvents, false); + dealEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, CurStatus, Debug, LeftEvents, false); {kpS, NewState, Actions} -> - parseEventAL(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, CurStatus, Debug, LeftEvents, false, listify(Actions), CallbackForm); + parseEventAL(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, CurStatus, Debug, LeftEvents, false, listify(Actions), CallbackForm); kpS_S -> - dealEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, CurStatus, Debug, LeftEvents, false); + dealEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, CurStatus, Debug, LeftEvents, false); {kpS_S, Actions} -> - parseEventAL(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, CurStatus, Debug, LeftEvents, false, listify(Actions), CallbackForm); + parseEventAL(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, CurStatus, Debug, LeftEvents, false, listify(Actions), CallbackForm); {reS, NewState} -> - dealEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, CurStatus, Debug, LeftEvents, true); + dealEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, CurStatus, Debug, LeftEvents, true); {reS, NewState, Actions} -> - parseEventAL(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, CurStatus, Debug, LeftEvents, true, listify(Actions), CallbackForm); + parseEventAL(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, CurStatus, Debug, LeftEvents, true, listify(Actions), CallbackForm); reS_S -> - dealEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, CurStatus, Debug, LeftEvents, true); + dealEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, CurStatus, Debug, LeftEvents, true); {reS_S, Actions} -> - parseEventAL(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, CurStatus, Debug, LeftEvents, true, listify(Actions), CallbackForm); + parseEventAL(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, CurStatus, Debug, LeftEvents, true, listify(Actions), CallbackForm); stop -> terminate(exit, normal, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents); {stop, Reason} -> @@ -1509,9 +1518,9 @@ handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Pos {stop, Reason, NewState} -> terminate(exit, Reason, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, Debug, LeftEvents); {stopReply, Reason, Replies} -> - NewDebug = ?SYS_DEBUG(Debug, Name, {out, Replies}), + ?SYS_DEBUG(Debug, Name, {out, Replies}), try - terminate(exit, Reason, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewDebug, LeftEvents) + terminate(exit, Reason, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents) after case Replies of {reply, RFrom, Reply} -> @@ -1524,9 +1533,9 @@ handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Pos end end; {stopReply, Reason, Replies, NewState} -> - NewDebug = ?SYS_DEBUG(Debug, Name, {out, Replies}), + ?SYS_DEBUG(Debug, Name, {out, Replies}), try - terminate(exit, Reason, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, NewDebug, LeftEvents) + terminate(exit, Reason, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, NewState, Debug, LeftEvents) after case Replies of {reply, RFrom, Reply} -> @@ -1539,77 +1548,77 @@ handleEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Pos end end; _ -> - terminate(error, {bad_handleEventCR, Result}, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents) + innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, error, {bad_handleEventCR, Result}, ?STACKTRACE()) end. -dealEnterCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, IsCallEnter) -> +dealEnterCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter, IsCallEnter) -> NewTimers = cancelESTimeout(CurStatus =:= NewStatus, Timers), case IsEnter andalso IsCallEnter of true -> - startEnterCall(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter); + startEnterCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter); false -> - performTransitions(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter) + performTransitions(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter) end. %% dealEventCallbackRet -dealEventCR(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewStatus, Debug, LeftEvents, IsCallEnter) -> +dealEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewStatus, Debug, LeftEvents, IsCallEnter) -> NewTimers = cancelESTimeout(CurStatus =:= NewStatus, Timers), case IsEnter andalso IsCallEnter of true -> - startEnterCall(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, [], false, false, false); + startEnterCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, [], false, false, false); false -> - performTransitions(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, [], false, false, false) + performTransitions(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, [], false, false, false) end. %% 处理enter callback 动作列表 %% parseEnterActionsList -parseEnterAL(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewStatus, Debug, LeftEvents, NextEs, IsPos, IsCallEnter, IsHib, DoAfter, Actions) -> +parseEnterAL(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewStatus, Debug, LeftEvents, NextEs, IsPos, IsCallEnter, IsHib, DoAfter, Actions) -> NewTimers = cancelESTimeout(CurStatus =:= NewStatus, Timers), %% enter 调用不能改成状态 actions 不能返回 IsPos = true 但是可以取消之前的推迟 设置IsPos = false 不能设置 doafter 不能插入事件 case Actions of [] -> case IsEnter andalso IsCallEnter of true -> - startEnterCall(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter); + startEnterCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter); _ -> - performTransitions(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter) + performTransitions(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, NextEs, IsPos, IsHib, DoAfter) end; _ -> case doParseAL(Actions, ?CB_FORM_ENTER, Name, IsEnter, NewTimers, Debug, IsPos, IsHib, DoAfter, NextEs) of {error, ErrorContent} -> - terminate(error, ErrorContent, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, Debug, LeftEvents); - {NewIsEnter, NNewTimers, NewDebug, NewIsPos, NewIsHib, DoAfter, NewNextEs} -> + innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, Actions, error, ErrorContent, ?STACKTRACE()); + {NewIsEnter, NNewTimers, Debug, NewIsPos, NewIsHib, DoAfter, NewNextEs} -> case NewIsEnter andalso IsCallEnter of true -> - startEnterCall(Parent, Name, Module, HibernateAfterTimeout, NewIsEnter, EpmHers, Postponed, NNewTimers, CurStatus, CurState, NewStatus, NewDebug, LeftEvents, NewNextEs, NewIsPos, NewIsHib, DoAfter); + startEnterCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, NewIsEnter, EpmHers, Postponed, NNewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, NewNextEs, NewIsPos, NewIsHib, DoAfter); _ -> - performTransitions(Parent, Name, Module, HibernateAfterTimeout, NewIsEnter, EpmHers, Postponed, NNewTimers, CurStatus, CurState, NewStatus, NewDebug, LeftEvents, NewNextEs, NewIsPos, NewIsHib, DoAfter) + performTransitions(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, NewIsEnter, EpmHers, Postponed, NNewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, NewNextEs, NewIsPos, NewIsHib, DoAfter) end end end. %% 处理非 enter 或者after callback 返回的动作列表 %% parseEventActionsList -parseEventAL(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewStatus, Debug, LeftEvents, IsCallEnter, Actions, CallbackForm) -> +parseEventAL(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewStatus, Debug, LeftEvents, IsCallEnter, Actions, CallbackForm) -> NewTimers = cancelESTimeout(CurStatus =:= NewStatus, Timers), case Actions of [] -> case IsEnter andalso IsCallEnter of true -> - startEnterCall(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, [], false, false, false); + startEnterCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, [], false, false, false); _ -> - performTransitions(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, [], false, false, false) + performTransitions(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, [], false, false, false) end; _ -> case doParseAL(Actions, CallbackForm, Name, IsEnter, NewTimers, Debug, false, false, false, []) of {error, ErrorContent} -> - terminate(error, ErrorContent, ?STACKTRACE(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, []); - {NewIsEnter, NNewTimers, NewDebug, NewIsPos, NewIsHib, MewDoAfter, NewNextEs} -> + innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, Actions, error, ErrorContent, ?STACKTRACE()); + {NewIsEnter, NNewTimers, Debug, NewIsPos, NewIsHib, MewDoAfter, NewNextEs} -> case NewIsEnter andalso IsCallEnter of true -> - startEnterCall(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NNewTimers, CurStatus, CurState, NewStatus, NewDebug, LeftEvents, NewNextEs, NewIsPos, NewIsHib, MewDoAfter); + startEnterCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NNewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, NewNextEs, NewIsPos, NewIsHib, MewDoAfter); _ -> - performTransitions(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NNewTimers, CurStatus, CurState, NewStatus, NewDebug, LeftEvents, NewNextEs, NewIsPos, NewIsHib, MewDoAfter) + performTransitions(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, NNewTimers, CurStatus, CurState, NewStatus, Debug, LeftEvents, NewNextEs, NewIsPos, NewIsHib, MewDoAfter) end end end. @@ -1621,8 +1630,8 @@ doParseAL([OneAction | LeftActions], CallbackForm, Name, IsEnter, Timers, Debug, case OneAction of {reply, From, Reply} -> reply(From, Reply), - NewDebug = ?SYS_DEBUG(Debug, Name, {out, Reply, From}), - doParseAL(LeftActions, CallbackForm, Name, IsEnter, Timers, NewDebug, IsPos, IsHib, DoAfter, NextEs); + ?SYS_DEBUG(Debug, Name, {out, Reply, From}), + doParseAL(LeftActions, CallbackForm, Name, IsEnter, Timers, Debug, IsPos, IsHib, DoAfter, NextEs); {eTimeout, Time, TimeoutMsg} -> case Time of infinity -> @@ -1630,9 +1639,9 @@ doParseAL([OneAction | LeftActions], CallbackForm, Name, IsEnter, Timers, Debug, doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, Debug, IsPos, IsHib, DoAfter, NextEs); _ -> TimerRef = erlang:start_timer(Time, self(), eTimeout), - NewDebug = ?SYS_DEBUG(Debug, Name, {start_timer, {eTimeout, Time, TimeoutMsg, []}}), + ?SYS_DEBUG(Debug, Name, {start_timer, {eTimeout, Time, TimeoutMsg, []}}), NewTimers = doRegisterTimer(eTimeout, TimerRef, TimeoutMsg, Timers), - doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, NewDebug, IsPos, IsHib, DoAfter, NextEs) + doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, Debug, IsPos, IsHib, DoAfter, NextEs) end; {sTimeout, Time, TimeoutMsg} -> case Time of @@ -1641,9 +1650,9 @@ doParseAL([OneAction | LeftActions], CallbackForm, Name, IsEnter, Timers, Debug, doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, Debug, IsPos, IsHib, DoAfter, NextEs); _ -> TimerRef = erlang:start_timer(Time, self(), sTimeout), - NewDebug = ?SYS_DEBUG(Debug, Name, {start_timer, {sTimeout, Time, TimeoutMsg, []}}), + ?SYS_DEBUG(Debug, Name, {start_timer, {sTimeout, Time, TimeoutMsg, []}}), NewTimers = doRegisterTimer(sTimeout, TimerRef, TimeoutMsg, Timers), - doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, NewDebug, IsPos, IsHib, DoAfter, NextEs) + doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, Debug, IsPos, IsHib, DoAfter, NextEs) end; {gTimeout, TimeoutName, Time, TimeoutMsg} -> case Time of @@ -1652,9 +1661,9 @@ doParseAL([OneAction | LeftActions], CallbackForm, Name, IsEnter, Timers, Debug, doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, Debug, IsPos, IsHib, DoAfter, NextEs); _ -> TimerRef = erlang:start_timer(Time, self(), TimeoutName), - NewDebug = ?SYS_DEBUG(Debug, Name, {start_timer, {TimeoutName, Time, TimeoutMsg, []}}), + ?SYS_DEBUG(Debug, Name, {start_timer, {TimeoutName, Time, TimeoutMsg, []}}), NewTimers = doRegisterTimer(TimeoutName, TimerRef, TimeoutMsg, Timers), - doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, NewDebug, IsPos, IsHib, DoAfter, NextEs) + doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, Debug, IsPos, IsHib, DoAfter, NextEs) end; {eTimeout, Time, TimeoutMsg, Options} -> case Time of @@ -1663,9 +1672,9 @@ doParseAL([OneAction | LeftActions], CallbackForm, Name, IsEnter, Timers, Debug, doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, Debug, IsPos, IsHib, DoAfter, NextEs); _ -> TimerRef = erlang:start_timer(Time, self(), eTimeout, Options), - NewDebug = ?SYS_DEBUG(Debug, Name, {start_timer, {eTimeout, Time, TimeoutMsg, Options}}), + ?SYS_DEBUG(Debug, Name, {start_timer, {eTimeout, Time, TimeoutMsg, Options}}), NewTimers = doRegisterTimer(eTimeout, TimerRef, TimeoutMsg, Timers), - doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, NewDebug, IsPos, IsHib, DoAfter, NextEs) + doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, Debug, IsPos, IsHib, DoAfter, NextEs) end; {sTimeout, Time, TimeoutMsg, Options} -> case Time of @@ -1674,9 +1683,9 @@ doParseAL([OneAction | LeftActions], CallbackForm, Name, IsEnter, Timers, Debug, doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, Debug, IsPos, IsHib, DoAfter, NextEs); _ -> TimerRef = erlang:start_timer(Time, self(), sTimeout, Options), - NewDebug = ?SYS_DEBUG(Debug, Name, {start_timer, {sTimeout, Time, TimeoutMsg, Options}}), + ?SYS_DEBUG(Debug, Name, {start_timer, {sTimeout, Time, TimeoutMsg, Options}}), NewTimers = doRegisterTimer(sTimeout, TimerRef, TimeoutMsg, Timers), - doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, NewDebug, IsPos, IsHib, DoAfter, NextEs) + doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, Debug, IsPos, IsHib, DoAfter, NextEs) end; {gTimeout, TimeoutName, Time, TimeoutMsg, Options} -> case Time of @@ -1685,9 +1694,9 @@ doParseAL([OneAction | LeftActions], CallbackForm, Name, IsEnter, Timers, Debug, doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, Debug, IsPos, IsHib, DoAfter, NextEs); _ -> TimerRef = erlang:start_timer(Time, self(), TimeoutName, Options), - NewDebug = ?SYS_DEBUG(Debug, Name, {start_timer, {TimeoutName, Time, TimeoutMsg, Options}}), + ?SYS_DEBUG(Debug, Name, {start_timer, {TimeoutName, Time, TimeoutMsg, Options}}), NewTimers = doRegisterTimer(TimeoutName, TimerRef, TimeoutMsg, Timers), - doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, NewDebug, IsPos, IsHib, DoAfter, NextEs) + doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, Debug, IsPos, IsHib, DoAfter, NextEs) end; {u_eTimeout, NewTimeoutMsg} -> NewTimers = doUpdateTimer(eTimeout, NewTimeoutMsg, Timers), @@ -1708,8 +1717,8 @@ doParseAL([OneAction | LeftActions], CallbackForm, Name, IsEnter, Timers, Debug, NewTimers = doCancelTimer(TimeoutName, Timers), doParseAL(LeftActions, CallbackForm, Name, IsEnter, NewTimers, Debug, IsPos, IsHib, DoAfter, NextEs); {isEnter, NewIsEnter} -> - NewDebug = ?SYS_DEBUG(Debug, Name, {change_isEnter, NewIsEnter}), - doParseAL(LeftActions, CallbackForm, Name, Timers, NewIsEnter, NewDebug, IsPos, IsHib, DoAfter, NextEs); + ?SYS_DEBUG(Debug, Name, {change_isEnter, NewIsEnter}), + doParseAL(LeftActions, CallbackForm, Name, Timers, NewIsEnter, Debug, IsPos, IsHib, DoAfter, NextEs); {isHib, NewIsHib} -> doParseAL(LeftActions, CallbackForm, Name, IsEnter, Timers, Debug, IsPos, NewIsHib, DoAfter, NextEs); {isPos, NewIsPos} when (not NewIsPos orelse CallbackForm == ?CB_FORM_EVENT) -> @@ -1737,7 +1746,7 @@ doParseAL([OneAction | LeftActions], CallbackForm, Name, IsEnter, Timers, Debug, % end. %% 进行状态转换 -performTransitions(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewStatus, Debug, AllLeftEvents, NextEs, IsPos, IsHib, DoAfter) -> +performTransitions(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, NewStatus, Debug, AllLeftEvents, NextEs, IsPos, IsHib, DoAfter) -> %% 已收集所有选项,并缓冲next_events。执行实际状态转换。如果推迟则将当前事件移至推迟 %% 此时 NextEs的顺序与最开始出现的顺序相反. 后面执行的顺序 当前新增事件 + 反序的Postpone事件 + LeftEvents case AllLeftEvents of @@ -1748,7 +1757,7 @@ performTransitions(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers [CurEvent | LeftEvents] = AllLeftEvents end, - NewDebug = ?SYS_DEBUG(Debug, Name, case IsPos of true -> {postpone, CurEvent, CurStatus, NewStatus}; _ -> {consume, CurEvent, CurStatus, NewStatus} end), + ?SYS_DEBUG(Debug, Name, case IsPos of true -> {postpone, CurEvent, CurStatus, NewStatus}; _ -> {consume, CurEvent, CurStatus, NewStatus} end), if CurStatus =:= NewStatus -> %% Cancel event timeout @@ -1765,7 +1774,7 @@ performTransitions(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers _ -> lists:reverse(NextEs, LeftEvents) end, - performEvents(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, [CurEvent | Postponed], Timers, NewStatus, CurState, NewDebug, LastLeftEvents, IsHib, DoAfter); + performEvents(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, [CurEvent | Postponed], Timers, NewStatus, CurState, Debug, LastLeftEvents, IsHib, DoAfter); true -> LastLeftEvents = case NextEs of @@ -1778,7 +1787,7 @@ performTransitions(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers _ -> lists:reverse(NextEs, LeftEvents) end, - performEvents(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, NewStatus, CurState, NewDebug, LastLeftEvents, IsHib, DoAfter) + performEvents(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, NewStatus, CurState, Debug, LastLeftEvents, IsHib, DoAfter) end; true -> %% 状态发生改变 重试推迟的事件 @@ -1806,7 +1815,7 @@ performTransitions(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers _ -> lists:reverse(NextEs, NewLeftEvents) end, - performEvents(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, [], Timers, NewStatus, CurState, NewDebug, LastLeftEvents, IsHib, DoAfter); + performEvents(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, [], Timers, NewStatus, CurState, Debug, LastLeftEvents, IsHib, DoAfter); true -> NewLeftEvents = case Postponed of @@ -1830,21 +1839,21 @@ performTransitions(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers _ -> lists:reverse(NextEs, NewLeftEvents) end, - performEvents(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, [], Timers, NewStatus, CurState, NewDebug, LastLeftEvents, IsHib, DoAfter) + performEvents(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, [], Timers, NewStatus, CurState, Debug, LastLeftEvents, IsHib, DoAfter) end end. %% 状态转换已完成,如果有排队事件,则继续循环,否则获取新事件 -performEvents(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, IsHib, DoAfter) -> +performEvents(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, IsHib, DoAfter) -> % io:format("loop_done: status_data = ~p ~n postponed = ~p LeftEvents = ~p ~n timers = ~p.~n", [S#status.status_data,,S#status.postponed,LeftEvents,S#status.timers]), case DoAfter of {true, Args} -> %% 这里 IsHib设置会被丢弃 按照gen_server中的设计 continue 和 hiernate是互斥的 - startAfterCall(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Args); + startAfterCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Args); _ -> case LeftEvents of [] -> - reLoopEntry(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, IsHib); + reLoopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, IsHib); [Event | _Events] -> %% 循环直到没有排队事件 if @@ -1854,7 +1863,7 @@ performEvents(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Pos true -> ignore end, - startEventCall(Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Event) + startEventCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents, Event) end end. @@ -1957,15 +1966,15 @@ cancelTimer(TimeoutType, TimerRef, Timers) -> %% {Events, Debug}; %% mergeTimeoutEvents([{eTimeout, _} = TimeoutEvent | TimeoutEvents], Status, CycleData, Debug, []) -> %% %% 由于队列中没有其他事件,因此添加该事件零超时事件 -%% NewDebug = ?SYS_DEBUG(Debug, CycleData, {insert_timeout, TimeoutEvent, Status}), -%% mergeTimeoutEvents(TimeoutEvents, Status, CycleData, NewDebug, [TimeoutEvent]); +%% ?SYS_DEBUG(Debug, CycleData, {insert_timeout, TimeoutEvent, Status}), +%% mergeTimeoutEvents(TimeoutEvents, Status, CycleData, Debug, [TimeoutEvent]); %% mergeTimeoutEvents([{eTimeout, _} | TimeoutEvents], Status, CycleData, Debug, Events) -> %% %% 忽略,因为队列中还有其他事件,因此它们取消了事件超时0。 %% mergeTimeoutEvents(TimeoutEvents, Status, CycleData, Debug, Events); %% mergeTimeoutEvents([TimeoutEvent | TimeoutEvents], Status, CycleData, Debug, Events) -> %% %% Just prepend all others -%% NewDebug = ?SYS_DEBUG(Debug, CycleData, {insert_timeout, TimeoutEvent, Status}), -%% mergeTimeoutEvents(TimeoutEvents, Status, CycleData, NewDebug, [TimeoutEvent | Events]). +%% ?SYS_DEBUG(Debug, CycleData, {insert_timeout, TimeoutEvent, Status}), +%% mergeTimeoutEvents(TimeoutEvents, Status, CycleData, Debug, [TimeoutEvent | Events]). %% Return a list of all pending timeouts listTimeouts(Timers) -> @@ -1980,6 +1989,28 @@ allTimer(Iterator, Acc) -> end. %%--------------------------------------------------------------------------- +innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, MsgEvent, Class, Reason, Stacktrace) -> + case GbhOpts of + #gbhOpts{daemon = true} -> + error_msg({innerError, {Class, Reason, Stacktrace}}, Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, MsgEvent), + case erlang:function_exported(Module, handleError, 2) of + true -> + try Module:handleError({Class, Reason, Stacktrace}, CurState) of + Result -> + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, [MsgEvent], Result, ?CB_FORM_EVENT, false) + catch + throw:Result -> + handleEventCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, [MsgEvent], Result, ?CB_FORM_EVENT, false); + IClass:IReason:IStrace -> + error_msg({handleError, {IClass, IReason, IStrace}}, Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, {Class, Reason, Stacktrace}), + kpS + end; + false -> + kpS + end; + _ -> + terminate(Class, Reason, Stacktrace, Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, MsgEvent) + end. terminate(Class, Reason, Stacktrace, Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents) -> epmStopAll(EpmHers), @@ -2036,6 +2067,29 @@ error_info(Class, Reason, Stacktrace, Parent, Name, Module, HibernateAfterTimeou report_cb => fun gen_ipc:format_log/2, error_logger => #{tag => error, report_cb => fun gen_ipc:format_log/1}}). +error_msg(Reason, Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState, Debug, LeftEvents) -> + Log = sys:get_log(Debug), + ?LOG_ERROR( + #{ + label => {gen_ipc, inner_error}, + name => Name, + module => Module, + queue => LeftEvents, + postponed => Postponed, + isEnter => IsEnter, + status => format_status(inner_error, get(), Parent, Name, Module, HibernateAfterTimeout, IsEnter, EpmHers, Postponed, Timers, CurStatus, CurState), + timeouts => listTimeouts(Timers), + log => Log, + reason => Reason, + client_info => cliStacktrace(LeftEvents) + }, + #{ + domain => [otp], + report_cb => fun gen_ipc:format_log/2, + error_logger => #{tag => error, report_cb => fun gen_ipc:format_log/1}}). + + + cliStacktrace([]) -> undefined; cliStacktrace([{{call, {Pid, _Tag}}, _Req} | _]) when is_pid(Pid) -> diff --git a/src/gen_mpp.erl b/src/gen_mpp.erl index a798020..9aff8aa 100644 --- a/src/gen_mpp.erl +++ b/src/gen_mpp.erl @@ -1295,7 +1295,7 @@ mod(_) -> "t". %% Status information %%----------------------------------------------------------------- format_status(Opt, StatusData) -> - [PDict, SysState, Parent, Debug, {Name, Module, _HibernateAfterTimeout, _Timers, CurState, _IsHib}] = StatusData, + [PDict, SysState, Parent, Debug, {Name, Module, _GbhOpts, _HibernateAfterTimeout, _Timers, CurState, _IsHib}] = StatusData, Header = gen:format_status_header("Status for generic server", Name), Log = sys:get_log(Debug), Specific = diff --git a/src/gen_srv.erl b/src/gen_srv.erl index 0abf10d..69a1679 100644 --- a/src/gen_srv.erl +++ b/src/gen_srv.erl @@ -153,6 +153,7 @@ -optional_callbacks([ handleAfter/2 + , handleError/2 , terminate/2 , code_change/3 , formatStatus/2 @@ -1368,7 +1369,7 @@ mod(_) -> "t". %% Status information %%----------------------------------------------------------------- format_status(Opt, StatusData) -> - [PDict, SysState, Parent, Debug, {Name, Module, _HibernateAfterTimeout, _Timers, CurState, _IsHib}] = StatusData, + [PDict, SysState, Parent, Debug, {Name, Module, _GbhOpts, _HibernateAfterTimeout, _Timers, CurState, _IsHib}] = StatusData, Header = gen:format_status_header("Status for generic server", Name), Log = sys:get_log(Debug), Specific =