diff --git a/src/gen_ipc.erl b/src/gen_ipc.erl index 79c1d63..2be1e7f 100644 --- a/src/gen_ipc.erl +++ b/src/gen_ipc.erl @@ -47,6 +47,19 @@ -export([receiveIng/6]). +% 简写备注********************************** +% isPostpone isPos +% isHibernate isHib +% +% nextEvent nextE +% nextStatus nextS +% +% keepStatus kpS +% keepStatusState kpS_S +% repeatStatus reS +% repeatStatusState reS_S +% ***************************************** + % %% timeout相关宏定义 % -define(REL_TIMEOUT(T), ((is_integer(T) andalso (T) >= 0) orelse (T) =:= infinity)). % -define(ABS_TIMEOUT(T), (is_integer(T) orelse (T) =:= infinity)). @@ -84,9 +97,9 @@ %% 是否允许进入enter 回调 -type isEnter() :: boolean(). %% 如果为 "true" 则推迟当前事件,并在状态更改时重试(=/=) --type isPostpone() :: boolean(). +-type isPos() :: boolean(). %% 如果为 "true" 则使服务器休眠而不是进入接收状态 --type isHibernate() :: boolean(). +-type isHib() :: boolean(). %% 定时器相关 -type timeouts() :: Time :: timeout() | integer(). @@ -106,26 +119,26 @@ %% 如果有postponed 事件则 事件执行顺序为 超时添加和更新 + 零超时 + 当前事件 + 反序的Postpone事件 + LeftEvent %% 处理待处理的事件,或者如果没有待处理的事件,则服务器进入接收或休眠状态(当“hibernate”为“ true”时) -type initAction() :: -{trap_exit, Bool :: isTrapExit()} | % 设置是否捕捉信息 主要用于gen_event模式下 +{trap_exit, Bool :: isTrapExit()} | % 设置是否捕捉信息 主要用于gen_event模式下 eventAction(). -type eventAction() :: {'doAfter', Args :: term()} | % 设置执行某事件后是否回调 handleAfter - {'isPostpone', Bool :: isPostpone()} | % 设置推迟选项 - {'nextEvent', EventType :: eventType(), EventContent :: term()} | % 插入事件作为下一个处理 + {'isPos', Bool :: isPos()} | % 设置推迟选项 + {'nextE', EventType :: eventType(), EventContent :: term()} | % 插入事件作为下一个处理 commonAction(). -type afterAction() :: - {'nextEvent', EventType :: eventType(), EventContent :: term()} | % 插入事件作为下一个处理 + {'nextE', EventType :: eventType(), EventContent :: term()} | % 插入事件作为下一个处理 commonAction(). -type enterAction() :: - {'isPostpone', false} | % 虽然enter action 不能设置postpone 但是可以取消之前event的设置 + {'isPos', false} | % 虽然enter action 不能设置postpone 但是可以取消之前event的设置 commonAction(). -type commonAction() :: {'isEnter', Bool :: isEnter()} | - {'isHibernate', Bool :: isHibernate()} | + {'isHib', Bool :: isHib()} | timeoutAction() | replyAction(). @@ -162,13 +175,13 @@ eventAction(). {'reply', Reply :: term(), NewState :: term(), Options :: hibernate | {doAfter, Args}} | % 用作gen_server模式时快速响应进入消息接收 {'sreply', Reply :: term(), NextStatus :: term(), NewState :: term(), Actions :: [eventAction(), ...]} | % 用作gen_ipc模式便捷式返回reply 而不用把reply放在actions列表中 {'noreply', NewState :: term(), Options :: hibernate | {doAfter, Args}} | % 用作gen_server模式时快速响应进入循环 - {'nextStatus', NextStatus :: term(), NewState :: term()} | % {next_status,NextStatus,NewData,[]} - {'nextStatus', NextStatus :: term(), NewState :: term(), Actions :: [eventAction(), ...]} | % Status transition, maybe to the same status + {'nextS', NextStatus :: term(), NewState :: term()} | % {next_status,NextS,NewData,[]} + {'nextS', NextStatus :: term(), NewState :: term(), Actions :: [eventAction(), ...]} | % Status transition, maybe to the same status commonCallbackResult(eventAction()). -type afterCallbackResult() :: - {'nextStatus', NextStatus :: term(), NewState :: term()} | % {next_status,NextStatus,NewData,[]} - {'nextStatus', NextStatus :: term(), NewState :: term(), Actions :: [afterAction(), ...]} | % Status transition, maybe to the same status + {'nextS', NextStatus :: term(), NewState :: term()} | % {next_status,NextS,NewData,[]} + {'nextS', NextStatus :: term(), NewState :: term(), Actions :: [afterAction(), ...]} | % Status transition, maybe to the same status {'noreply', NewState :: term()} | % 用作gen_server模式时快速响应进入消息接收 {'noreply', NewState :: term(), Options :: hibernate} | % 用作gen_server模式时快速响应进入消息接收 commonCallbackResult(afterAction()). @@ -177,14 +190,14 @@ eventAction(). commonCallbackResult(enterAction()). -type commonCallbackResult(ActionType) :: - {'keepStatus', NewState :: term()} | % {keep_status,NewData,[]} - {'keepStatus', NewState :: term(), Actions :: [ActionType]} | % Keep status, change data - 'keepStatusState' | % {keep_status_and_data,[]} - {'keepStatusState', Actions :: [ActionType]} | % Keep status and data -> only actions - {'repeatStatus', NewState :: term()} | % {repeat_status,NewData,[]} - {'repeatStatus', NewState :: term(), Actions :: [ActionType]} | % Repeat status, change data - 'repeatStatusState' | % {repeat_status_and_data,[]} - {'repeatStatusState', Actions :: [ActionType]} | % Repeat status and data -> only actions + {'kpS', NewState :: term()} | % {keep_status,NewData,[]} + {'kpS', NewState :: term(), Actions :: [ActionType]} | % Keep status, change data + 'kpS_S' | % {keep_status_and_data,[]} + {'kpS_S', Actions :: [ActionType]} | % Keep status and data -> only actions + {'reS', NewState :: term()} | % {repeat_status,NewData,[]} + {'reS', NewState :: term(), Actions :: [ActionType]} | % Repeat status, change data + 'reS_S' | % {repeat_status_and_data,[]} + {'reS_S', Actions :: [ActionType]} | % Repeat status and data -> only actions 'stop' | % {stop,normal} {'stop', Reason :: term()} | % Stop the server {'stop', Reason :: term(), NewState :: term()} | % Stop the server @@ -223,7 +236,7 @@ eventAction(). -callback handleInfo(EventContent :: term(), Status :: term(), State :: term()) -> eventCallbackResult(). -%% 内部事件 Onevent 包括actions 设置的定时器超时产生的事件 和 nextEvent产生的超时事件 但是不是 call cast info 回调函数 以及其他自定义定时事件 的回调函数 +%% 内部事件 Onevent 包括actions 设置的定时器超时产生的事件 和 nextE产生的超时事件 但是不是 call cast info 回调函数 以及其他自定义定时事件 的回调函数 %% 并且这里需要注意 其他erlang:start_timer生成超时事件发送的消息 不能和gen_ipc定时器关键字重合 有可能会导致一些问题 -callback handleOnevent(EventType :: term(), EventContent :: term(), Status :: term(), State :: term()) -> eventCallbackResult(). @@ -452,24 +465,24 @@ loopEntry(Parent, Debug, Module, Name, HibernateAfterTimeout, CurStatus, CurStat CycleData = #cycleData{parent = Parent, name = Name, hibernateAfter = HibernateAfterTimeout}, NewDebug = ?SYS_DEBUG(Debug, CycleData, {enter, CurStatus}), %% 强制执行{postpone,false}以确保我们的假事件被丢弃 - LastActions = MewActions ++ [{isPostpone, false}], + LastActions = MewActions ++ [{isPos, false}], parseEventAL(CycleData, Module, CurStatus, CurState, CurStatus, NewDebug, [{onevent, init_status}], true, LastActions, ?CB_FORM_EVENT). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% sys callbacks start %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -system_continue(Parent, Debug, {CycleData, Module, CurStatus, CurState, IsHibernate}) -> +system_continue(Parent, Debug, {CycleData, Module, CurStatus, CurState, IsHib}) -> NewCycleData = updateParent(Parent, CycleData), if - IsHibernate -> - proc_lib:hibernate(?MODULE, wakeupFromHib, [NewCycleData, Module, CurStatus, CurState, Debug, IsHibernate]); + IsHib -> + proc_lib:hibernate(?MODULE, wakeupFromHib, [NewCycleData, Module, CurStatus, CurState, Debug, IsHib]); true -> - ?MODULE:receiveIng(NewCycleData, Module, CurStatus, CurState, Debug, IsHibernate) + ?MODULE:receiveIng(NewCycleData, Module, CurStatus, CurState, Debug, IsHib) end. -system_terminate(Reason, Parent, Debug, {CycleData, Module, CurStatus, CurState, _IsHibernate}) -> +system_terminate(Reason, Parent, Debug, {CycleData, Module, CurStatus, CurState, _IsHib}) -> NewCycleData = updateParent(Parent, CycleData), terminate(exit, Reason, ?STACKTRACE(), NewCycleData, Module, CurStatus, CurState, Debug, []). -system_code_change({CycleData, Module, CurStatus, CurState, IsHibernate}, _Mod, OldVsn, Extra) -> +system_code_change({CycleData, Module, CurStatus, CurState, IsHib}, _Mod, OldVsn, Extra) -> case try Module:code_change(OldVsn, CurStatus, CurState, Extra) catch @@ -477,19 +490,19 @@ system_code_change({CycleData, Module, CurStatus, CurState, IsHibernate}, _Mod, end of {ok, NewStatus, NewState} -> - {ok, {CycleData, Module, NewStatus, NewState, IsHibernate}}; + {ok, {CycleData, Module, NewStatus, NewState, IsHib}}; Error -> Error end. -system_get_state({_CycleData, _Module, CurStatus, CurState, _IsHibernate}) -> +system_get_state({_CycleData, _Module, CurStatus, CurState, _IsHib}) -> {ok, {CurStatus, CurState}}. -system_replace_state(StatusFun, {CycleData, Module, CurStatus, CurState, IsHibernate}) -> +system_replace_state(StatusFun, {CycleData, Module, CurStatus, CurState, IsHib}) -> {NewStatus, NewState} = StatusFun(CurStatus, CurState), - {ok, {NewStatus, NewState}, {CycleData, Module, NewStatus, NewState, IsHibernate}}. + {ok, {NewStatus, NewState}, {CycleData, Module, NewStatus, NewState, IsHib}}. -format_status(Opt, [PDict, SysStatus, Parent, Debug, {#cycleData{name = Name, timers = Timers, postponed = Postponed} = CycleData, Module, CurStatus, CurState, _IsHibernate}]) -> +format_status(Opt, [PDict, SysStatus, Parent, Debug, {#cycleData{name = Name, timers = Timers, postponed = Postponed} = CycleData, Module, CurStatus, CurState, _IsHib}]) -> Header = gen:format_status_header("Status for gen_ipc", Name), NewCycleData = updateParent(Parent, CycleData), Log = sys:get_log(Debug), @@ -1114,22 +1127,22 @@ updateParent(Parent, #cycleData{parent = OldParent} = CycleData) -> end. %%%========================================================================== %%% Internal callbacks -wakeupFromHib(CycleData, Module, CurStatus, CurState, Debug, IsHibernate) -> +wakeupFromHib(CycleData, Module, CurStatus, CurState, Debug, IsHib) -> %% 这是一条新消息,唤醒了我们,因此我们必须立即收到它 - ?MODULE:receiveIng(CycleData, Module, CurStatus, CurState, Debug, IsHibernate). + ?MODULE:receiveIng(CycleData, Module, CurStatus, CurState, Debug, IsHib). %%%========================================================================== %% Entry point for system_continue/3 -reLoopEntry(CycleData, Module, CurStatus, CurState, Debug, IsHibernate) -> +reLoopEntry(CycleData, Module, CurStatus, CurState, Debug, IsHib) -> if - IsHibernate -> - proc_lib:hibernate(?MODULE, wakeupFromHib, [CycleData, Module, CurStatus, CurState, Debug, IsHibernate]); + IsHib -> + proc_lib:hibernate(?MODULE, wakeupFromHib, [CycleData, Module, CurStatus, CurState, Debug, IsHib]); true -> - ?MODULE:receiveIng(CycleData, Module, CurStatus, CurState, Debug, IsHibernate) + ?MODULE:receiveIng(CycleData, Module, CurStatus, CurState, Debug, IsHib) end. %% 接收新的消息 -receiveIng(#cycleData{parent = Parent, hibernateAfter = HibernateAfterTimeout, timers = Timers, epmHers = EpmHers} = CycleData, Module, CurStatus, CurState, Debug, IsHibernate) -> +receiveIng(#cycleData{parent = Parent, hibernateAfter = HibernateAfterTimeout, timers = Timers, epmHers = EpmHers} = CycleData, Module, CurStatus, CurState, Debug, IsHib) -> receive Msg -> case Msg of @@ -1148,7 +1161,7 @@ receiveIng(#cycleData{parent = Parent, hibernateAfter = HibernateAfterTimeout, t end; {system, PidFrom, Request} -> %% 不返回但尾递归调用 system_continue/3 - sys:handle_system_msg(Request, PidFrom, Parent, ?MODULE, Debug, {CycleData, Module, CurStatus, CurState, IsHibernate}, IsHibernate); + sys:handle_system_msg(Request, PidFrom, Parent, ?MODULE, Debug, {CycleData, Module, CurStatus, CurState, IsHib}, IsHib); {'EXIT', PidFrom, Reason} -> case Parent =:= PidFrom of true -> @@ -1166,7 +1179,7 @@ receiveIng(#cycleData{parent = Parent, hibernateAfter = HibernateAfterTimeout, t end after HibernateAfterTimeout -> - proc_lib:hibernate(?MODULE, wakeupFromHib, [CycleData, Module, CurStatus, CurState, Debug, IsHibernate]) + proc_lib:hibernate(?MODULE, wakeupFromHib, [CycleData, Module, CurStatus, CurState, Debug, IsHib]) end. matchCallMsg(CycleData, Module, CurStatus, CurState, Debug, From, Request) -> @@ -1283,13 +1296,13 @@ startEpmCall(CycleData, Module, CurStatus, CurState, Debug, CallbackFun, Event, ?MODULE:receiveIng(CycleData, Module, CurStatus, CurState, Debug, IsHib) end. -startEnterCall(CycleData, Module, PrevStatus, CurState, CurStatus, Debug, LeftEvents, Timeouts, NextEvents, IsPostpone, IsHibernate, DoAfter) -> +startEnterCall(CycleData, Module, PrevStatus, CurState, CurStatus, Debug, LeftEvents, Timeouts, NextEs, IsPos, IsHib, DoAfter) -> try Module:handleEnter(PrevStatus, CurStatus, CurState) of Result -> - handleEnterCR(CycleData, Module, PrevStatus, CurState, CurStatus, Debug, LeftEvents, Timeouts, NextEvents, IsPostpone, IsHibernate, DoAfter, Result) + handleEnterCR(CycleData, Module, PrevStatus, CurState, CurStatus, Debug, LeftEvents, Timeouts, NextEs, IsPos, IsHib, DoAfter, Result) catch throw:Result -> - handleEnterCR(CycleData, Module, PrevStatus, CurState, CurStatus, Debug, LeftEvents, Timeouts, NextEvents, IsPostpone, IsHibernate, DoAfter, Result); + handleEnterCR(CycleData, Module, PrevStatus, CurState, CurStatus, Debug, LeftEvents, Timeouts, NextEs, IsPos, IsHib, DoAfter, Result); Class:Reason:Stacktrace -> terminate(Class, Reason, Stacktrace, CycleData, Module, CurStatus, CurState, Debug, LeftEvents) end. @@ -1409,24 +1422,24 @@ handleEpmCR(Result, EpmHers, #epmHer{epmId = EpmId} = EpmHer, Event, From) -> end. %% handleEnterCallbackRet -handleEnterCR(CycleData, Module, PrevStatus, CurState, CurStatus, Debug, LeftEvents, Timeouts, NextEvents, IsPostpone, IsHibernate, DoAfter, Result) -> +handleEnterCR(CycleData, Module, PrevStatus, CurState, CurStatus, Debug, LeftEvents, Timeouts, NextEs, IsPos, IsHib, DoAfter, Result) -> case Result of - {keepStatus, NewState} -> - dealEnterCR(CycleData, Module, PrevStatus, NewState, CurStatus, Debug, LeftEvents, Timeouts, NextEvents, IsPostpone, IsHibernate, DoAfter, false); - {keepStatus, NewState, Actions} -> - parseEnterAL(CycleData, Module, PrevStatus, NewState, CurStatus, Debug, LeftEvents, Timeouts, NextEvents, IsPostpone, IsHibernate, DoAfter, false, Actions); - keepStatusState -> - dealEnterCR(CycleData, Module, PrevStatus, CurState, CurStatus, Debug, LeftEvents, Timeouts, NextEvents, IsPostpone, IsHibernate, DoAfter, false); - {keepStatusState, Actions} -> - parseEnterAL(CycleData, Module, PrevStatus, CurState, CurStatus, Debug, LeftEvents, Timeouts, NextEvents, IsPostpone, IsHibernate, DoAfter, false, Actions); - {repeatStatus, NewState} -> - dealEnterCR(CycleData, Module, PrevStatus, NewState, CurStatus, Debug, LeftEvents, Timeouts, NextEvents, IsPostpone, IsHibernate, DoAfter, true); - {repeatStatus, NewState, Actions} -> - parseEnterAL(CycleData, Module, PrevStatus, NewState, CurStatus, Debug, LeftEvents, Timeouts, NextEvents, IsPostpone, IsHibernate, DoAfter, true, Actions); - repeatStatusState -> - dealEnterCR(CycleData, Module, PrevStatus, CurState, CurStatus, Debug, LeftEvents, Timeouts, NextEvents, IsPostpone, IsHibernate, DoAfter, true); - {repeatStatusState, Actions} -> - parseEnterAL(CycleData, Module, PrevStatus, CurState, CurStatus, Debug, LeftEvents, Timeouts, NextEvents, IsPostpone, IsHibernate, DoAfter, true, Actions); + {kpS, NewState} -> + dealEnterCR(CycleData, Module, PrevStatus, NewState, CurStatus, Debug, LeftEvents, Timeouts, NextEs, IsPos, IsHib, DoAfter, false); + {kpS, NewState, Actions} -> + parseEnterAL(CycleData, Module, PrevStatus, NewState, CurStatus, Debug, LeftEvents, Timeouts, NextEs, IsPos, IsHib, DoAfter, false, Actions); + kpS_S -> + dealEnterCR(CycleData, Module, PrevStatus, CurState, CurStatus, Debug, LeftEvents, Timeouts, NextEs, IsPos, IsHib, DoAfter, false); + {kpS_S, Actions} -> + parseEnterAL(CycleData, Module, PrevStatus, CurState, CurStatus, Debug, LeftEvents, Timeouts, NextEs, IsPos, IsHib, DoAfter, false, Actions); + {reS, NewState} -> + dealEnterCR(CycleData, Module, PrevStatus, NewState, CurStatus, Debug, LeftEvents, Timeouts, NextEs, IsPos, IsHib, DoAfter, true); + {reS, NewState, Actions} -> + parseEnterAL(CycleData, Module, PrevStatus, NewState, CurStatus, Debug, LeftEvents, Timeouts, NextEs, IsPos, IsHib, DoAfter, true, Actions); + reS_S -> + dealEnterCR(CycleData, Module, PrevStatus, CurState, CurStatus, Debug, LeftEvents, Timeouts, NextEs, IsPos, IsHib, DoAfter, true); + {reS_S, Actions} -> + parseEnterAL(CycleData, Module, PrevStatus, CurState, CurStatus, Debug, LeftEvents, Timeouts, NextEs, IsPos, IsHib, DoAfter, true, Actions); stop -> terminate(exit, normal, ?STACKTRACE(), CycleData, Module, CurStatus, CurState, Debug, LeftEvents); {stop, Reason} -> @@ -1477,25 +1490,25 @@ handleEventCR(CycleData, Module, CurStatus, CurState, Debug, LeftEvents, Result, reply(From, Reply), NewDebug = ?SYS_DEBUG(Debug, CycleData, {out, Reply, From}), parseEventAL(CycleData, Module, CurStatus, NewState, NewStatus, NewDebug, LeftEvents, NewStatus =/= CurStatus, Actions, CallbackForm); - {nextStatus, NewStatus, NewState} -> + {nextS, NewStatus, NewState} -> dealEventCR(CycleData, Module, CurStatus, NewState, NewStatus, Debug, LeftEvents, NewStatus =/= CurStatus); - {nextStatus, NewStatus, NewState, Actions} -> + {nextS, NewStatus, NewState, Actions} -> parseEventAL(CycleData, Module, CurStatus, NewState, NewStatus, Debug, LeftEvents, NewStatus =/= CurStatus, Actions, CallbackForm); - {keepStatus, NewState} -> + {kpS, NewState} -> dealEventCR(CycleData, Module, CurStatus, NewState, CurStatus, Debug, LeftEvents, false); - {keepStatus, NewState, Actions} -> + {kpS, NewState, Actions} -> parseEventAL(CycleData, Module, CurStatus, NewState, CurStatus, Debug, LeftEvents, false, Actions, CallbackForm); - keepStatusState -> + kpS_S -> dealEventCR(CycleData, Module, CurStatus, CurState, CurStatus, Debug, LeftEvents, false); - {keepStatusState, Actions} -> + {kpS_S, Actions} -> parseEventAL(CycleData, Module, CurStatus, CurState, CurStatus, Debug, LeftEvents, false, Actions, CallbackForm); - {repeatStatus, NewState} -> + {reS, NewState} -> dealEventCR(CycleData, Module, CurStatus, NewState, CurStatus, Debug, LeftEvents, true); - {repeatStatus, NewState, Actions} -> + {reS, NewState, Actions} -> parseEventAL(CycleData, Module, CurStatus, NewState, CurStatus, Debug, LeftEvents, true, Actions, CallbackForm); - repeatStatusState -> + reS_S -> dealEventCR(CycleData, Module, CurStatus, CurState, CurStatus, Debug, LeftEvents, true); - {repeatStatusState, Actions} -> + {reS_S, Actions} -> parseEventAL(CycleData, Module, CurStatus, CurState, CurStatus, Debug, LeftEvents, true, Actions, CallbackForm); stop -> terminate(exit, normal, ?STACKTRACE(), CycleData, Module, CurStatus, CurState, Debug, LeftEvents); @@ -1511,12 +1524,12 @@ handleEventCR(CycleData, Module, CurStatus, CurState, Debug, LeftEvents, Result, terminate(error, {bad_handleEventCR, Result}, ?STACKTRACE(), CycleData, Module, CurStatus, CurState, Debug, LeftEvents) end. -dealEnterCR(#cycleData{isEnter = IsEnter} = CycleData, Module, CurStatus, CurState, NewStatus, Debug, LeftEvents, Timeouts, NextEvents, IsPostpone, IsHibernate, DoAfter, IsCallEnter) -> +dealEnterCR(#cycleData{isEnter = IsEnter} = CycleData, Module, CurStatus, CurState, NewStatus, Debug, LeftEvents, Timeouts, NextEs, IsPos, IsHib, DoAfter, IsCallEnter) -> case IsEnter andalso IsCallEnter of true -> - startEnterCall(CycleData, Module, CurStatus, CurState, NewStatus, Debug, LeftEvents, Timeouts, NextEvents, IsPostpone, IsHibernate, DoAfter); + startEnterCall(CycleData, Module, CurStatus, CurState, NewStatus, Debug, LeftEvents, Timeouts, NextEs, IsPos, IsHib, DoAfter); false -> - performTransitions(CycleData, Module, CurStatus, CurState, NewStatus, Debug, LeftEvents, Timeouts, NextEvents, IsPostpone, IsHibernate, DoAfter) + performTransitions(CycleData, Module, CurStatus, CurState, NewStatus, Debug, LeftEvents, Timeouts, NextEs, IsPos, IsHib, DoAfter) end. %% dealEventCallbackRet @@ -1530,26 +1543,26 @@ dealEventCR(#cycleData{isEnter = IsEnter} = CycleData, Module, CurStatus, CurSta %% 处理enter callback 动作列表 %% parseEnterActionsList -parseEnterAL(CycleData, Module, CurStatus, CurState, NewStatus, Debug, LeftEvents, Timeouts, NextEvents, IsPostpone, IsCallEnter, IsHibernate, DoAfter, Actions) -> - %% enter 调用不能改成状态 actions 不能返回 IsPostpone = true 但是可以取消之前的推迟 设置IsPostpone = false 不能设置 doafter 不能插入事件 +parseEnterAL(CycleData, Module, CurStatus, CurState, NewStatus, Debug, LeftEvents, Timeouts, NextEs, IsPos, IsCallEnter, IsHib, DoAfter, Actions) -> + %% enter 调用不能改成状态 actions 不能返回 IsPos = true 但是可以取消之前的推迟 设置IsPos = false 不能设置 doafter 不能插入事件 case Actions of [] -> case IsCallEnter andalso element(#cycleData.isEnter, CycleData) of true -> - startEnterCall(CycleData, Module, CurStatus, CurState, NewStatus, Debug, LeftEvents, Timeouts, NextEvents, IsPostpone, IsHibernate, DoAfter); + startEnterCall(CycleData, Module, CurStatus, CurState, NewStatus, Debug, LeftEvents, Timeouts, NextEs, IsPos, IsHib, DoAfter); _ -> - performTransitions(CycleData, Module, CurStatus, CurState, NewStatus, Debug, LeftEvents, Timeouts, NextEvents, IsPostpone, IsHibernate, DoAfter) + performTransitions(CycleData, Module, CurStatus, CurState, NewStatus, Debug, LeftEvents, Timeouts, NextEs, IsPos, IsHib, DoAfter) end; _ -> - case doParseAL(Actions, ?CB_FORM_ENTER, CycleData, Debug, IsPostpone, IsHibernate, DoAfter, Timeouts, NextEvents) of + case doParseAL(Actions, ?CB_FORM_ENTER, CycleData, Debug, IsPos, IsHib, DoAfter, Timeouts, NextEs) of {error, ErrorContent} -> terminate(error, ErrorContent, ?STACKTRACE(), CycleData, Module, CurStatus, CurState, Debug, LeftEvents); - {NewCycleData, NewDebug, NewIsPostpone, NewIsHibernate, DoAfter, NewTimeouts, NewNextEvents} -> + {NewCycleData, NewDebug, NewIsPos, NewIsHib, DoAfter, NewTimeouts, NewNextEs} -> case IsCallEnter andalso element(#cycleData.isEnter, NewCycleData) of true -> - startEnterCall(NewCycleData, Module, CurStatus, CurState, NewStatus, NewDebug, LeftEvents, NewTimeouts, NewNextEvents, NewIsPostpone, NewIsHibernate, DoAfter); + startEnterCall(NewCycleData, Module, CurStatus, CurState, NewStatus, NewDebug, LeftEvents, NewTimeouts, NewNextEs, NewIsPos, NewIsHib, DoAfter); _ -> - performTransitions(NewCycleData, Module, CurStatus, CurState, NewStatus, NewDebug, LeftEvents, NewTimeouts, NewNextEvents, NewIsPostpone, NewIsHibernate, DoAfter) + performTransitions(NewCycleData, Module, CurStatus, CurState, NewStatus, NewDebug, LeftEvents, NewTimeouts, NewNextEs, NewIsPos, NewIsHib, DoAfter) end end end. @@ -1569,67 +1582,67 @@ parseEventAL(CycleData, Module, CurStatus, CurState, NewStatus, Debug, LeftEvent case doParseAL(Actions, CallbackForm, CycleData, Debug, false, false, false, [], []) of {error, ErrorContent} -> terminate(error, ErrorContent, ?STACKTRACE(), CycleData, Module, CurStatus, CurState, Debug, []); - {NewCycleData, NewDebug, NewIsPostpone, NewIsHibernate, MewDoAfter, NewTimeouts, NewNextEvents} -> + {NewCycleData, NewDebug, NewIsPos, NewIsHib, MewDoAfter, NewTimeouts, NewNextEs} -> case IsCallEnter andalso element(#cycleData.isEnter, NewCycleData) of true -> - startEnterCall(NewCycleData, Module, CurStatus, CurState, NewStatus, NewDebug, LeftEvents, NewTimeouts, NewNextEvents, NewIsPostpone, NewIsHibernate, MewDoAfter); + startEnterCall(NewCycleData, Module, CurStatus, CurState, NewStatus, NewDebug, LeftEvents, NewTimeouts, NewNextEs, NewIsPos, NewIsHib, MewDoAfter); _ -> - performTransitions(NewCycleData, Module, CurStatus, CurState, NewStatus, NewDebug, LeftEvents, NewTimeouts, NewNextEvents, NewIsPostpone, NewIsHibernate, MewDoAfter) + performTransitions(NewCycleData, Module, CurStatus, CurState, NewStatus, NewDebug, LeftEvents, NewTimeouts, NewNextEs, NewIsPos, NewIsHib, MewDoAfter) end end end. %% loopParseActionsList -doParseAL([], _CallbackForm, CycleData, Debug, IsPostpone, IsHibernate, DoAfter, Timeouts, NextEvents) -> - {CycleData, Debug, IsPostpone, IsHibernate, DoAfter, Timeouts, NextEvents}; -doParseAL([OneAction | LeftActions], CallbackForm, CycleData, Debug, IsPostpone, IsHibernate, DoAfter, Timeouts, NextEvents) -> +doParseAL([], _CallbackForm, CycleData, Debug, IsPos, IsHib, DoAfter, Timeouts, NextEs) -> + {CycleData, Debug, IsPos, IsHib, DoAfter, Timeouts, NextEs}; +doParseAL([OneAction | LeftActions], CallbackForm, CycleData, Debug, IsPos, IsHib, DoAfter, Timeouts, NextEs) -> case OneAction of {reply, From, Reply} -> reply(From, Reply), NewDebug = ?SYS_DEBUG(Debug, CycleData, {out, Reply, From}), - doParseAL(LeftActions, CallbackForm, CycleData, NewDebug, IsPostpone, IsHibernate, DoAfter, Timeouts, NextEvents); + doParseAL(LeftActions, CallbackForm, CycleData, NewDebug, IsPos, IsHib, DoAfter, Timeouts, NextEs); {eTimeout, _Time, _TimeoutMsg} -> - doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPostpone, IsHibernate, DoAfter, [OneAction | Timeouts], NextEvents); + doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPos, IsHib, DoAfter, [OneAction | Timeouts], NextEs); {sTimeout, _Time, _TimeoutMsg} -> - doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPostpone, IsHibernate, DoAfter, [OneAction | Timeouts], NextEvents); + doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPos, IsHib, DoAfter, [OneAction | Timeouts], NextEs); {{gTimeout, _Name}, _Time, _TimeoutMsg} -> - doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPostpone, IsHibernate, DoAfter, [OneAction | Timeouts], NextEvents); + doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPos, IsHib, DoAfter, [OneAction | Timeouts], NextEs); {eTimeout, _Time, _TimeoutMsg, _Options} -> - doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPostpone, IsHibernate, DoAfter, [OneAction | Timeouts], NextEvents); + doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPos, IsHib, DoAfter, [OneAction | Timeouts], NextEs); {sTimeout, _Time, _TimeoutMsg, _Options} -> - doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPostpone, IsHibernate, DoAfter, [OneAction | Timeouts], NextEvents); + doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPos, IsHib, DoAfter, [OneAction | Timeouts], NextEs); {{gTimeout, _Name}, _Time, _TimeoutMsg, _Options} -> - doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPostpone, IsHibernate, DoAfter, [OneAction | Timeouts], NextEvents); + doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPos, IsHib, DoAfter, [OneAction | Timeouts], NextEs); {u_eTimeout, _TimeoutMsg} -> - doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPostpone, IsHibernate, DoAfter, [OneAction | Timeouts], NextEvents); + doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPos, IsHib, DoAfter, [OneAction | Timeouts], NextEs); {u_sTimeout, _TimeoutMsg} -> - doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPostpone, IsHibernate, DoAfter, [OneAction | Timeouts], NextEvents); + doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPos, IsHib, DoAfter, [OneAction | Timeouts], NextEs); {{u_gTimeout, _Name}, _TimeoutMsg} -> - doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPostpone, IsHibernate, DoAfter, [OneAction | Timeouts], NextEvents); + doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPos, IsHib, DoAfter, [OneAction | Timeouts], NextEs); c_eTimeout -> - doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPostpone, IsHibernate, DoAfter, [OneAction | Timeouts], NextEvents); + doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPos, IsHib, DoAfter, [OneAction | Timeouts], NextEs); c_sTimeout -> - doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPostpone, IsHibernate, DoAfter, [OneAction | Timeouts], NextEvents); + doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPos, IsHib, DoAfter, [OneAction | Timeouts], NextEs); {c_gTimeout, _Name} -> - doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPostpone, IsHibernate, DoAfter, [OneAction | Timeouts], NextEvents); + doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPos, IsHib, DoAfter, [OneAction | Timeouts], NextEs); {isEnter, IsEnter} when is_boolean(IsEnter) -> case element(#cycleData.isEnter, CycleData) of IsEnter -> - doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPostpone, IsHibernate, DoAfter, Timeouts, NextEvents); + doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPos, IsHib, DoAfter, Timeouts, NextEs); _ -> NewCycleData = setelement(#cycleData.isEnter, CycleData, IsEnter), NewDebug = ?SYS_DEBUG(Debug, CycleData, {change_isEnter, IsEnter}), - doParseAL(LeftActions, CallbackForm, NewCycleData, NewDebug, IsPostpone, IsHibernate, DoAfter, Timeouts, NextEvents) + doParseAL(LeftActions, CallbackForm, NewCycleData, NewDebug, IsPos, IsHib, DoAfter, Timeouts, NextEs) end; - {isHibernate, NewIsHibernate} -> - doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPostpone, NewIsHibernate, DoAfter, Timeouts, NextEvents); - {isPostpone, NewIsPostpone} when (not NewIsPostpone orelse CallbackForm == ?CB_FORM_EVENT) -> - doParseAL(LeftActions, CallbackForm, CycleData, Debug, NewIsPostpone, IsHibernate, DoAfter, Timeouts, NextEvents); + {isHib, NewIsHib} -> + doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPos, NewIsHib, DoAfter, Timeouts, NextEs); + {isPos, NewIsPos} when (not NewIsPos orelse CallbackForm == ?CB_FORM_EVENT) -> + doParseAL(LeftActions, CallbackForm, CycleData, Debug, NewIsPos, IsHib, DoAfter, Timeouts, NextEs); {doAfter, Args} when CallbackForm == ?CB_FORM_EVENT -> - doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPostpone, IsHibernate, {true, Args}, Timeouts, NextEvents); - {nextEvent, Type, Content} when CallbackForm == ?CB_FORM_EVENT orelse CallbackForm == ?CB_FORM_AFTER -> + doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPos, IsHib, {true, Args}, Timeouts, NextEs); + {nextE, Type, Content} when CallbackForm == ?CB_FORM_EVENT orelse CallbackForm == ?CB_FORM_AFTER -> %% 处理next_event动作 - doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPostpone, IsHibernate, DoAfter, Timeouts, [{Type, Content} | NextEvents]); + doParseAL(LeftActions, CallbackForm, CycleData, Debug, IsPos, IsHib, DoAfter, Timeouts, [{Type, Content} | NextEs]); _ -> {error, {bad_ActionType, OneAction}} end. @@ -1648,10 +1661,10 @@ doParseAL([OneAction | LeftActions], CallbackForm, CycleData, Debug, IsPostpone, % end. %% 进行状态转换 -performTransitions(#cycleData{postponed = Postponed, timers = Timers} = CycleData, Module, CurStatus, CurState, NewStatus, Debug, [CurEvent | LeftEvents], Timeouts, NextEvents, IsPostpone, IsHibernate, DoAfter) -> +performTransitions(#cycleData{postponed = Postponed, timers = Timers} = CycleData, Module, CurStatus, CurState, NewStatus, Debug, [CurEvent | LeftEvents], Timeouts, NextEs, IsPos, IsHib, DoAfter) -> %% 已收集所有选项,并缓冲next_events。执行实际状态转换。如果推迟则将当前事件移至推迟 - %% 此时 Timeouts, NextEvents的顺序与最开始出现的顺序相反. 后面执行的顺序 超时添加和更新 + 零超时 + 当前事件 + 反序的Postpone事件 + LeftEvent %% TODO 测试验证 - NewDebug = ?SYS_DEBUG(Debug, CycleData, case IsPostpone of true -> {postpone, CurEvent, CurStatus, NewStatus}; _ -> + %% 此时 Timeouts, NextEs的顺序与最开始出现的顺序相反. 后面执行的顺序 超时添加和更新 + 零超时 + 当前事件 + 反序的Postpone事件 + LeftEvent + NewDebug = ?SYS_DEBUG(Debug, CycleData, case IsPos of true -> {postpone, CurEvent, CurStatus, NewStatus}; _ -> {consume, CurEvent, NewStatus, NewStatus} end), if CurStatus =:= NewStatus -> @@ -1664,11 +1677,11 @@ performTransitions(#cycleData{postponed = Postponed, timers = Timers} = CycleDat Timers end, if - IsPostpone -> + IsPos -> NewCycleData = setelement(#cycleData.postponed, CycleData, [CurEvent | Postponed]), - performTimeouts(NewCycleData, Module, NewStatus, CurState, NewDebug, LeftEvents, Timeouts, NextEvents, LastTimers, IsHibernate, DoAfter); + performTimeouts(NewCycleData, Module, NewStatus, CurState, NewDebug, LeftEvents, Timeouts, NextEs, LastTimers, IsHib, DoAfter); true -> - performTimeouts(CycleData, Module, NewStatus, CurState, NewDebug, LeftEvents, Timeouts, NextEvents, LastTimers, IsHibernate, DoAfter) + performTimeouts(CycleData, Module, NewStatus, CurState, NewDebug, LeftEvents, Timeouts, NextEs, LastTimers, IsHib, DoAfter) end; true -> %% 取消 status and event timeout @@ -1694,7 +1707,7 @@ performTransitions(#cycleData{postponed = Postponed, timers = Timers} = CycleDat %% 状态发生改变 重试推迟的事件 if - IsPostpone -> + IsPos -> NewLeftEvents = case Postponed of [] -> @@ -1706,7 +1719,7 @@ performTransitions(#cycleData{postponed = Postponed, timers = Timers} = CycleDat _ -> lists:reverse(Postponed, [CurEvent | LeftEvents]) end, - performTimeouts(NewCycleData, Module, NewStatus, CurState, NewDebug, NewLeftEvents, Timeouts, NextEvents, LastTimers, IsHibernate, DoAfter); + performTimeouts(NewCycleData, Module, NewStatus, CurState, NewDebug, NewLeftEvents, Timeouts, NextEs, LastTimers, IsHib, DoAfter); true -> NewLeftEvents = case Postponed of @@ -1719,14 +1732,14 @@ performTransitions(#cycleData{postponed = Postponed, timers = Timers} = CycleDat _ -> lists:reverse(Postponed, LeftEvents) end, - performTimeouts(NewCycleData, Module, NewStatus, CurState, NewDebug, NewLeftEvents, Timeouts, NextEvents, LastTimers, IsHibernate, DoAfter) + performTimeouts(NewCycleData, Module, NewStatus, CurState, NewDebug, NewLeftEvents, Timeouts, NextEs, LastTimers, IsHib, DoAfter) end end. %% 通过超时和插入事件的处理继续状态转换 -performTimeouts(#cycleData{timers = OldTimer} = CycleData, Module, CurStatus, CurState, Debug, LeftEvents, Timeouts, NextEvents, CurTimers, IsHibernate, DoAfter) -> +performTimeouts(#cycleData{timers = OldTimer} = CycleData, Module, CurStatus, CurState, Debug, LeftEvents, Timeouts, NextEs, CurTimers, IsHib, DoAfter) -> TemLastEvents = - case NextEvents of + case NextEs of [] -> LeftEvents; [E1] -> @@ -1734,16 +1747,16 @@ performTimeouts(#cycleData{timers = OldTimer} = CycleData, Module, CurStatus, Cu [E2, E1] -> [E1, E2 | LeftEvents]; _ -> - lists:reverse(NextEvents, LeftEvents) + lists:reverse(NextEs, LeftEvents) end, case Timeouts of [] -> case OldTimer =:= CurTimers of true -> - performEvents(CycleData, Module, CurStatus, CurState, Debug, TemLastEvents, IsHibernate, DoAfter); + performEvents(CycleData, Module, CurStatus, CurState, Debug, TemLastEvents, IsHib, DoAfter); _ -> NewCycleData = setelement(#cycleData.timers, CycleData, CurTimers), - performEvents(NewCycleData, Module, CurStatus, CurState, Debug, TemLastEvents, IsHibernate, DoAfter) + performEvents(NewCycleData, Module, CurStatus, CurState, Debug, TemLastEvents, IsHib, DoAfter) end; _ -> %% 下面执行 loopTimeoutList 时 列表顺序跟最开始的是反的 @@ -1752,19 +1765,19 @@ performTimeouts(#cycleData{timers = OldTimer} = CycleData, Module, CurStatus, Cu [] -> case OldTimer =:= NewTimers of true -> - performEvents(CycleData, Module, CurStatus, CurState, NewDebug, TemLastEvents, IsHibernate, DoAfter); + performEvents(CycleData, Module, CurStatus, CurState, NewDebug, TemLastEvents, IsHib, DoAfter); _ -> NewCycleData = setelement(#cycleData.timers, CycleData, NewTimers), - performEvents(NewCycleData, Module, CurStatus, CurState, NewDebug, TemLastEvents, IsHibernate, DoAfter) + performEvents(NewCycleData, Module, CurStatus, CurState, NewDebug, TemLastEvents, IsHib, DoAfter) end; _ -> {LastEvents, LastDebug} = mergeTimeoutEvents(TimeoutEvents, CurStatus, CycleData, NewDebug, TemLastEvents), case OldTimer =:= NewTimers of true -> - performEvents(CycleData, Module, CurStatus, CurState, LastDebug, LastEvents, IsHibernate, DoAfter); + performEvents(CycleData, Module, CurStatus, CurState, LastDebug, LastEvents, IsHib, DoAfter); _ -> NewCycleData = setelement(#cycleData.timers, CycleData, NewTimers), - performEvents(NewCycleData, Module, CurStatus, CurState, LastDebug, LastEvents, IsHibernate, DoAfter) + performEvents(NewCycleData, Module, CurStatus, CurState, LastDebug, LastEvents, IsHib, DoAfter) end end end. @@ -1885,20 +1898,20 @@ listTimeouts(Timers) -> %%--------------------------------------------------------------------------- %% 状态转换已完成,如果有排队事件,则继续循环,否则获取新事件 -performEvents(CycleData, Module, CurStatus, CurState, Debug, LeftEvents, IsHibernate, DoAfter) -> +performEvents(CycleData, Module, 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} -> - %% 这里 IsHibernate设置会被丢弃 按照gen_server中的设计 continue 和 hiernate是互斥的 + %% 这里 IsHib设置会被丢弃 按照gen_server中的设计 continue 和 hiernate是互斥的 startAfterCall(CycleData, Module, CurStatus, CurState, Debug, LeftEvents, Args); _ -> case LeftEvents of [] -> - reLoopEntry(CycleData, Module, CurStatus, CurState, Debug, IsHibernate); + reLoopEntry(CycleData, Module, CurStatus, CurState, Debug, IsHib); [Event | _Events] -> %% 循环直到没有排队事件 if - IsHibernate -> + IsHib -> %% _ = garbage_collect(), erts_internal:garbage_collect(major); true ->