From 1e4831762b5ab4bd2210fc9e0a204e00dfe81b39 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 26 Feb 2016 10:35:16 +0100 Subject: Implement 'keep_state_and_data' and 'stop' --- lib/stdlib/doc/src/gen_statem.xml | 7 ++++- lib/stdlib/src/gen_statem.erl | 60 ++++++++++++++++++++---------------- lib/stdlib/test/gen_statem_SUITE.erl | 4 +-- 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 keep_state_and_data - The gen_statem will keep the current state, or + The gen_statem 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 Actions +

+ All these terms are tuples or atoms and this property + will hold in any future version of gen_statem, + just in case you need such a promise. +

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}, _, _) -> -- cgit v1.2.3