aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaimo Niskanen <[email protected]>2016-02-26 10:35:16 +0100
committerRaimo Niskanen <[email protected]>2016-02-26 10:35:16 +0100
commit1e4831762b5ab4bd2210fc9e0a204e00dfe81b39 (patch)
tree48e065aa786f1256c3fd1662fcad60ae991aebab
parentcea77ca09be156669c657592bebf6efc9d5cfaee (diff)
downloadotp-1e4831762b5ab4bd2210fc9e0a204e00dfe81b39.tar.gz
otp-1e4831762b5ab4bd2210fc9e0a204e00dfe81b39.tar.bz2
otp-1e4831762b5ab4bd2210fc9e0a204e00dfe81b39.zip
Implement 'keep_state_and_data' and 'stop'
-rw-r--r--lib/stdlib/doc/src/gen_statem.xml7
-rw-r--r--lib/stdlib/src/gen_statem.erl60
-rw-r--r--lib/stdlib/test/gen_statem_SUITE.erl4
3 files changed, 42 insertions, 29 deletions
diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml
index d50b88c561..bda3ef081d 100644
--- a/lib/stdlib/doc/src/gen_statem.xml
+++ b/lib/stdlib/doc/src/gen_statem.xml
@@ -803,12 +803,17 @@ ok
</item>
<tag><c>keep_state_and_data</c></tag>
<item>
- The <c>gen_statem</c> will keep the current state, or
+ The <c>gen_statem</c> will keep the current state or
do a state transition to the current state if you like,
keep the current server data,
and execute all <c><anno>Actions</anno></c>
</item>
</taglist>
+ <p>
+ All these terms are tuples or atoms and this property
+ will hold in any future version of <c>gen_statem</c>,
+ just in case you need such a promise.
+ </p>
</desc>
</datatype>
</datatypes>
diff --git a/lib/stdlib/src/gen_statem.erl b/lib/stdlib/src/gen_statem.erl
index e6ad7ab0be..16c296794f 100644
--- a/lib/stdlib/src/gen_statem.erl
+++ b/lib/stdlib/src/gen_statem.erl
@@ -135,32 +135,34 @@
Caller :: caller(), Reply :: term()}.
-type state_callback_result() ::
- {'stop', % Stop the server
- Reason :: term()} |
- {'stop', % Stop the server
- Reason :: term(),
- NewData :: data()} |
- {'stop_and_reply', % Reply then stop the server
- Reason :: term(),
- Replies :: [reply_action()] | reply_action()} |
- {'stop_and_reply', % Reply then stop the server
- Reason :: term(),
- Replies :: [reply_action()] | reply_action(),
- NewData :: data()} |
- {'next_state', % {next_state,NewState,NewData,[]}
- NewState :: state(),
- NewData :: data()} |
- {'next_state', % State transition, maybe to the same state
- NewState :: state(),
- NewData :: data(),
- Actions :: [action()] | action()} |
- {'keep_state', % {keep_state,NewData,[]}
- NewData :: data()} |
- {'keep_state', % Keep state, change data
- NewData :: data(),
- Actions :: [action()] | action()} |
- {'keep_state_and_data', % Keep state and data -> only actions
- Actions :: [action()] | action()}.
+ 'stop' | % {stop,normal}
+ {'stop', % Stop the server
+ Reason :: term()} |
+ {'stop', % Stop the server
+ Reason :: term(),
+ NewData :: data()} |
+ {'stop_and_reply', % Reply then stop the server
+ Reason :: term(),
+ Replies :: [reply_action()] | reply_action()} |
+ {'stop_and_reply', % Reply then stop the server
+ Reason :: term(),
+ Replies :: [reply_action()] | reply_action(),
+ NewData :: data()} |
+ {'next_state', % {next_state,NewState,NewData,[]}
+ NewState :: state(),
+ NewData :: data()} |
+ {'next_state', % State transition, maybe to the same state
+ NewState :: state(),
+ NewData :: data(),
+ Actions :: [action()] | action()} |
+ {'keep_state', % {keep_state,NewData,[]}
+ NewData :: data()} |
+ {'keep_state', % Keep state, change data
+ NewData :: data(),
+ Actions :: [action()] | action()} |
+ 'keep_state_and_data' | % {keep_state_and_data,[]}
+ {'keep_state_and_data', % Keep state and data -> only actions
+ Actions :: [action()] | action()}.
%% The state machine init function. It is called only once and
@@ -841,6 +843,8 @@ loop_event_result(
#{state := State, data := Data} = S,
Events, Event, Result) ->
case Result of
+ stop ->
+ ?TERMINATE(exit, normal, Debug, S, [Event|Events]);
{stop,Reason} ->
?TERMINATE(exit, Reason, Debug, S, [Event|Events]);
{stop,Reason,NewData} ->
@@ -879,6 +883,10 @@ loop_event_result(
loop_event_actions(
Parent, Debug, S, Events, Event,
State, State, NewData, Actions);
+ keep_state_and_data ->
+ loop_event_actions(
+ Parent, Debug, S, Events, Event,
+ State, State, Data, []);
{keep_state_and_data,Actions} ->
loop_event_actions(
Parent, Debug, S, Events, Event,
diff --git a/lib/stdlib/test/gen_statem_SUITE.erl b/lib/stdlib/test/gen_statem_SUITE.erl
index f5cbdd9a40..09b309c36f 100644
--- a/lib/stdlib/test/gen_statem_SUITE.erl
+++ b/lib/stdlib/test/gen_statem_SUITE.erl
@@ -1233,7 +1233,7 @@ wfor_conf(Type, Content, Data) ->
{next_state,idle,Data,
[{reply,From,'eh?'}]};
_ ->
- throw({keep_state_and_data,[]})
+ throw(keep_state_and_data)
end;
Result ->
Result
@@ -1334,7 +1334,7 @@ handle_common_events(cast, {get,Pid}, State, Data) ->
handle_common_events({call,From}, stop, _, Data) ->
{stop_and_reply,normal,[{reply,From,stopped}],Data};
handle_common_events(cast, stop, _, _) ->
- {stop,normal};
+ stop;
handle_common_events({call,From}, {stop,Reason}, _, Data) ->
{stop_and_reply,Reason,{reply,From,stopped},Data};
handle_common_events(cast, {stop,Reason}, _, _) ->