From: Ulf W. <uw...@us...> - 2006-03-06 13:31:42
|
Update of /cvsroot/jungerl/jungerl/lib/plain_fsm/doc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25000/doc Modified Files: plain_fsm.html Log Message: plain_fsm-0.7 Index: plain_fsm.html =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/plain_fsm/doc/plain_fsm.html,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- plain_fsm.html 13 Feb 2004 16:25:00 -0000 1.2 +++ plain_fsm.html 6 Mar 2006 13:31:35 -0000 1.3 @@ -5,322 +5,363 @@ <link rel="stylesheet" type="text/css" href="stylesheet.css"> </head> <body bgcolor="white"> + <h1>Module plain_fsm</h1> -A behaviour/support library for writing plain Erlang FSMs.<ul><li><a href="#description">Description</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul><p><b>Authors:</b> Ulf Wiger, (<a href="mailto:ulf...@er..."><tt>ulf...@er...</tt></a>).</p> -<h2><a name="description">Description</a></h2>A behaviour/support library for writing plain Erlang FSMs. - - <p>This module implements an OTP behaviour for writing plain Erlang FSMs, - alleviating a long-standing gripe of mine that the OTP behaviours, for all - their power, force programmers into a coding style that is very much - different from that taught in the Basic Erlang Course (or the book, or - online tutorials, ...) -- the type of programming that made us want to - use Erlang in the first place.</p> - - <p>Only in my old age have I begun to understand fully what a sacrifice - this is. See <a href="pots/index.html"> - Programming Models for Concurrency </a> for a detailed discussion of - the issues involved.</p> - - <p>The requirements that drove us away from plain Erlang programming - in the first place were: - <ul> - <li><b>The need to support <i>system messages</i></b> to control upgrade, - state inspection, shutdown, etc. The plain_fsm library solves this in a - reasonable way, I think.</li> - <li><b>The need for debugging support</b>. The debugging support in - e.g. gen_server is, I believe, rendered obsolete by the new powerful - trace support (and dbg) in later versions of OTP.</li> - <li>In the case of gen_server, <b>reducing the need to reinvent the - wheel</b>, a valid point, but more so for e.g. the client side of - gen_server:call(). In a protocol state machine, the only thing that - really needs reusing is the handling of system messages.</li> - </ul> - </p> - - <p>However, the behaviours provided by OTP for FSM programming, - <code>gen_server</code> and <code>gen_fsm</code> (<code>gen_server</code> - is perhaps a more common choice than <code>gen_fsm</code>), both have the - distinct drawback that you cannot normally start with a classic Erlang design - and then migrate to a behaviour without significant code rewrite. In - addition, the two behaviours are semantically different from the classic - Erlang design</p> - - <h2>Using plain_fsm</h2> - - <p>First, write your state machine without worrying about OTP system - messages. Once you're happy with it, figure out where you really want - to handle system messages. Normally, it will suffice to do it in a fairly - stable state. </p> - - <p>In the states where you want to handle system messages, you have - three choices:</p> - - <h3>(A) Insert the system messages in the receive clause:</h3> - - <pre> - idle(S) -> - Parent = plain_fsm:info(parent), - receive - {system, From, Req} -> - plain_fsm:handle_system_msg(From, Req, S, fun(S1) -> idle(S1) end); - {'EXIT', Parent, Reason} -> - plain_fsm:parent_EXIT(Reason, S); - ... %% your original code here - end. - </pre> - - <p>This has the advantage that everyone can understand what's going on. - The part that plain_fsm.erl helps you with is the set of functions - <code>system_code_change()</code>, <code>system_continue()</code>, - <code>system_shutdown()</code>, <code>format_status()</code>, which - are required callbacks when you handle system messages directly.</p> - - <h3>(B) Handle system messages and unknown messages together:</h3> - - <pre> - idle(S) -> - Parent = plain_fsm:info(parent), - receive - ... %% your original code here - Msg -> - plain_fsm:handle_msg(Msg, State, fun(S1) -> idle(S1) end) - end. - </pre> - - <p>This is quite convenient if the receive statement already has a - 'catch-all' clause, discarding unknown messages. - <code>plain_fsm:handle_msg/3</code> will handle system messages properly - and ignore any other message.</p> - - <h3>(C) Write a pseudo wrapper function around your receive clause:</h3> - - <pre> - idle(S) -> - plain_fsm:extended_receive( - receive - ... %% your original code - end). - </pre> - - <p>The function <code>plain_fsm:extended_receive/1</code> is replaced - in a <i>parse_transform</i> into something that looks very much like - the previous program (A). The code, as it reads, requires the reader to - know that the transformation takes place, otherwise the semantics - would be confusing (you cannot solve the problem using a real function - that way.) On the plus side, this is a fairly small violation of both - the original code and Erlang's semantics.</p> - - <p><i>Note that for this to work, you must include "plain_fsm.hrl" - in your module.</i></p> - - <h4>Example</h4> - <p>In the module <a href="../src/fsm_example.erl">fsm_example.erl</a> - (included in the plain_fsm package), we choose to handle system - messages in the idle state. The example code is runnable, and supports - suspend, resume, status inspection, and code change.</p> - <p>Imagine that the code initially looked like this:</p> - <pre> - idle(S) -> +A behaviour/support library for writing plain Erlang FSMs. +<ul><li><a href="#description">Description</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul> +<p><b>This module defines the <tt>plain_fsm</tt> behaviour.</b><br> Required callback functions: <tt>code_change/3</tt>, <tt>data_vsn/0</tt>.</p> +<p><b>Authors:</b> Ulf Wiger, (<a href="mailto:ulf...@er..."><tt>ulf...@er...</tt></a>).</p> + +<h2><a name="description">Description</a></h2><p>A behaviour/support library for writing plain Erlang FSMs.</p> + + <p>This module implements an OTP behaviour for writing plain Erlang FSMs, + alleviating a long-standing gripe of mine that the OTP behaviours, for all + their power, force programmers into a coding style that is very much + different from that taught in the Basic Erlang Course (or the book, or + online tutorials, ...) -- the type of programming that made us want to + use Erlang in the first place.</p> + + <p>Only in my old age have I begun to understand fully what a sacrifice + this is. See <a href="pots/index.html"> + Programming Models for Concurrency </a> for a detailed discussion of + the issues involved.</p> + + <p>The requirements that drove us away from plain Erlang programming + in the first place were: + <ul> + <li><b>The need to support <i>system messages</i></b> to control upgrade, + state inspection, shutdown, etc. The plain_fsm library solves this in a + reasonable way, I think.</li> + <li><b>The need for debugging support</b>. The debugging support in + e.g. gen_server is, I believe, rendered obsolete by the new powerful + trace support (and dbg) in later versions of OTP.</li> + <li>In the case of gen_server, <b>reducing the need to reinvent the + wheel</b>, a valid point, but more so for e.g. the client side of + gen_server:call(). In a protocol state machine, the only thing that + really needs reusing is the handling of system messages.</li> + </ul> + </p> + + <p>However, the behaviours provided by OTP for FSM programming, + <code>gen_server</code> and <code>gen_fsm</code> (<code>gen_server</code> + is perhaps a more common choice than <code>gen_fsm</code>), both have the + distinct drawback that you cannot normally start with a classic + Erlang design and then migrate to a behaviour without significant + code rewrite. In addition, the two behaviours are semantically different + from the classic Erlang design</p> + + <h2>Using plain_fsm</h2> + + <p>First, write your state machine without worrying about OTP system + messages. Once you're happy with it, figure out where you really want + to handle system messages. Normally, it will suffice to do it in a fairly + stable state. A good rule of thumb is that the top-level state machine + should handle system messages, while the transient (sub-) states + shouldn't</p> + + <p>In the states where you want to handle system messages, you have + three choices:</p> + + <h3>(A) Insert the system messages in the receive clause:</h3> + + <pre> + idle(S) -> + Parent = plain_fsm:info(parent), receive - a -> - io:format("going to state a~n", []), - a(S); - b -> - io:format("going to state b~n", []), - b(S) - after 10000 -> - io:format("timeout in idle~n", []), - idle(S) - end). - </pre> - - <p>The change required to handle system messages is as follows:</p> - <pre> - idle(S) -> - <a href="#extended_receive-1">plain_fsm:extended_receive</a>( - receive - a -> - io:format("going to state a~n", []), - a(S); - b -> - io:format("going to state b~n", []), - b(S) - after 10000 -> - io:format("timeout in idle~n", []), - idle(S) - end). - </pre> - - <p>In addition, we change the start function from, in this case:</p> - <pre> - spawn_link() -> - spawn_link(fun() -> - process_flag(trap_exit, true), - idle(mystate) - end). - </pre> - <p>Is changed into:</p> - <pre> - spawn_link() -> - <a href="#spawn_link-2">plain_fsm:spawn_link</a>(?MODULE, fun() -> - process_flag(trap_exit,true), - idle(mystate) - end). - </pre> - <p>See also <a href="#spawn-2">spawn/2</a> and <a href="#spawn_opt-3">spawn_opt/3</a> - for information on other possible start functions.</p> - <p>To be fully compliant, you also need to supply a code_change/3 function. - See <a href="#behaviour_info-1">behaviour_info/1</a> for details.</p> + {system, From, Req} -> + plain_fsm:handle_system_msg( + From, Req, S, fun(S1) -> idle(S1) end); + {'EXIT', Parent, Reason} -> + plain_fsm:parent_EXIT(Reason, S); + ... %% your original code here + end. + </pre> + + <p>This has the advantage that everyone can understand what's going on. + The part that plain_fsm.erl helps you with is the set of functions + <code>system_code_change()</code>, <code>system_continue()</code>, + <code>system_shutdown()</code>, <code>format_status()</code>, which + are required callbacks when you handle system messages directly.</p> + + <h3>(B) Handle system messages and unknown messages together:</h3> + + <pre> + idle(S) -> + Parent = plain_fsm:info(parent), + receive + ... %% your original code here + Msg -> + plain_fsm:handle_msg(Msg, State, fun(S1) -> idle(S1) end) + end. + </pre> + + <p>This is quite convenient if the receive statement already has a + 'catch-all' clause, discarding unknown messages. + <code>plain_fsm:handle_msg/3</code> will handle system messages properly + and ignore any other message.</p> + + <h3>(C) Write a pseudo wrapper function around your receive clause:</h3> + + <pre> + idle(S) -> + plain_fsm:extended_receive( + receive + ... %% your original code + end). + </pre> + + <p>The function <code>plain_fsm:extended_receive/1</code> is replaced + in a <i>parse_transform</i> into something that looks very much like + the previous program (A). The code, as it reads, requires the reader to + know that the transformation takes place, otherwise the semantics + would be confusing (you cannot solve the problem using a real function + that way.) On the plus side, this is a fairly small violation of both + the original code and Erlang's semantics.</p> + + <p><i>Note that for this to work, you must include "plain_fsm.hrl" + in your module.</i></p> + + <h4>Example</h4> + <p>In the module <a href="../src/fsm_example.erl">fsm_example.erl</a> + (included in the plain_fsm package), we choose to handle system + messages in the idle state. The example code is runnable, and supports + suspend, resume, status inspection, and code change.</p> + <p>Imagine that the code initially looked like this:</p> + <pre> + idle(S) -> + receive + a -> + io:format("going to state a~n", []), + a(S); + b -> + io:format("going to state b~n", []), + b(S) + after 10000 -> + io:format("timeout in idle~n", []), + idle(S) + end). + </pre> + + <p>The change required to handle system messages is as follows:</p> + <pre> + idle(S) -> + <a href="#extended_receive-1">plain_fsm:extended_receive</a>( + receive + a -> + io:format("going to state a~n", []), + a(S); + b -> + io:format("going to state b~n", []), + b(S) + after 10000 -> + io:format("timeout in idle~n", []), + idle(S) + end). + </pre> + + <p>In addition, we change the start function from, in this case:</p> + <pre> + spawn_link() -> + spawn_link(fun() -> + process_flag(trap_exit, true), + idle(mystate) + end). + </pre> + <p>Is changed into:</p> + <pre> + spawn_link() -> + <a href="#spawn_link-2">plain_fsm:spawn_link</a>(?MODULE, fun() -> + process_flag(trap_exit,true), + idle(mystate) + end). + </pre> + <p>See also <a href="#spawn-2">spawn/2</a> and <a href="#spawn_opt-3">spawn_opt/3</a> + for information on other possible start functions.</p> + <p>To be fully compliant, you also need to supply a code_change/3 function. + See <a href="#behaviour_info-1">behaviour_info/1</a> for details.</p> <h2><a name="index">Function Index</a></h2> <table width="100%" border="1"><tr><td valign="top"><a href="#behaviour_info-1">behaviour_info/1</a></td><td>Defines which functions this behaviour expects to be exported from - the user's callback module.</td></tr> + the user's callback module.</td></tr> <tr><td valign="top"><a href="#extended_receive-1">extended_receive/1</a></td><td>Virtual function used to wrap receive clauses.</td></tr> <tr><td valign="top"><a href="#handle_msg-3">handle_msg/3</a></td><td>Called in a "catch-all" clause within a receive statement.</td></tr> <tr><td valign="top"><a href="#handle_system_msg-4">handle_system_msg/4</a></td><td>Called when the process receives a system message.</td></tr> +<tr><td valign="top"><a href="#hibernate-3">hibernate/3</a></td><td>Virtual function used to wrap a call to the BIF erlang:hibernate/3.</td></tr> <tr><td valign="top"><a href="#info-1">info/1</a></td><td>retrieves meta-data for the plain_fsm process.</td></tr> <tr><td valign="top"><a href="#parent_EXIT-2">parent_EXIT/2</a></td><td>Handles parent termination properly.</td></tr> <tr><td valign="top"><a href="#spawn-2">spawn/2</a></td><td>Equivalent to <code>proc_lib:spawn(StartF)</code>.</td></tr> <tr><td valign="top"><a href="#spawn_link-2">spawn_link/2</a></td><td>Equivalent to <code>proc_lib:spawn_link(StartF)</code>.</td></tr> <tr><td valign="top"><a href="#spawn_opt-3">spawn_opt/3</a></td><td>Equivalent to <code>proc_lib:spawn_opt(StartF, Opts)</code>.</td></tr> +<tr><td valign="top"><a href="#spawn_opt-4">spawn_opt/4</a></td><td>Equivalent to <code>proc_lib:spawn_opt(Node, StartF, Opts)</code>.</td></tr> +<tr><td valign="top"><a href="#start_opt-4">start_opt/4</a></td><td/></tr> <tr><td valign="top"><a href="#store_name-1">store_name/1</a></td><td>stores an internal name for the FSM - (for <code>sys:get_status()</code>).</td></tr> + (for <code>sys:get_status()</code>).</td></tr> +<tr><td valign="top"><a href="#wake_up-5">wake_up/5</a></td><td/></tr> </table> <h2><a name="functions">Function Details</a></h2> <h3><a name="behaviour_info-1">behaviour_info/1</a></h3> -<p><tt>behaviour_info(Other::atom()) -> term()</tt></p> +<p><tt>behaviour_info(Other::atom()) -> term()</tt></p> <p>Defines which functions this behaviour expects to be exported from - the user's callback module. plain_fsm requires only code_change/3 to - be present. The semantics of <code>Mod:code_change/3</code> are as follows: - <pre> - code_change(OldVsn, State, Extra) -> {ok, NewState}. - </pre> - <p>The above code is just like it would look like in a gen_server callback - module.</p> - <pre> - code_change(OldVsn, State, Extra) -> {ok, NewState, Options}. - </pre> - <p>where <code>Options</code> may be any of </p> - <ul> - <li><code>{mod, module()}</code>, allowing you to switch callback - modules during a code change.</li> - <li><code>{name, name()}</code>, allowing you to rename the process - (note that you have to handle name registration yourself.)</li> - <li><code>{cont, atom() | function(1)}</code>, allowing you to provide - another continuation (point of entry into your own code after the - code change.)</li> - </ul></p> + the user's callback module. plain_fsm requires only code_change/3 to + be present. The semantics of <code>Mod:code_change/3</code> are as follows: + <pre> + code_change(OldVsn, State, Extra) -> {ok, NewState}. + </pre> + <p>The above code is just like it would look like in a gen_server callback + module.</p> + <pre> + code_change(OldVsn, State, Extra) -> {ok, NewState, Options}. + </pre> + <p>where <code>Options</code> may be any of </p> + <ul> + <li><code>{mod, module()}</code>, allowing you to switch callback + modules during a code change.</li> + <li><code>{name, name()}</code>, allowing you to rename the process + (note that you have to handle name registration yourself.)</li> + <li><code>{cont, atom() | function(1)}</code>, allowing you to provide + another continuation (point of entry into your own code after the + code change.)</li> + </ul></p> <h3><a name="extended_receive-1">extended_receive/1</a></h3> -<p><tt>extended_receive(Expr::Expr) -> VOID</tt></p> +<p><tt>extended_receive(Expr) -> VOID</tt></p> <p>Virtual function used to wrap receive clauses. - <p>This function cannot be called directly, but is intended as a syntactic - wrapper around a receive clause. It will be transformed at compile time - to a set of receive patterns handling system messages and parent termination - according to the OTP rules. The transform requires that the surrounding - function has exactly one argument (the "State" or "Loop Data".)</p> - <p>To trigger the parse_transform, include the file - <code>plain_fsm.hrl</code> (found in <code>plain_fsm/inc/</code>) in - your module, and the Erlang compiler must be able to find the module - <code>plain_fsm.beam</code>. If <code>erlc</code> is used, this is - accomplished by adding <code>-pa .../plain_fsm/ebin</code> to the - <code>erlc</code> command.</p></p> + <p>This function cannot be called directly, but is intended as a syntactic + wrapper around a receive clause. It will be transformed at compile time + to a set of receive patterns handling system messages and parent + termination according to the OTP rules. The transform requires that + the surrounding function has exactly one argument (the "State" or + "Loop Data".)</p> + <p>To trigger the parse_transform, include the file + <code>plain_fsm.hrl</code> (found in <code>plain_fsm/inc/</code>) in + your module, and the Erlang compiler must be able to find the module + <code>plain_fsm_xform.beam</code>. If <code>erlc</code> is used, this is + accomplished by adding <code>-pa .../plain_fsm/ebin</code> to the + <code>erlc</code> command.</p></p> <h3><a name="handle_msg-3">handle_msg/3</a></h3> -<p><tt>handle_msg(Other::Msg, State::State, Cont::<a href="#type-cont">cont()</a>) -> NEVER_RETURNS</tt></p> +<p><tt>handle_msg(Other::Msg, State, Cont::<a href="#type-cont">cont()</a>) -> NEVER_RETURNS</tt></p> <p>Called in a "catch-all" clause within a receive statement. - <p>This function never returns. It will handle system messages - properly and ignore anything else. - Example:</p> - <pre> - idle(S) -> - receive - ... - Msg -> - plain_fsm:handle_msg(Msg, S, fun(S1) -> - idle(S1) - end) - end. - </pre> - - <p>Note that this function should <i>only</i> be used if it is known - to be safe to discard unknown messages. In most state machines there should - be at least <i>one</i> state where unknown messages are discarded; in - these states, the handle_msg/3 function can be a convenient way to - handle both unknown messages and system messages.</p> - - <p>The <code>Cont</code> argument should be either a fun with one argument - (the new state), which jumps back into the user code in the proper place, - or it can be the name of a function (in this case, 'idle'). In the latter - case, the function in question must be exported; in the former case, this - is not necessary.</p></p> + <p>This function never returns. It will handle system messages + properly and ignore anything else. + Example:</p> + <pre> + idle(S) -> + receive + ... + Msg -> + plain_fsm:handle_msg(Msg, S, fun(S1) -> + idle(S1) + end) + end. + </pre> + + <p>Note that this function should <i>only</i> be used if it is known + to be safe to discard unknown messages. In most state machines there should + be at least <i>one</i> state where unknown messages are discarded; in + these states, the handle_msg/3 function can be a convenient way to + handle both unknown messages and system messages.</p> + + <p>The <code>Cont</code> argument should be either a fun with one argument + (the new state), which jumps back into the user code in the proper place, + or it can be the name of a function (in this case, 'idle'). In the latter + case, the function in question must be exported; in the former case, this + is not necessary.</p></p> <h3><a name="handle_system_msg-4">handle_system_msg/4</a></h3> -<p><tt>handle_system_msg(Req::Req, From::From, State::State, Cont::<a href="#type-cont">cont()</a>) -> NEVER_RETURNS</tt></p> +<p><tt>handle_system_msg(Req, From, State, Cont::<a href="#type-cont">cont()</a>) -> NEVER_RETURNS</tt></p> <p>Called when the process receives a system message. - <p>This function never returns. If the program handles system messages - explicitly, this function can be called to handle them in the plain_fsm - way. Example:</p> - <pre> - idle(S) -> - receive - {system, From, Req} -> - plain_fsm:handle_system_msg(From, Req, S, fun(S1) -> - idle(S1) - end); - ... - end. - </pre> - <p>The <code>Cont</code> argument should be either a fun with one argument - (the new state), which jumps back into the user code in the proper place, - or it can be the name of a function (in this case, 'idle'). In the latter - case, the function in question must be exported; in the former case, this - is not necessary.</p></p> + <p>This function never returns. If the program handles system messages + explicitly, this function can be called to handle them in the plain_fsm + way. Example:</p> + <pre> + idle(S) -> + receive + {system, From, Req} -> + plain_fsm:handle_system_msg(From, Req, S, fun(S1) -> + idle(S1) + end); + ... + end. + </pre> + <p>The <code>Cont</code> argument should be either a fun with one argument + (the new state), which jumps back into the user code in the proper place, + or it can be the name of a function (in this case, 'idle'). In the latter + case, the function in question must be exported; in the former case, this + is not necessary.</p></p> + +<h3><a name="hibernate-3">hibernate/3</a></h3> +<p><tt>hibernate(M::atom(), F::atom(), A::[IntState]) -> NEVER_RETURNS</tt></p> +<p>Virtual function used to wrap a call to the BIF erlang:hibernate/3. + <p>This function cannot be called directly, but translates to the call + <code>erlang:hibernate(plain_fsm,wake_up,[data_vsn(),Module,M,F,A])</code> + where <code>Module:data_vsn()</code> and <code>Module:code_change/3</code> + are expected to exist (the parse_transform will add and export the + function <code>data_vsn() -< 0</code>, if it doesn't already exist.)</p> + <p>The function <code>plain_fsm:wake_up/5</code> will begin by calling + <code>Module:data_vsn()</code>, and if it is the same as before, simply + call <code>apply(M,F,A)</code>. Otherwise, <code>Module:code_change(OldVsn, + IntState, hibernate)</code> will be called first. This allows a plain_fsm + behaviour module to be "bootstrapped" to a new version during hibernation. + </p></p> <h3><a name="info-1">info/1</a></h3> -<p><tt>info(What::atom()) -> term()</tt> +<p><tt>info(What::atom()) -> term()</tt> <ul><li><tt>What = debug | name | mod | parent</tt></li></ul></p> <p>retrieves meta-data for the plain_fsm process. - <p>Description of available meta-data:</p> - <pre> - debug : See the manual for sys.erl - name : Internal name, normally the same as the registered name. - initially undefined, can be set via plain_fsm:store_name/1. - mod : Name of the callback module. - parent: The pid() of the parent process. - </pre></p> + <p>Description of available meta-data:</p> + <pre> + debug : See the manual for sys.erl + name : Internal name, normally the same as the registered name. + initially undefined, can be set via plain_fsm:store_name/1. + mod : Name of the callback module. + parent: The pid() of the parent process. + </pre></p> <h3><a name="parent_EXIT-2">parent_EXIT/2</a></h3> -<p><tt>parent_EXIT(Reason::Reason, State::State) -> EXIT</tt></p> +<p><tt>parent_EXIT(Reason, State) -> EXIT</tt></p> <p>Handles parent termination properly. - <p>This function is called when the parent of a plain_fsm instance dies. - The OTP rules state that the child should die with the same reason - as the parent (especially in the case of Reason='shutdown'.)</p></p> + <p>This function is called when the parent of a plain_fsm instance dies. + The OTP rules state that the child should die with the same reason + as the parent (especially in the case of Reason='shutdown'.)</p></p> <h3><a name="spawn-2">spawn/2</a></h3> -<p><tt>spawn(Mod::atom(), StartF::function()) -> pid()</tt></p> +<p><tt>spawn(Mod::atom(), StartF::function()) -> pid()</tt></p> <p>Equivalent to <code>proc_lib:spawn(StartF)</code>. This function also - initializes the plain_fsm meta-data.</p> + initializes the plain_fsm meta-data.</p> <h3><a name="spawn_link-2">spawn_link/2</a></h3> -<p><tt>spawn_link(Mod::atom(), StartF::function()) -> pid()</tt></p> +<p><tt>spawn_link(Mod::atom(), StartF::function()) -> pid()</tt></p> <p>Equivalent to <code>proc_lib:spawn_link(StartF)</code>. - This function also initializes the plain_fsm meta-data.</p> + This function also initializes the plain_fsm meta-data.</p> <h3><a name="spawn_opt-3">spawn_opt/3</a></h3> -<p><tt>spawn_opt(Mod::atom(), StartF::function(), Opts::list()) -> pid()</tt></p> +<p><tt>spawn_opt(Mod::atom(), StartF::function(), Opts::list()) -> pid()</tt></p> <p>Equivalent to <code>proc_lib:spawn_opt(StartF, Opts)</code>. - This function also initializes the plain_fsm meta-data.</p> + This function also initializes the plain_fsm meta-data.</p> + +<h3><a name="spawn_opt-4">spawn_opt/4</a></h3> +<p><tt>spawn_opt(Node::atom(), Mod::atom(), StartF::function(), Opts::list()) -> pid()</tt></p> +<p>Equivalent to <code>proc_lib:spawn_opt(Node, StartF, Opts)</code>. + This function also initializes the sysFsm meta-data.</p> + +<h3><a name="start_opt-4">start_opt/4</a></h3> +<tt>start_opt(Mod, InitF, Timeout, Opts) -> term() +</tt> <h3><a name="store_name-1">store_name/1</a></h3> -<p><tt>store_name(Name::term()) -> ok</tt></p> +<p><tt>store_name(Name::term()) -> ok</tt></p> <p>stores an internal name for the FSM - (for <code>sys:get_status()</code>). - This can be used if the FSM were started as an anonymous process - (the only kind currently supported). - Note that this function does not register the name. The name stored - is the one that shows up in sys:get_status/1. No restriction is made - here regarding the data type.</p> + (for <code>sys:get_status()</code>). + This can be used if the FSM were started as an anonymous process + (the only kind currently supported). + Note that this function does not register the name. The name stored + is the one that shows up in sys:get_status/1. No restriction is made + here regarding the data type.</p> + +<h3><a name="wake_up-5">wake_up/5</a></h3> +<tt>wake_up(OldVsn, Module, M, F, A) -> term() +</tt> </body> -</html> \ No newline at end of file +</html> |