Sophie

Sophie

distrib > Fedora > 17 > i386 > media > updates > by-pkgid > 675c8c8167236dfcf8d66da674f931e8 > files > 15

erlang-doc-R15B-03.3.fc17.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns:fn="http://www.w3.org/2005/02/xpath-functions">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="../otp_doc.css" type="text/css">
<title>Erlang -- Gen_Fsm Behaviour</title>
</head>
<body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000"><div id="container">
<script id="js" type="text/javascript" language="JavaScript" src="../js/flipmenu/flipmenu.js"></script><script id="js2" type="text/javascript" src="../js/erlresolvelinks.js"></script><script language="JavaScript" type="text/javascript">
            <!--
              function getWinHeight() {
                var myHeight = 0;
                if( typeof( window.innerHeight ) == 'number' ) {
                  //Non-IE
                  myHeight = window.innerHeight;
                } else if( document.documentElement && ( document.documentElement.clientWidth ||
                                                         document.documentElement.clientHeight ) ) {
                  //IE 6+ in 'standards compliant mode'
                  myHeight = document.documentElement.clientHeight;
                } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
                  //IE 4 compatible
                  myHeight = document.body.clientHeight;
                }
                return myHeight;
              }

              function setscrollpos() {
                var objf=document.getElementById('loadscrollpos');
                 document.getElementById("leftnav").scrollTop = objf.offsetTop - getWinHeight()/2;
              }

              function addEvent(obj, evType, fn){
                if (obj.addEventListener){
                obj.addEventListener(evType, fn, true);
                return true;
              } else if (obj.attachEvent){
                var r = obj.attachEvent("on"+evType, fn);
                return r;
              } else {
                return false;
              }
             }

             addEvent(window, 'load', setscrollpos);

             //--></script><div id="leftnav"><div class="innertube">
<img alt="Erlang logo" src="../erlang-logo.png"><br><small><a href="users_guide.html">User's Guide</a><br><a href="../pdf/otp-system-documentation-5.9.3.1.pdf">PDF</a><br><a href="../index.html">Top</a></small><p><strong>OTP Design Principles</strong><br><strong>User's Guide</strong><br><small>Version 5.9.3.1</small></p>
<br><a href="javascript:openAllFlips()">Expand All</a><br><a href="javascript:closeAllFlips()">Contract All</a><p><small><strong>Chapters</strong></small></p>
<ul class="flipMenu" imagepath="../js/flipmenu">
<li id="no" title="Overview" expanded="false">Overview<ul>
<li><a href="des_princ.html">
              Top of chapter
            </a></li>
<li title="Supervision Trees"><a href="des_princ.html#id65609">Supervision Trees</a></li>
<li title="Behaviours"><a href="des_princ.html#id59741">Behaviours</a></li>
<li title="Applications"><a href="des_princ.html#id66345">Applications</a></li>
<li title="Releases"><a href="des_princ.html#id61095">Releases</a></li>
<li title="Release Handling"><a href="des_princ.html#id60860">Release Handling</a></li>
</ul>
</li>
<li id="no" title="Gen_Server Behaviour" expanded="false">Gen_Server Behaviour<ul>
<li><a href="gen_server_concepts.html">
              Top of chapter
            </a></li>
<li title="Client-Server Principles"><a href="gen_server_concepts.html#id64192">Client-Server Principles</a></li>
<li title="Example"><a href="gen_server_concepts.html#id61515">Example</a></li>
<li title="Starting a Gen_Server"><a href="gen_server_concepts.html#id67798">Starting a Gen_Server</a></li>
<li title="Synchronous Requests - Call"><a href="gen_server_concepts.html#id66815">Synchronous Requests - Call</a></li>
<li title="Asynchronous Requests - Cast"><a href="gen_server_concepts.html#id62843">Asynchronous Requests - Cast</a></li>
<li title="Stopping"><a href="gen_server_concepts.html#id67345">Stopping</a></li>
<li title="Handling Other Messages"><a href="gen_server_concepts.html#id67435">Handling Other Messages</a></li>
</ul>
</li>
<li id="loadscrollpos" title="Gen_Fsm Behaviour" expanded="true">Gen_Fsm Behaviour<ul>
<li><a href="fsm.html">
              Top of chapter
            </a></li>
<li title="Finite State Machines"><a href="fsm.html#id68991">Finite State Machines</a></li>
<li title="Example"><a href="fsm.html#id69046">Example</a></li>
<li title="Starting a Gen_Fsm"><a href="fsm.html#id69093">Starting a Gen_Fsm</a></li>
<li title="Notifying About Events"><a href="fsm.html#id69273">Notifying About Events</a></li>
<li title="Timeouts"><a href="fsm.html#id69352">Timeouts</a></li>
<li title="All State Events"><a href="fsm.html#id69391">All State Events</a></li>
<li title="Stopping"><a href="fsm.html#id69423">Stopping</a></li>
<li title="Handling Other Messages"><a href="fsm.html#id69514">Handling Other Messages</a></li>
</ul>
</li>
<li id="no" title="Gen_Event Behaviour" expanded="false">Gen_Event Behaviour<ul>
<li><a href="events.html">
              Top of chapter
            </a></li>
<li title="Event Handling Principles"><a href="events.html#id69613">Event Handling Principles</a></li>
<li title="Example"><a href="events.html#id69665">Example</a></li>
<li title="Starting an Event Manager"><a href="events.html#id69706">Starting an Event Manager</a></li>
<li title="Adding an Event Handler"><a href="events.html#id70832">Adding an Event Handler</a></li>
<li title="Notifying About Events"><a href="events.html#id70916">Notifying About Events</a></li>
<li title="Deleting an Event Handler"><a href="events.html#id70987">Deleting an Event Handler</a></li>
<li title="Stopping"><a href="events.html#id71062">Stopping</a></li>
<li title="Handling Other Messages"><a href="events.html#id71116">Handling Other Messages</a></li>
</ul>
</li>
<li id="no" title="Supervisor Behaviour" expanded="false">Supervisor Behaviour<ul>
<li><a href="sup_princ.html">
              Top of chapter
            </a></li>
<li title="Supervision Principles"><a href="sup_princ.html#id71210">Supervision Principles</a></li>
<li title="Example"><a href="sup_princ.html#id71235">Example</a></li>
<li title="Restart Strategy"><a href="sup_princ.html#id71306">Restart Strategy</a></li>
<li title="Maximum Restart Frequency"><a href="sup_princ.html#id71384">Maximum Restart Frequency</a></li>
<li title="Child Specification"><a href="sup_princ.html#id71906">Child Specification</a></li>
<li title="Starting a Supervisor"><a href="sup_princ.html#id72235">Starting a Supervisor</a></li>
<li title="Adding a Child Process"><a href="sup_princ.html#id72349">Adding a Child Process</a></li>
<li title="Stopping a Child Process"><a href="sup_princ.html#id72393">Stopping a Child Process</a></li>
<li title="Simple-One-For-One Supervisors"><a href="sup_princ.html#id72443">Simple-One-For-One Supervisors</a></li>
<li title="Stopping"><a href="sup_princ.html#id72567">Stopping</a></li>
</ul>
</li>
<li id="no" title="Sys and Proc_Lib" expanded="false">Sys and Proc_Lib<ul>
<li><a href="spec_proc.html">
              Top of chapter
            </a></li>
<li title="Simple Debugging"><a href="spec_proc.html#id72665">Simple Debugging</a></li>
<li title="Special Processes"><a href="spec_proc.html#id72749">Special Processes</a></li>
<li title="User-Defined Behaviours"><a href="spec_proc.html#id73359">User-Defined Behaviours</a></li>
</ul>
</li>
<li id="no" title="Applications" expanded="false">Applications<ul>
<li><a href="applications.html">
              Top of chapter
            </a></li>
<li title="Application Concept"><a href="applications.html#id73539">Application Concept</a></li>
<li title="Application Callback Module"><a href="applications.html#id73606">Application Callback Module</a></li>
<li title="Application Resource File"><a href="applications.html#id73720">Application Resource File</a></li>
<li title="Directory Structure"><a href="applications.html#id73969">Directory Structure</a></li>
<li title="Application Controller"><a href="applications.html#id74095">Application Controller</a></li>
<li title="Loading and Unloading Applications"><a href="applications.html#id74128">Loading and Unloading Applications</a></li>
<li title="Starting and Stopping Applications"><a href="applications.html#id74190">Starting and Stopping Applications</a></li>
<li title="Configuring an Application"><a href="applications.html#id74278">Configuring an Application</a></li>
<li title="Application Start Types"><a href="applications.html#id74477">Application Start Types</a></li>
</ul>
</li>
<li id="no" title="Included Applications" expanded="false">Included Applications<ul>
<li><a href="included_applications.html">
              Top of chapter
            </a></li>
<li title="Definition"><a href="included_applications.html#id74617">Definition</a></li>
<li title="Specifying Included Applications"><a href="included_applications.html#id74682">Specifying Included Applications</a></li>
<li title="Synchronizing Processes During Startup"><a href="included_applications.html#id74708">Synchronizing Processes During Startup</a></li>
</ul>
</li>
<li id="no" title="Distributed Applications" expanded="false">Distributed Applications<ul>
<li><a href="distributed_applications.html">
              Top of chapter
            </a></li>
<li title="Definition"><a href="distributed_applications.html#id74921">Definition</a></li>
<li title="Specifying Distributed Applications"><a href="distributed_applications.html#id74957">Specifying Distributed Applications</a></li>
<li title="Starting and Stopping Distributed Applications"><a href="distributed_applications.html#id75164">Starting and Stopping Distributed Applications</a></li>
<li title="Failover"><a href="distributed_applications.html#id75266">Failover</a></li>
<li title="Takeover"><a href="distributed_applications.html#id75408">Takeover</a></li>
</ul>
</li>
<li id="no" title="Releases" expanded="false">Releases<ul>
<li><a href="release_structure.html">
              Top of chapter
            </a></li>
<li title="Release Concept"><a href="release_structure.html#id75603">Release Concept</a></li>
<li title="Release Resource File"><a href="release_structure.html#id75656">Release Resource File</a></li>
<li title="Generating Boot Scripts"><a href="release_structure.html#id75803">Generating Boot Scripts</a></li>
<li title="Creating a Release Package"><a href="release_structure.html#id75897">Creating a Release Package</a></li>
<li title="Directory Structure"><a href="release_structure.html#id76046">Directory Structure</a></li>
</ul>
</li>
<li id="no" title="Release Handling" expanded="false">Release Handling<ul>
<li><a href="release_handling.html">
              Top of chapter
            </a></li>
<li title="Release Handling Principles"><a href="release_handling.html#id76299">Release Handling Principles</a></li>
<li title="Requirements"><a href="release_handling.html#id76543">Requirements</a></li>
<li title="Distributed Systems"><a href="release_handling.html#id76636">Distributed Systems</a></li>
<li title="Release Handling Instructions"><a href="release_handling.html#id76663">Release Handling Instructions</a></li>
<li title="Application Upgrade File"><a href="release_handling.html#id77177">Application Upgrade File</a></li>
<li title="Release Upgrade File"><a href="release_handling.html#id77359">Release Upgrade File</a></li>
<li title="Installing a Release"><a href="release_handling.html#id77515">Installing a Release</a></li>
<li title="Updating Application Specifications"><a href="release_handling.html#id77986">Updating Application Specifications</a></li>
</ul>
</li>
<li id="no" title="Appup Cookbook" expanded="false">Appup Cookbook<ul>
<li><a href="appup_cookbook.html">
              Top of chapter
            </a></li>
<li title="Changing a Functional Module"><a href="appup_cookbook.html#id78170">Changing a Functional Module</a></li>
<li title="Changing a Residence Module"><a href="appup_cookbook.html#id78193">Changing a Residence Module</a></li>
<li title="Changing a Callback Module"><a href="appup_cookbook.html#id78232">Changing a Callback Module</a></li>
<li title="Changing Internal State"><a href="appup_cookbook.html#id78283">Changing Internal State</a></li>
<li title="Module Dependencies"><a href="appup_cookbook.html#id78417">Module Dependencies</a></li>
<li title="Changing Code For a Special Process"><a href="appup_cookbook.html#id78588">Changing Code For a Special Process</a></li>
<li title="Changing a Supervisor"><a href="appup_cookbook.html#id78755">Changing a Supervisor</a></li>
<li title="Adding or Deleting a Module"><a href="appup_cookbook.html#id79000">Adding or Deleting a Module</a></li>
<li title="Starting or Terminating a Process"><a href="appup_cookbook.html#id79026">Starting or Terminating a Process</a></li>
<li title="Adding or Removing an Application"><a href="appup_cookbook.html#id79044">Adding or Removing an Application</a></li>
<li title="Restarting an Application"><a href="appup_cookbook.html#id79075">Restarting an Application</a></li>
<li title="Changing an Application Specification"><a href="appup_cookbook.html#id79117">Changing an Application Specification</a></li>
<li title="Changing Application Configuration"><a href="appup_cookbook.html#id79141">Changing Application Configuration</a></li>
<li title="Changing Included Applications"><a href="appup_cookbook.html#id79174">Changing Included Applications</a></li>
<li title="Changing Non-Erlang Code"><a href="appup_cookbook.html#id79414">Changing Non-Erlang Code</a></li>
<li title="Emulator Restart and Upgrade"><a href="appup_cookbook.html#id79499">Emulator Restart and Upgrade</a></li>
<li title="Emulator Upgrade from pre OTP R15"><a href="appup_cookbook.html#id79575">Emulator Upgrade from pre OTP R15</a></li>
</ul>
</li>
</ul>
</div></div>
<div id="content">
<div class="innertube">
<h1>3 Gen_Fsm Behaviour</h1>
  
  <p>This chapter should be read in conjunction with <span class="code">gen_fsm(3)</span>,
    where all interface functions and callback functions are described
    in detail.</p>

  <h3><a name="id68991">3.1 
        Finite State Machines</a></h3>
    
    <p>A finite state machine, FSM, can be described as a set of
      relations of the form:</p>
    <div class="example"><pre>
State(S) x Event(E) -&gt; Actions(A), State(S')</pre></div>
    <p>These relations are interpreted as meaning:</p>
    
      <p>If we are in state <span class="code">S</span> and the event <span class="code">E</span> occurs, we
        should perform the actions <span class="code">A</span> and make a transition to
        the state <span class="code">S'</span>.</p>
    
    <p>For an FSM implemented using the <span class="code">gen_fsm</span> behaviour,
      the state transition rules are written as a number of Erlang
      functions which conform to the following convention:</p>
    <div class="example"><pre>
StateName(Event, StateData) -&gt;
    .. code for actions here ...
    {next_state, StateName', StateData'}</pre></div>
  

  <h3><a name="id69046">3.2 
        Example</a></h3>
    
    <p>A door with a code lock could be viewed as an FSM. Initially,
      the door is locked. Anytime someone presses a button, this
      generates an event. Depending on what buttons have been pressed
      before, the sequence so far may be correct, incomplete or wrong.</p>
    <p>If it is correct, the door is unlocked for 30 seconds (30000 ms).
      If it is incomplete, we wait for another button to be pressed. If
      it is is wrong, we start all over, waiting for a new button
      sequence.</p>
    <p>Implementing the code lock FSM using <span class="code">gen_fsm</span> results in
      this callback module:</p>
    <a name="ex"></a>
    <div class="example"><pre>
-module(code_lock).
-behaviour(gen_fsm).

-export([start_link/1]).
-export([button/1]).
-export([init/1, locked/2, open/2]).

start_link(Code) -&gt;
    gen_fsm:start_link({local, code_lock}, code_lock, Code, []).

button(Digit) -&gt;
    gen_fsm:send_event(code_lock, {button, Digit}).

init(Code) -&gt;
    {ok, locked, {[], Code}}.

locked({button, Digit}, {SoFar, Code}) -&gt;
    case [Digit|SoFar] of
        Code -&gt;
            do_unlock(),
            {next_state, open, {[], Code}, 3000};
        Incomplete when length(Incomplete)&lt;length(Code) -&gt;
            {next_state, locked, {Incomplete, Code}};
        _Wrong -&gt;
            {next_state, locked, {[], Code}}
    end.

open(timeout, State) -&gt;
    do_lock(),
    {next_state, locked, State}.</pre></div>
    <p>The code is explained in the next sections.</p>
  

  <h3><a name="id69093">3.3 
        Starting a Gen_Fsm</a></h3>
    
    <p>In the example in the previous section, the gen_fsm is started by
      calling <span class="code">code_lock:start_link(Code)</span>:</p>
    <div class="example"><pre>
start_link(Code) -&gt;
    gen_fsm:start_link({local, code_lock}, code_lock, Code, []).</pre></div>
    <p><span class="code">start_link</span> calls the function <span class="code">gen_fsm:start_link/4</span>.
      This function spawns and links to a new process, a gen_fsm.</p>
    <ul>
      <li>
        <p>The first argument <span class="code">{local, code_lock}</span> specifies
          the name. In this case, the gen_fsm will be locally registered
          as <span class="code">code_lock</span>.</p>
        <p>If the name is omitted, the gen_fsm is not registered.
          Instead its pid must be used. The name could also be given as
          <span class="code">{global, Name}</span>, in which case the gen_fsm is registered
          using <span class="code">global:register_name/2</span>.</p>
      </li>
      <li>
        <p>The second argument, <span class="code">code_lock</span>, is the name of
          the callback module, that is the module where the callback
          functions are located.</p>
        <p>In this case, the interface functions (<span class="code">start_link</span> and
          <span class="code">button</span>) are located in the same module as the callback
          functions (<span class="code">init</span>, <span class="code">locked</span> and <span class="code">open</span>). This
          is normally good programming practice, to have the code
          corresponding to one process contained in one module.</p>
      </li>
      <li>
        <p>The third argument, <span class="code">Code</span>, is a term which is passed
          as-is to the callback function <span class="code">init</span>. Here, <span class="code">init</span>
          gets the correct code for the lock as indata.</p>
      </li>
      <li>
        <p>The fourth argument, [], is a list of options. See
          <span class="code">gen_fsm(3)</span> for available options.</p>
      </li>
    </ul>
    <p>If name registration succeeds, the new gen_fsm process calls
      the callback function <span class="code">code_lock:init(Code)</span>. This function
      is expected to return <span class="code">{ok, StateName, StateData}</span>, where
      <span class="code">StateName</span> is the name of the initial state of the gen_fsm.
      In this case <span class="code">locked</span>, assuming the door is locked to begin
      with. <span class="code">StateData</span> is the internal state of the gen_fsm. (For
      gen_fsms, the internal state is often referred to 'state data' to
      distinguish it from the state as in states of a state machine.)
      In this case, the state data is the button sequence so far (empty
      to begin with) and the correct code of the lock.</p>
    <div class="example"><pre>
init(Code) -&gt;
    {ok, locked, {[], Code}}.</pre></div>
    <p>Note that <span class="code">gen_fsm:start_link</span> is synchronous. It does not
      return until the gen_fsm has been initialized and is ready to
      receive notifications.</p>
    <p><span class="code">gen_fsm:start_link</span> must be used if the gen_fsm is part of
      a supervision tree, i.e. is started by a supervisor. There is
      another function <span class="code">gen_fsm:start</span> to start a stand-alone
      gen_fsm, i.e. a gen_fsm which is not part of a supervision tree.</p>
  

  <h3><a name="id69273">3.4 
        Notifying About Events</a></h3>
    
    <p>The function notifying the code lock about a button event is
      implemented using <span class="code">gen_fsm:send_event/2</span>:</p>
    <div class="example"><pre>
button(Digit) -&gt;
    gen_fsm:send_event(code_lock, {button, Digit}).</pre></div>
    <p><span class="code">code_lock</span> is the name of the gen_fsm and must agree with
      the name used to start it. <span class="code">{button, Digit}</span> is the actual
      event.</p>
    <p>The event is made into a message and sent to the gen_fsm. When
      the event is received, the gen_fsm calls
      <span class="code">StateName(Event, StateData)</span> which is expected to return a
      tuple <span class="code">{next_state, StateName1, StateData1}</span>.
      <span class="code">StateName</span> is the name of the current state and
      <span class="code">StateName1</span> is the name of the next state to go to.
      <span class="code">StateData1</span> is a new value for the state data of
      the gen_fsm.</p>
    <div class="example"><pre>
locked({button, Digit}, {SoFar, Code}) -&gt;
    case [Digit|SoFar] of
        Code -&gt;
            do_unlock(),
            {next_state, open, {[], Code}, 30000};
        Incomplete when length(Incomplete)&lt;length(Code) -&gt;
            {next_state, locked, {Incomplete, Code}};
        _Wrong -&gt;
            {next_state, locked, {[], Code}};
    end.

open(timeout, State) -&gt;
    do_lock(),
    {next_state, locked, State}.</pre></div>
    <p>If the door is locked and a button is pressed, the complete
      button sequence so far is compared with the correct code for
      the lock and, depending on the result, the door is either unlocked
      and the gen_fsm goes to state <span class="code">open</span>, or the door remains in
      state <span class="code">locked</span>.</p>
  

  <h3><a name="id69352">3.5 
        Timeouts</a></h3>
    
    <p>When a correct code has been givened, the door is unlocked and
      the following tuple is returned from <span class="code">locked/2</span>:</p>
    <div class="example"><pre>
{next_state, open, {[], Code}, 30000};</pre></div>
    <p>30000 is a timeout value in milliseconds. After 30000 ms, i.e.
      30 seconds, a timeout occurs. Then <span class="code">StateName(timeout, StateData)</span> is called. In this case, the timeout occurs when
      the door has been in state <span class="code">open</span> for 30 seconds. After that
      the door is locked again:</p>
    <div class="example"><pre>
open(timeout, State) -&gt;
    do_lock(),
    {next_state, locked, State}.</pre></div>
  

  <h3><a name="id69391">3.6 
        All State Events</a></h3>
    
    <p>Sometimes an event can arrive at any state of the gen_fsm.
      Instead of sending the message with <span class="code">gen_fsm:send_event/2</span>
      and writing one clause handling the event for each state function,
      the message can be sent with <span class="code">gen_fsm:send_all_state_event/2</span>
      and handled with <span class="code">Module:handle_event/3</span>:</p>
    <div class="example"><pre>
-module(code_lock).
...
-export([stop/0]).
...

stop() -&gt;
    gen_fsm:send_all_state_event(code_lock, stop).

...

handle_event(stop, _StateName, StateData) -&gt;
    {stop, normal, StateData}.</pre></div>
  

  <h3><a name="id69423">3.7 
        Stopping</a></h3>
    

    <h4>In a Supervision Tree</h4>
      
      <p>If the gen_fsm is part of a supervision tree, no stop function
        is needed. The gen_fsm will automatically be terminated by its
        supervisor. Exactly how this is done is defined by a
        <span class="bold_code"><a href="sup_princ.html#shutdown">shutdown strategy</a></span>
        set in the supervisor.</p>
      <p>If it is necessary to clean up before termination, the shutdown
        strategy must be a timeout value and the gen_fsm must be set to
        trap exit signals in the <span class="code">init</span> function. When ordered
        to shutdown, the gen_fsm will then call the callback function
        <span class="code">terminate(shutdown, StateName, StateData)</span>:</p>
      <div class="example"><pre>
init(Args) -&gt;
    ...,
    process_flag(trap_exit, true),
    ...,
    {ok, StateName, StateData}.

...

terminate(shutdown, StateName, StateData) -&gt;
    ..code for cleaning up here..
    ok.</pre></div>
    

    <h4>Stand-Alone Gen_Fsms</h4>
      
      <p>If the gen_fsm is not part of a supervision tree, a stop
        function may be useful, for example:</p>
      <div class="example"><pre>
...
-export([stop/0]).
...

stop() -&gt;
    gen_fsm:send_all_state_event(code_lock, stop).
...

handle_event(stop, _StateName, StateData) -&gt;
    {stop, normal, StateData}.

...

terminate(normal, _StateName, _StateData) -&gt;
    ok.</pre></div>
      <p>The callback function handling the <span class="code">stop</span> event returns a
        tuple <span class="code">{stop,normal,StateData1}</span>, where <span class="code">normal</span>
        specifies that it is a normal termination and <span class="code">StateData1</span>
        is a new value for the state data of the gen_fsm. This will
        cause the gen_fsm to call
        <span class="code">terminate(normal,StateName,StateData1)</span> and then
        terminate gracefully:</p>
    
  

  <h3><a name="id69514">3.8 
        Handling Other Messages</a></h3>
    
    <p>If the gen_fsm should be able to receive other messages than
      events, the callback function <span class="code">handle_info(Info, StateName, StateData)</span> must be implemented to handle them. Examples of
      other messages are exit messages, if the gen_fsm is linked to
      other processes (than the supervisor) and trapping exit signals.</p>
    <div class="example"><pre>
handle_info({'EXIT', Pid, Reason}, StateName, StateData) -&gt;
    ..code to handle exits here..
    {next_state, StateName1, StateData1}.</pre></div>
    <p>The code_change method also has to be implemented.</p>
    <div class="example"><pre>
code_change(OldVsn, StateName, StateData, Extra) -&gt;
    ..code to convert state (and more) during code change
    {ok, NextStateName, NewStateData}</pre></div>
  
</div>
<div class="footer">
<hr>
<p>Copyright © 1997-2012 Ericsson AB. All Rights Reserved.</p>
</div>
</div>
</div></body>
</html>