From 84adefa331c4159d432d22840663c38f155cd4c1 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Fri, 20 Nov 2009 14:54:40 +0000 Subject: The R13B03 release. --- lib/stdlib/doc/src/gen_fsm.xml | 743 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 743 insertions(+) create mode 100644 lib/stdlib/doc/src/gen_fsm.xml (limited to 'lib/stdlib/doc/src/gen_fsm.xml') diff --git a/lib/stdlib/doc/src/gen_fsm.xml b/lib/stdlib/doc/src/gen_fsm.xml new file mode 100644 index 0000000000..f5d8b9bb48 --- /dev/null +++ b/lib/stdlib/doc/src/gen_fsm.xml @@ -0,0 +1,743 @@ + + + + +
+ + 19962009 + Ericsson AB. All Rights Reserved. + + + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + + + gen_fsm + + + + +
+ gen_fsm + Generic Finite State Machine Behaviour + +

A behaviour module for implementing a finite state machine. + A generic finite state machine process (gen_fsm) implemented + using this module will have a standard set of interface functions + and include functionality for tracing and error reporting. It will + also fit into an OTP supervision tree. Refer to + OTP Design Principles for more information.

+

A gen_fsm assumes all specific parts to be located in a callback + module exporting a pre-defined set of functions. The relationship + between the behaviour functions and the callback functions can be + illustrated as follows:

+
+gen_fsm module                    Callback module
+--------------                    ---------------
+gen_fsm:start_link                -----> Module:init/1
+
+gen_fsm:send_event                -----> Module:StateName/2
+
+gen_fsm:send_all_state_event      -----> Module:handle_event/3
+
+gen_fsm:sync_send_event           -----> Module:StateName/3
+
+gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
+
+-                                 -----> Module:handle_info/3
+
+-                                 -----> Module:terminate/3
+
+-                                 -----> Module:code_change/4
+

If a callback function fails or returns a bad value, the gen_fsm + will terminate.

+

A gen_fsm handles system messages as documented in + sys(3). The sys module + can be used for debugging a gen_fsm.

+

Note that a gen_fsm does not trap exit signals automatically, + this must be explicitly initiated in the callback module.

+

Unless otherwise stated, all functions in this module fail if + the specified gen_fsm does not exist or if bad arguments are + given.

+

The gen_fsm process can go into hibernation + (see erlang(3)) if a callback + function specifies 'hibernate' instead of a timeout value. This + might be useful if the server is expected to be idle for a long + time. However this feature should be used with care as hibernation + implies at least two garbage collections (when hibernating and + shortly after waking up) and is not something you'd want to do + between each call to a busy state machine.

+ +
+ + + start_link(Module, Args, Options) -> Result + start_link(FsmName, Module, Args, Options) -> Result + Create a gen_fsm process in a supervision tree. + + FsmName = {local,Name} | {global,GlobalName} +  Name = atom() +  GlobalName = term() + Module = atom() + Args = term() + Options = [Option] +  Option = {debug,Dbgs} | {timeout,Time} | {spawn_opt,SOpts} +   Dbgs = [Dbg] +    Dbg = trace | log | statistics +     | {log_to_file,FileName} | {install,{Func,FuncState}} +   SOpts = [SOpt] +    SOpt - see erlang:spawn_opt/2,3,4,5 + Result = {ok,Pid} | ignore | {error,Error} +  Pid = pid() +  Error = {already_started,Pid} | term() + + +

Creates a gen_fsm process as part of a supervision tree. + The function should be called, directly or indirectly, by + the supervisor. It will, among other things, ensure that + the gen_fsm is linked to the supervisor.

+

The gen_fsm process calls Module:init/1 to + initialize. To ensure a synchronized start-up procedure, + start_link/3,4 does not return until + Module:init/1 has returned.

+

If FsmName={local,Name}, the gen_fsm is registered + locally as Name using register/2. + If FsmName={global,GlobalName}, the gen_fsm is + registered globally as GlobalName using + global:register_name/2. If no name is provided, + the gen_fsm is not registered.

+

Module is the name of the callback module.

+

Args is an arbitrary term which is passed as + the argument to Module:init/1.

+

If the option {timeout,Time} is present, the gen_fsm + is allowed to spend Time milliseconds initializing + or it will be terminated and the start function will return + {error,timeout}.

+

If the option {debug,Dbgs} is present, + the corresponding sys function will be called for each + item in Dbgs. See + sys(3).

+

If the option {spawn_opt,SOpts} is present, + SOpts will be passed as option list to + the spawn_opt BIF which is used to spawn the gen_fsm + process. See + erlang(3).

+ +

Using the spawn option monitor is currently not + allowed, but will cause the function to fail with reason + badarg.

+
+

If the gen_fsm is successfully created and initialized + the function returns {ok,Pid}, where Pid is + the pid of the gen_fsm. If there already exists a process with + the specified FsmName, the function returns + {error,{already_started,Pid}} where Pid is + the pid of that process.

+

If Module:init/1 fails with Reason, + the function returns {error,Reason}. If + Module:init/1 returns {stop,Reason} or + ignore, the process is terminated and the function + returns {error,Reason} or ignore, respectively.

+
+
+ + start(Module, Args, Options) -> Result + start(FsmName, Module, Args, Options) -> Result + Create a stand-alone gen_fsm process. + + FsmName = {local,Name} | {global,GlobalName} +  Name = atom() +  GlobalName = term() + Module = atom() + Args = term() + Options = [Option] +  Option = {debug,Dbgs} | {timeout,Time} | {spawn_opt,SOpts} +   Dbgs = [Dbg] +    Dbg = trace | log | statistics +     | {log_to_file,FileName} | {install,{Func,FuncState}} +   SOpts = [term()] + Result = {ok,Pid} | ignore | {error,Error} +  Pid = pid() +  Error = {already_started,Pid} | term() + + +

Creates a stand-alone gen_fsm process, i.e. a gen_fsm which + is not part of a supervision tree and thus has no supervisor.

+

See start_link/3,4 + for a description of arguments and return values.

+
+
+ + send_event(FsmRef, Event) -> ok + Send an event asynchronously to a generic FSM. + + FsmRef = Name | {Name,Node} | {global,GlobalName} | pid() +  Name = Node = atom() +  GlobalName = term() + Event = term() + + +

Sends an event asynchronously to the gen_fsm FsmRef + and returns ok immediately. The gen_fsm will call + Module:StateName/2 to handle the event, where + StateName is the name of the current state of + the gen_fsm.

+

FsmRef can be:

+ + the pid, + Name, if the gen_fsm is locally registered, + {Name,Node}, if the gen_fsm is locally + registered at another node, or + {global,GlobalName}, if the gen_fsm is globally + registered. + +

Event is an arbitrary term which is passed as one of + the arguments to Module:StateName/2.

+
+
+ + send_all_state_event(FsmRef, Event) -> ok + Send an event asynchronously to a generic FSM. + + FsmRef = Name | {Name,Node} | {global,GlobalName} | pid() +  Name = Node = atom() +  GlobalName = term() + Event = term() + + +

Sends an event asynchronously to the gen_fsm FsmRef + and returns ok immediately. The gen_fsm will call + Module:handle_event/3 to handle the event.

+

See send_event/2 + for a description of the arguments.

+

The difference between send_event and + send_all_state_event is which callback function is + used to handle the event. This function is useful when + sending events that are handled the same way in every state, + as only one handle_event clause is needed to handle + the event instead of one clause in each state name function.

+
+
+ + sync_send_event(FsmRef, Event) -> Reply + sync_send_event(FsmRef, Event, Timeout) -> Reply + Send an event synchronously to a generic FSM. + + FsmRef = Name | {Name,Node} | {global,GlobalName} | pid() +  Name = Node = atom() +  GlobalName = term() + Event = term() + Timeout = int()>0 | infinity + Reply = term() + + +

Sends an event to the gen_fsm FsmRef and waits until a + reply arrives or a timeout occurs. The gen_fsm will call + Module:StateName/3 to handle the event, where + StateName is the name of the current state of + the gen_fsm.

+

See send_event/2 + for a description of FsmRef and Event.

+

Timeout is an integer greater than zero which + specifies how many milliseconds to wait for a reply, or + the atom infinity to wait indefinitely. Default value + is 5000. If no reply is received within the specified time, + the function call fails.

+

The return value Reply is defined in the return value + of Module:StateName/3.

+

The ancient behaviour of sometimes consuming the server + exit message if the server died during the call while + linked to the client has been removed in OTP R12B/Erlang 5.6.

+
+
+ + sync_send_all_state_event(FsmRef, Event) -> Reply + sync_send_all_state_event(FsmRef, Event, Timeout) -> Reply + Send an event synchronously to a generic FSM. + + FsmRef = Name | {Name,Node} | {global,GlobalName} | pid() +  Name = Node = atom() +  GlobalName = term() + Event = term() + Timeout = int()>0 | infinity + Reply = term() + + +

Sends an event to the gen_fsm FsmRef and waits until a + reply arrives or a timeout occurs. The gen_fsm will call + Module:handle_sync_event/4 to handle the event.

+

See send_event/2 + for a description of FsmRef and Event. See + sync_send_event/3 + for a description of Timeout and Reply.

+

See + send_all_state_event/2 + for a discussion about the difference between + sync_send_event and sync_send_all_state_event.

+
+
+ + reply(Caller, Reply) -> true + Send a reply to a caller. + + Caller - see below + Reply = term() + + +

This function can be used by a gen_fsm to explicitly send a + reply to a client process that called + sync_send_event/2,3 + or + sync_send_all_state_event/2,3, + when the reply cannot be defined in the return value of + Module:State/3 or Module:handle_sync_event/4.

+

Caller must be the From argument provided to + the callback function. Reply is an arbitrary term, + which will be given back to the client as the return value of + sync_send_event/2,3 or + sync_send_all_state_event/2,3.

+
+
+ + send_event_after(Time, Event) -> Ref + Send a delayed event internally in a generic FSM. + + Time = integer() + Event = term() + Ref = reference() + + +

Sends a delayed event internally in the gen_fsm that calls + this function after Time ms. Returns immediately a + reference that can be used to cancel the delayed send using + cancel_timer/1.

+

The gen_fsm will call Module:StateName/2 to handle + the event, where StateName is the name of the current + state of the gen_fsm at the time the delayed event is + delivered.

+

Event is an arbitrary term which is passed as one of + the arguments to Module:StateName/2.

+
+
+ + start_timer(Time, Msg) -> Ref + Send a timeout event internally in a generic FSM. + + Time = integer() + Msg = term() + Ref = reference() + + +

Sends a timeout event internally in the gen_fsm that calls + this function after Time ms. Returns immediately a + reference that can be used to cancel the timer using + cancel_timer/1.

+

The gen_fsm will call Module:StateName/2 to handle + the event, where StateName is the name of the current + state of the gen_fsm at the time the timeout message is + delivered.

+

Msg is an arbitrary term which is passed in the + timeout message, {timeout, Ref, Msg}, as one of + the arguments to Module:StateName/2.

+
+
+ + cancel_timer(Ref) -> RemainingTime | false + Cancel an internal timer in a generic FSM. + + Ref = reference() + RemainingTime = integer() + + +

Cancels an internal timer referred by Ref in the + gen_fsm that calls this function.

+

Ref is a reference returned from + send_event_after/2 + or + start_timer/2.

+

If the timer has already timed out, but the event not yet + been delivered, it is cancelled as if it had not + timed out, so there will be no false timer event after + returning from this function.

+

Returns the remaining time in ms until the timer would + have expired if Ref referred to an active timer, + false otherwise.

+
+
+ + enter_loop(Module, Options, StateName, StateData) + enter_loop(Module, Options, StateName, StateData, FsmName) + enter_loop(Module, Options, StateName, StateData, Timeout) + enter_loop(Module, Options, StateName, StateData, FsmName, Timeout) + Enter the gen_fsm receive loop + + Module = atom() + Options = [Option] +  Option = {debug,Dbgs} +   Dbgs = [Dbg] +    Dbg = trace | log | statistics +     | {log_to_file,FileName} | {install,{Func,FuncState}} + StateName = atom() + StateData = term() + FsmName = {local,Name} | {global,GlobalName} +  Name = atom() +  GlobalName = term() + Timeout = int() | infinity + + +

Makes an existing process into a gen_fsm. Does not return, + instead the calling process will enter the gen_fsm receive + loop and become a gen_fsm process. The process must + have been started using one of the start functions in + proc_lib, see + proc_lib(3). The user is + responsible for any initialization of the process, including + registering a name for it.

+

This function is useful when a more complex initialization + procedure is needed than the gen_fsm behaviour provides.

+

Module, Options and FsmName have + the same meanings as when calling + start[_link]/3,4. + However, if FsmName is specified, the process must have + been registered accordingly before this function is + called.

+

StateName, StateData and Timeout have + the same meanings as in the return value of + Module:init/1. + Also, the callback module Module does not need to + export an init/1 function.

+

Failure: If the calling process was not started by a + proc_lib start function, or if it is not registered + according to FsmName.

+
+
+
+ +
+ CALLBACK FUNCTIONS +

The following functions should be exported from a gen_fsm + callback module.

+

In the description, the expression state name is used to + denote a state of the state machine. state data is used + to denote the internal state of the Erlang process which + implements the state machine.

+

+
+ + + Module:init(Args) -> Result + Initialize process and internal state name and state data. + + Args = term() + Return = {ok,StateName,StateData} | {ok,StateName,StateData,Timeout} +   | {ok,StateName,StateData,hibernate} +   | {stop,Reason} | ignore +  StateName = atom() +  StateData = term() +  Timeout = int()>0 | infinity +  Reason = term() + + + +

Whenever a gen_fsm is started using + gen_fsm:start/3,4 or + gen_fsm:start_link/3,4, + this function is called by the new process to initialize.

+

Args is the Args argument provided to the start + function.

+

If initialization is successful, the function should return + {ok,StateName,StateData}, + {ok,StateName,StateData,Timeout} or {ok,StateName,StateData,hibernate}, + where StateName + is the initial state name and StateData the initial + state data of the gen_fsm.

+

If an integer timeout value is provided, a timeout will occur + unless an event or a message is received within Timeout + milliseconds. A timeout is represented by the atom + timeout and should be handled by + the Module:StateName/2 callback functions. The atom + infinity can be used to wait indefinitely, this is + the default value.

+

If hibernate is specified instead of a timeout value, the process will go + into hibernation when waiting for the next message to arrive (by calling + proc_lib:hibernate/3).

+

If something goes wrong during the initialization + the function should return {stop,Reason}, where + Reason is any term, or ignore.

+
+
+ + Module:StateName(Event, StateData) -> Result + Handle an asynchronous event. + + Event = timeout | term() + StateData = term() + Result = {next_state,NextStateName,NewStateData} +   | {next_state,NextStateName,NewStateData,Timeout} +   | {next_state,NextStateName,NewStateData,hibernate} +   | {stop,Reason,NewStateData} +  NextStateName = atom() +  NewStateData = term() +  Timeout = int()>0 | infinity +  Reason = term() + + +

There should be one instance of this function for each + possible state name. Whenever a gen_fsm receives an event + sent using + gen_fsm:send_event/2, + the instance of this function with the same name as + the current state name StateName is called to handle + the event. It is also called if a timeout occurs.

+

Event is either the atom timeout, if a timeout + has occurred, or the Event argument provided to + send_event/2.

+

StateData is the state data of the gen_fsm.

+

If the function returns + {next_state,NextStateName,NewStateData}, + {next_state,NextStateName,NewStateData,Timeout} or + {next_state,NextStateName,NewStateData,hibernate}, + the gen_fsm will continue executing with the current state + name set to NextStateName and with the possibly + updated state data NewStateData. See + Module:init/1 for a description of Timeout and hibernate.

+

If the function returns {stop,Reason,NewStateData}, + the gen_fsm will call + Module:terminate(Reason,NewStateData) and terminate.

+
+
+ + Module:handle_event(Event, StateName, StateData) -> Result + Handle an asynchronous event. + + Event = term() + StateName = atom() + StateData = term() + Result = {next_state,NextStateName,NewStateData} +   | {next_state,NextStateName,NewStateData,Timeout} +   | {next_state,NextStateName,NewStateData,hibernate} +   | {stop,Reason,NewStateData} +  NextStateName = atom() +  NewStateData = term() +  Timeout = int()>0 | infinity +  Reason = term() + + +

Whenever a gen_fsm receives an event sent using + gen_fsm:send_all_state_event/2, + this function is called to handle the event.

+

StateName is the current state name of the gen_fsm.

+

See Module:StateName/2 for a description of the other + arguments and possible return values.

+
+
+ + Module:StateName(Event, From, StateData) -> Result + Handle a synchronous event. + + Event = term() + From = {pid(),Tag} + StateData = term() + Result = {reply,Reply,NextStateName,NewStateData} +   | {reply,Reply,NextStateName,NewStateData,Timeout} +   | {reply,Reply,NextStateName,NewStateData,hibernate} +   | {next_state,NextStateName,NewStateData} +   | {next_state,NextStateName,NewStateData,Timeout} +   | {next_state,NextStateName,NewStateData,hibernate} +   | {stop,Reason,Reply,NewStateData} | {stop,Reason,NewStateData} +  Reply = term() +  NextStateName = atom() +  NewStateData = term() +  Timeout = int()>0 | infinity +  Reason = normal | term() + + +

There should be one instance of this function for each + possible state name. Whenever a gen_fsm receives an event + sent using + gen_fsm:sync_send_event/2,3, + the instance of this function with the same name as + the current state name StateName is called to handle + the event.

+

Event is the Event argument provided to + sync_send_event.

+

From is a tuple {Pid,Tag} where Pid is + the pid of the process which called sync_send_event/2,3 + and Tag is a unique tag.

+

StateData is the state data of the gen_fsm.

+

If the function returns + {reply,Reply,NextStateName,NewStateData}, + {reply,Reply,NextStateName,NewStateData,Timeout} or + {reply,Reply,NextStateName,NewStateData,hibernate}, + Reply will be given back to From as the return + value of sync_send_event/2,3. The gen_fsm then + continues executing with the current state name set to + NextStateName and with the possibly updated state data + NewStateData. See Module:init/1 for a + description of Timeout and hibernate.

+

If the function returns + {next_state,NextStateName,NewStateData}, + {next_state,NextStateName,NewStateData,Timeout} or + {next_state,NextStateName,NewStateData,hibernate}, + the gen_fsm will continue executing in NextStateName + with NewStateData. Any reply to From must be + given explicitly using + gen_fsm:reply/2.

+

If the function returns + {stop,Reason,Reply,NewStateData}, Reply will be + given back to From. If the function returns + {stop,Reason,NewStateData}, any reply to From + must be given explicitly using gen_fsm:reply/2. + The gen_fsm will then call + Module:terminate(Reason,NewStateData) and terminate.

+
+
+ + Module:handle_sync_event(Event, From, StateName, StateData) -> Result + Handle a synchronous event. + + Event = term() + From = {pid(),Tag} + StateName = atom() + StateData = term() + Result = {reply,Reply,NextStateName,NewStateData} +   | {reply,Reply,NextStateName,NewStateData,Timeout} +   | {reply,Reply,NextStateName,NewStateData,hibernate} +   | {next_state,NextStateName,NewStateData} +   | {next_state,NextStateName,NewStateData,Timeout} +   | {next_state,NextStateName,NewStateData,hibernate} +   | {stop,Reason,Reply,NewStateData} | {stop,Reason,NewStateData} +  Reply = term() +  NextStateName = atom() +  NewStateData = term() +  Timeout = int()>0 | infinity +  Reason = term() + + +

Whenever a gen_fsm receives an event sent using + gen_fsm:sync_send_all_state_event/2,3, + this function is called to handle the event.

+

StateName is the current state name of the gen_fsm.

+

See Module:StateName/3 for a description of the other + arguments and possible return values.

+
+
+ + Module:handle_info(Info, StateName, StateData) -> Result + Handle an incoming message. + + Info = term() + StateName = atom() + StateData = term() + Result = {next_state,NextStateName,NewStateData} +  > | {next_state,NextStateName,NewStateData,Timeout} +  > | {next_state,NextStateName,NewStateData,hibernate} +  > | {stop,Reason,NewStateData} +  NextStateName = atom() +  NewStateData = term() +  Timeout = int()>0 | infinity +  Reason = normal | term() + + +

This function is called by a gen_fsm when it receives any + other message than a synchronous or asynchronous event (or a + system message).

+

Info is the received message.

+

See Module:StateName/2 for a description of the other + arguments and possible return values.

+
+
+ + Module:terminate(Reason, StateName, StateData) + Clean up before termination. + + Reason = normal | shutdown | {shutdown,term()} | term() + StateName = atom() + StateData = term() + + +

This function is called by a gen_fsm when it is about to + terminate. It should be the opposite of Module:init/1 + and do any necessary cleaning up. When it returns, the gen_fsm + terminates with Reason. The return value is ignored.

+

Reason is a term denoting the stop reason, + StateName is the current state name, and + StateData is the state data of the gen_fsm.

+

Reason depends on why the gen_fsm is terminating. If + it is because another callback function has returned a stop + tuple {stop,..}, Reason will have the value + specified in that tuple. If it is due to a failure, + Reason is the error reason.

+

If the gen_fsm is part of a supervision tree and is ordered + by its supervisor to terminate, this function will be called + with Reason=shutdown if the following conditions apply:

+ + the gen_fsm has been set to trap exit signals, and + the shutdown strategy as defined in the supervisor's + child specification is an integer timeout value, not + brutal_kill. + +

Even if the gen_fsm is not part of a supervision tree, + this function will be called if it receives an 'EXIT' + message from its parent. Reason will be the same as in + the 'EXIT' message.

+

Otherwise, the gen_fsm will be immediately terminated.

+

Note that for any other reason than normal, + shutdown, or {shutdown,Term} the gen_fsm is + assumed to terminate due to an error and + an error report is issued using + error_logger:format/2.

+
+
+ + Module:code_change(OldVsn, StateName, StateData, Extra) -> {ok, NextStateName, NewStateData} + Update the internal state data during upgrade/downgrade. + + OldVsn = Vsn | {down, Vsn} +   Vsn = term() + StateName = NextStateName = atom() + StateData = NewStateData = term() + Extra = term() + + +

This function is called by a gen_fsm when it should update + its internal state data during a release upgrade/downgrade, + i.e. when the instruction {update,Module,Change,...} + where Change={advanced,Extra} is given in + the appup file. See + OTP Design Principles.

+

In the case of an upgrade, OldVsn is Vsn, and + in the case of a downgrade, OldVsn is + {down,Vsn}. Vsn is defined by the vsn + attribute(s) of the old version of the callback module + Module. If no such attribute is defined, the version is + the checksum of the BEAM file.

+

StateName is the current state name and + StateData the internal state data of the gen_fsm.

+

Extra is passed as-is from the {advanced,Extra} + part of the update instruction.

+

The function should return the new current state name and + updated internal data.

+
+
+
+ +
+ SEE ALSO +

gen_event(3), + gen_server(3), + supervisor(3), + proc_lib(3), + sys(3)

+
+
+ -- cgit v1.2.3