aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/stdlib/doc/src/gen_statem.xml15
-rw-r--r--lib/stdlib/src/gen_statem.erl42
-rw-r--r--lib/stdlib/test/gen_statem_SUITE.erl11
3 files changed, 39 insertions, 29 deletions
diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml
index 5de1812b41..aeab09615c 100644
--- a/lib/stdlib/doc/src/gen_statem.xml
+++ b/lib/stdlib/doc/src/gen_statem.xml
@@ -369,7 +369,7 @@ erlang:'!' -----> Module:StateName/5
</p>
<p>The processing order for a state change is:</p>
<list type="ordered">
- <item>If the option <c>retry</c> is <c>true</c>
+ <item>If the option <c>postpone</c> is <c>true</c>
the current event is postponed.
</item>
<item>If the state changes the queue of incoming events
@@ -402,10 +402,10 @@ erlang:'!' -----> Module:StateName/5
and the last value is kept.
</p>
<taglist>
- <tag><c>retry</c></tag>
- <tag><c>{retry,<anno>Retry</anno>}</c></tag>
- <item>If <c><anno>Retry</anno> =:= true</c>
- or plain <c>retry</c> postpone the current event
+ <tag><c>postpone</c></tag>
+ <tag><c>{postpone,<anno>Postpone</anno>}</c></tag>
+ <item>If <c><anno>Postpone</anno> =:= true</c>
+ or plain <c>postpone</c> postpone the current event
to be retried after a state change.
This option is ignored when returned from
<seealso marker="#Module:init/1">Module:init/1</seealso>
@@ -434,9 +434,8 @@ erlang:'!' -----> Module:StateName/5
event counts just like a new in this respect.
If <c>Time =:= infinity</c> or <c>Time =:= 0</c>
no timer is started but for zero time the timeout
- event is enqued as just received after all
- other already received events.
- Also note that it is not possible
+ event is immediately enqueued as the newest received.
+ Also note that it is not possible nor needed
to cancel this timeout using the
<seealso marker="#type-state_operation">
<c>state_operation()</c>
diff --git a/lib/stdlib/src/gen_statem.erl b/lib/stdlib/src/gen_statem.erl
index 52fde7df7b..32174687cf 100644
--- a/lib/stdlib/src/gen_statem.erl
+++ b/lib/stdlib/src/gen_statem.erl
@@ -70,15 +70,15 @@
%% First NewState and NewStateData are set,
%% then all state_operations() are executed in order of
%% apperance. Postponing the current event is performed
- %% (iff state_option() 'retry' is 'true').
+ %% (iff state_option() 'postpone' is 'true').
%% Lastly pending events are processed or if there are
%% no pending events the server goes into receive
%% or hibernate (iff state_option() 'hibernate' is 'true')
state_option() | state_operation().
-type state_option() ::
%% The first of each kind in the state_op() list takes precedence
- 'retry' | % Postpone the current event to a different (=/=) state
- {'retry', Retry :: boolean()} |
+ 'postpone' | % Postpone the current event to a different (=/=) state
+ {'postpone', Postpone :: boolean()} |
'hibernate' | % Hibernate the server instead of going into receive
{'hibernate', Hibernate :: boolean()} |
(Timeout :: timeout()) | % {timeout,Timeout}
@@ -469,7 +469,7 @@ enter(Module, Options, State, StateData, Server, InitOps, Parent) ->
S#{callback_mode := CallbackMode},
[], {event,undefined},
State, StateData,
- StateOps++[{retry,false}]);
+ StateOps++[{postpone,false}]);
[Reason] ->
?TERMINATE(Reason, Debug, S, [])
end.
@@ -782,9 +782,9 @@ loop_event_state_ops(
Parent, Debug0, #{state := State, postponed := P0} = S, Events, Event,
NewState, NewStateData, StateOps) ->
case collect_state_options(StateOps) of
- {Retry,Hibernate,Timeout,Operations} ->
- P1 = % Move current event to postponed if Retry
- case Retry of
+ {Postpone,Hibernate,Timeout,Operations} ->
+ P1 = % Move current event to postponed if Postpone
+ case Postpone of
true ->
[Event|P0];
false ->
@@ -804,9 +804,9 @@ loop_event_state_ops(
NewDebug =
sys_debug(
Debug, S,
- case Retry of
+ case Postpone of
true ->
- {retry,Event,NewState};
+ {postpone,Event,NewState};
false ->
{consume,Event,NewState}
end),
@@ -867,38 +867,38 @@ collect_state_options(StateOps) ->
collect_state_options(StateOps, false, false, undefined, []).
%% Keep the last of each kind
collect_state_options(
- [], Retry, Hibernate, Timeout, Operations) ->
- {Retry,Hibernate,Timeout,lists:reverse(Operations)};
+ [], Postpone, Hibernate, Timeout, Operations) ->
+ {Postpone,Hibernate,Timeout,lists:reverse(Operations)};
collect_state_options(
- [StateOp|StateOps] = SOSOs, Retry, Hibernate, Timeout, Operations) ->
+ [StateOp|StateOps] = SOSOs, Postpone, Hibernate, Timeout, Operations) ->
case StateOp of
- retry ->
+ postpone ->
collect_state_options(
StateOps, true, Hibernate, Timeout, Operations);
- {retry,NewRetry} when is_boolean(NewRetry) ->
+ {postpone,NewPostpone} when is_boolean(NewPostpone) ->
collect_state_options(
- StateOps, NewRetry, Hibernate, Timeout, Operations);
- {retry,_} ->
+ StateOps, NewPostpone, Hibernate, Timeout, Operations);
+ {postpone,_} ->
[{bad_state_ops,SOSOs}];
hibernate ->
collect_state_options(
- StateOps, Retry, true, Timeout, Operations);
+ StateOps, Postpone, true, Timeout, Operations);
{hibernate,NewHibernate} when is_boolean(NewHibernate) ->
collect_state_options(
- StateOps, Retry, NewHibernate, Timeout, Operations);
+ StateOps, Postpone, NewHibernate, Timeout, Operations);
{hibernate,_} ->
[{bad_state_ops,SOSOs}];
{timeout,infinity,_} -> % Ignore since it will never time out
collect_state_options(
- StateOps, Retry, Hibernate, undefined, Operations);
+ StateOps, Postpone, Hibernate, undefined, Operations);
{timeout,Time,_} = NewTimeout when is_integer(Time), Time >= 0 ->
collect_state_options(
- StateOps, Retry, Hibernate, NewTimeout, Operations);
+ StateOps, Postpone, Hibernate, NewTimeout, Operations);
{timeout,_,_} ->
[{bad_state_ops,SOSOs}];
_ -> % Collect others as operations
collect_state_options(
- StateOps, Retry, Hibernate, Timeout, [StateOp|Operations])
+ StateOps, Postpone, Hibernate, Timeout, [StateOp|Operations])
end.
process_state_operations([], Debug, _S, Q, P) ->
diff --git a/lib/stdlib/test/gen_statem_SUITE.erl b/lib/stdlib/test/gen_statem_SUITE.erl
index facc36fb9f..8b619b6a60 100644
--- a/lib/stdlib/test/gen_statem_SUITE.erl
+++ b/lib/stdlib/test/gen_statem_SUITE.erl
@@ -1032,7 +1032,10 @@ do_connect(STM) ->
gen_statem:cast(STM, {connect,self()}),
wfor(accept),
check_state(STM, wfor_conf),
+ Tag = make_ref(),
+ gen_statem:cast(STM, {ping,self(),Tag}),
gen_statem:cast(STM, confirm),
+ wfor({pong,Tag}),
check_state(STM, connected),
ok.
@@ -1071,7 +1074,10 @@ do_sync_connect(STM) ->
check_state(STM, idle),
accept = gen_statem:call(STM, connect),
check_state(STM, wfor_conf),
+ Tag = make_ref(),
+ gen_statem:cast(STM, {ping,self(),Tag}),
yes = gen_statem:call(STM, confirm),
+ wfor({pong,Tag}),
check_state(STM, connected),
ok.
@@ -1202,6 +1208,8 @@ timeout3(_, _, _, State, Data) ->
wfor_conf({call,From}, confirm, _, _, Data) ->
{next_state,connected,Data,
[{reply,From,yes}]};
+wfor_conf(cast, {ping,_,_}, _, State, Data) ->
+ {next_state,State,Data,[postpone]};
wfor_conf(cast, confirm, _, _, Data) ->
{next_state,connected,Data};
wfor_conf(Type, Content, PrevState, State, Data) ->
@@ -1229,6 +1237,9 @@ connected({call,From}, disconnect, _, _, Data) ->
[{reply,From,yes}]};
connected(cast, disconnect, _, _, Data) ->
{next_state,idle,Data};
+connected(cast, {ping,Pid,Tag}, _, State, Data) ->
+ Pid ! {pong,Tag},
+ {next_state,State,Data};
connected(Type, Content, PrevState, State, Data) ->
case handle_common_events(Type, Content, PrevState, State, Data) of
undefined ->