Sophie

Sophie

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

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 -- Sys and Proc_Lib</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="no" title="Gen_Fsm Behaviour" expanded="false">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="loadscrollpos" title="Sys and Proc_Lib" expanded="true">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>6 Sys and Proc_Lib</h1>
  
  <p>The module <span class="code">sys</span> contains functions for simple debugging of
    processes implemented using behaviours.</p>
  <p>There are also functions that, together with functions in
    the module <span class="code">proc_lib</span>, can be used to implement a
    <strong>special process</strong>, a process which comply to the OTP design
    principles without making use of a standard behaviour. They can
    also be used to implement user defined (non-standard) behaviours.</p>
  <p>Both <span class="code">sys</span> and <span class="code">proc_lib</span> belong to the STDLIB
    application.</p>

  <h3><a name="id72665">6.1 
        Simple Debugging</a></h3>
    
    <p>The module <span class="code">sys</span> contains some functions for simple debugging
      of processes implemented using behaviours. We use the
      <span class="code">code_lock</span> example from
      the <span class="bold_code"><a href="fsm.html#ex">gen_event</a></span> chapter to
      illustrate this:</p>
    <div class="example"><pre>
% <span class="bold_code">erl</span>
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]

Eshell V5.2.3.6  (abort with ^G)
1&gt; <span class="bold_code">code_lock:start_link([1,2,3,4]).</span>
{ok,&lt;0.32.0&gt;}
2&gt; <span class="bold_code">sys:statistics(code_lock, true).</span>
ok
3&gt; <span class="bold_code">sys:trace(code_lock, true).</span>
ok
4&gt; <span class="bold_code">code_lock:button(4).</span>
*DBG* code_lock got event {button,4} in state closed
ok
*DBG* code_lock switched to state closed
5&gt; <span class="bold_code">code_lock:button(3).</span>
*DBG* code_lock got event {button,3} in state closed
ok
*DBG* code_lock switched to state closed
6&gt; <span class="bold_code">code_lock:button(2).</span>
*DBG* code_lock got event {button,2} in state closed
ok
*DBG* code_lock switched to state closed
7&gt; <span class="bold_code">code_lock:button(1).</span>
*DBG* code_lock got event {button,1} in state closed
ok
OPEN DOOR
*DBG* code_lock switched to state open
*DBG* code_lock got event timeout in state open
CLOSE DOOR
*DBG* code_lock switched to state closed
8&gt; <span class="bold_code">sys:statistics(code_lock, get).</span> 
{ok,[{start_time,{{2003,6,12},{14,11,40}}},
     {current_time,{{2003,6,12},{14,12,14}}},
     {reductions,333},
     {messages_in,5},
     {messages_out,0}]}
9&gt; <span class="bold_code">sys:statistics(code_lock, false).</span>
ok
10&gt; <span class="bold_code">sys:trace(code_lock, false).</span>     
ok
11&gt; <span class="bold_code">sys:get_status(code_lock).</span>
{status,&lt;0.32.0&gt;,
        {module,gen_fsm},
        [[{'$ancestors',[&lt;0.30.0&gt;]},
          {'$initial_call',{gen,init_it,
                                [gen_fsm,&lt;0.30.0&gt;,&lt;0.30.0&gt;,
                                 {local,code_lock},
                                 code_lock,
                                 [1,2,3,4],
                                 []]}}],
         running,&lt;0.30.0&gt;,[],
         [code_lock,closed,{[],[1,2,3,4]},code_lock,infinity]]}</pre></div>
  

  <h3><a name="id72749">6.2 
        Special Processes</a></h3>
    
    <p>This section describes how to write a process which comply to
      the OTP design principles, without making use of a standard
      behaviour. Such a process should:</p>
    <ul>
      <li>be started in a way that makes the process fit into a
       supervision tree,</li>
      <li>support the <span class="code">sys</span> <span class="bold_code"><a href="#debug">debug facilities</a></span>, and</li>
      <li>take care of <span class="bold_code"><a href="#msg">system messages</a></span>.</li>
    </ul>
    <p>System messages are messages with special meaning, used in
      the supervision tree. Typical system messages are requests for
      trace output, and requests to suspend or resume process execution
      (used during release handling). Processes implemented using
      standard behaviours automatically understand these messages.</p>

    <h4>Example</h4>
      
      <p>The simple server from
        the <span class="bold_code"><a href="des_princ.html#ch1">Overview</a></span> chapter,
        implemented using <span class="code">sys</span> and <span class="code">proc_lib</span> so it fits into
        a supervision tree:</p>
      <a name="ex"></a>
      <div class="example"><pre>
-module(ch4).
-export([start_link/0]).
-export([alloc/0, free/1]).
-export([init/1]).
-export([system_continue/3, system_terminate/4,
         write_debug/3]).

start_link() -&gt;
    proc_lib:start_link(ch4, init, [self()]).

alloc() -&gt;
    ch4 ! {self(), alloc},
    receive
        {ch4, Res} -&gt;
            Res
    end.

free(Ch) -&gt;
    ch4 ! {free, Ch},
    ok.

init(Parent) -&gt;
    register(ch4, self()),
    Chs = channels(),
    Deb = sys:debug_options([]),
    proc_lib:init_ack(Parent, {ok, self()}),
    loop(Chs, Parent, Deb).

loop(Chs, Parent, Deb) -&gt;
    receive
        {From, alloc} -&gt;
            Deb2 = sys:handle_debug(Deb, {ch4, write_debug},
                                    ch4, {in, alloc, From}),
            {Ch, Chs2} = alloc(Chs),
            From ! {ch4, Ch},
            Deb3 = sys:handle_debug(Deb2, {ch4, write_debug},
                                    ch4, {out, {ch4, Ch}, From}),
            loop(Chs2, Parent, Deb3);
        {free, Ch} -&gt;
            Deb2 = sys:handle_debug(Deb, {ch4, write_debug},
                                    ch4, {in, {free, Ch}}),
            Chs2 = free(Ch, Chs),
            loop(Chs2, Parent, Deb2);

        {system, From, Request} -&gt;
            sys:handle_system_msg(Request, From, Parent,
                                  ch4, Deb, Chs)
    end.

system_continue(Parent, Deb, Chs) -&gt;
    loop(Chs, Parent, Deb).

system_terminate(Reason, Parent, Deb, Chs) -&gt;
    exit(Reason).

write_debug(Dev, Event, Name) -&gt;
    io:format(Dev, "~p event = ~p~n", [Name, Event]).</pre></div>
      <p>Example on how the simple debugging functions in <span class="code">sys</span> can
        be used for <span class="code">ch4</span> as well:</p>
      <div class="example"><pre>
% <span class="bold_code">erl</span>
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]

Eshell V5.2.3.6  (abort with ^G)
1&gt; <span class="bold_code">ch4:start_link().</span>
{ok,&lt;0.30.0&gt;}
2&gt; <span class="bold_code">sys:statistics(ch4, true).</span>
ok
3&gt; <span class="bold_code">sys:trace(ch4, true).</span>
ok
4&gt; <span class="bold_code">ch4:alloc().</span>
ch4 event = {in,alloc,&lt;0.25.0&gt;}
ch4 event = {out,{ch4,ch1},&lt;0.25.0&gt;}
ch1
5&gt; <span class="bold_code">ch4:free(ch1).</span>
ch4 event = {in,{free,ch1}}
ok
6&gt; <span class="bold_code">sys:statistics(ch4, get).</span>
{ok,[{start_time,{{2003,6,13},{9,47,5}}},
     {current_time,{{2003,6,13},{9,47,56}}},
     {reductions,109},
     {messages_in,2},
     {messages_out,1}]}
7&gt; <span class="bold_code">sys:statistics(ch4, false).</span>
ok
8&gt; <span class="bold_code">sys:trace(ch4, false).</span>
ok
9&gt; <span class="bold_code">sys:get_status(ch4).</span>
{status,&lt;0.30.0&gt;,
        {module,ch4},
        [[{'$ancestors',[&lt;0.25.0&gt;]},{'$initial_call',{ch4,init,[&lt;0.25.0&gt;]}}],
         running,&lt;0.25.0&gt;,[],
         [ch1,ch2,ch3]]}</pre></div>
    

    <h4>Starting the Process</h4>
      
      <p>A function in the <span class="code">proc_lib</span> module should be used to
        start the process. There are several possible functions, for
        example <span class="code">spawn_link/3,4</span> for asynchronous start and
        <span class="code">start_link/3,4,5</span> for synchronous start.</p>
      <p>A process started using one of these functions will store
        information that is needed for a process in a supervision tree,
        for example about the ancestors and initial call.</p>
      <p>Also, if the process terminates with another reason than
        <span class="code">normal</span> or <span class="code">shutdown</span>, a crash report (see SASL
        User's Guide) is generated.</p>
      <p>In the example, synchronous start is used. The process is
        started by calling <span class="code">ch4:start_link()</span>:</p>
      <div class="example"><pre>
start_link() -&gt;
    proc_lib:start_link(ch4, init, [self()]).</pre></div>
      <p><span class="code">ch4:start_link</span> calls the function
        <span class="code">proc_lib:start_link</span>. This function takes a module name,
        a function name and an argument list as arguments and spawns
        and links to a new process. The new process starts by executing
        the given function, in this case <span class="code">ch4:init(Pid)</span>, where
        <span class="code">Pid</span> is the pid (<span class="code">self()</span>) of the first process, that
        is the parent process.</p>
      <p>In <span class="code">init</span>, all initialization including name registration
        is done. The new process must also acknowledge that it has been
        started to the parent:</p>
      <div class="example"><pre>
init(Parent) -&gt;
    ...
    proc_lib:init_ack(Parent, {ok, self()}),
    loop(...).</pre></div>
      <p><span class="code">proc_lib:start_link</span> is synchronous and does not return
        until <span class="code">proc_lib:init_ack</span> has been called.</p>
    

    <h4>Debugging</h4>
      <a name="debug"></a>
      
      <p>To support the debug facilites in <span class="code">sys</span>, we need a
        <strong>debug structure</strong>, a term <span class="code">Deb</span> which is
        initialized using <span class="code">sys:debug_options/1</span>:</p>
      <div class="example"><pre>
init(Parent) -&gt;
    ...
    Deb = sys:debug_options([]),
    ...
    loop(Chs, Parent, Deb).</pre></div>
      <p><span class="code">sys:debug_options/1</span> takes a list of options as argument.
        Here the list is empty, which means no debugging is enabled
        initially. See <span class="code">sys(3)</span> for information about possible
        options.</p>
      <p>Then for each <strong>system event</strong> that we want to be logged
        or traced, the following function should be called.</p>
      <div class="example"><pre>
sys:handle_debug(Deb, Func, Info, Event) =&gt; Deb1</pre></div>
      <ul>
        <li>
          <p><span class="code">Deb</span> is the debug structure.</p>
        </li>
        <li>
          <p><span class="code">Func</span> is a tuple <span class="code">{Module, Name}</span> (or a fun) and
            should specify a (user defined) function used to format
            trace output. For each system event, the format function is
            called as <span class="code">Module:Name(Dev, Event, Info)</span>, where:</p>
          <ul>
            <li>
              <p><span class="code">Dev</span> is the IO device to which the output should
                be printed. See <span class="code">io(3)</span>.</p>
            </li>
            <li>
              <p><span class="code">Event</span> and <span class="code">Info</span> are passed as-is from
                <span class="code">handle_debug</span>.</p>
            </li>
          </ul>
        </li>
        <li>
          <p><span class="code">Info</span> is used to pass additional information to
            <span class="code">Func</span>, it can be any term and is passed as-is.</p>
        </li>
        <li>
          <p><span class="code">Event</span> is the system event. It is up to the user to
            define what a system event is and how it should be
            represented, but typically at least incoming and outgoing
            messages are considered system events and represented by
            the tuples <span class="code">{in,Msg[,From]}</span> and <span class="code">{out,Msg,To}</span>,
            respectively.</p>
        </li>
      </ul>
      <p><span class="code">handle_debug</span> returns an updated debug structure
        <span class="code">Deb1</span>.</p>
      <p>In the example, <span class="code">handle_debug</span> is called for each incoming
        and outgoing message. The format function <span class="code">Func</span> is
        the function <span class="code">ch4:write_debug/3</span> which prints the message
        using <span class="code">io:format/3</span>.</p>
      <div class="example"><pre>
loop(Chs, Parent, Deb) -&gt;
    receive
        {From, alloc} -&gt;
            Deb2 = sys:handle_debug(Deb, {ch4, write_debug},
                                    ch4, {in, alloc, From}),
            {Ch, Chs2} = alloc(Chs),
            From ! {ch4, Ch},
            Deb3 = sys:handle_debug(Deb2, {ch4, write_debug},
                                    ch4, {out, {ch4, Ch}, From}),
            loop(Chs2, Parent, Deb3);
        {free, Ch} -&gt;
            Deb2 = sys:handle_debug(Deb, {ch4, write_debug},
                                    ch4, {in, {free, Ch}}),
            Chs2 = free(Ch, Chs),
            loop(Chs2, Parent, Deb2);
        ...
    end.

write_debug(Dev, Event, Name) -&gt;
    io:format(Dev, "~p event = ~p~n", [Name, Event]).</pre></div>
    

    <h4>Handling System Messages</h4>
      <a name="msg"></a>
      
      <p><strong>System messages</strong> are received as:</p>
      <div class="example"><pre>
{system, From, Request}</pre></div>
      <p>The content and meaning of these messages do not need to be
        interpreted by the process. Instead the following function
        should be called:</p>
      <div class="example"><pre>
sys:handle_system_msg(Request, From, Parent, Module, Deb, State)</pre></div>
      <p>This function does not return. It will handle the system
        message and then call:</p>
      <div class="example"><pre>
Module:system_continue(Parent, Deb, State)</pre></div>
      <p>if process execution should continue, or:</p>
      <div class="example"><pre>
Module:system_terminate(Reason, Parent, Deb, State)</pre></div>
      <p>if the process should terminate. Note that a process in a
        supervision tree is expected to terminate with the same reason as
        its parent.</p>
      <ul>
        <li>
<span class="code">Request</span> and <span class="code">From</span> should be passed as-is from
         the system message to the call to <span class="code">handle_system_msg</span>.</li>
        <li>
<span class="code">Parent</span> is the pid of the parent.</li>
        <li>
<span class="code">Module</span> is the name of the module.</li>
        <li>
<span class="code">Deb</span> is the debug structure.</li>
        <li>
<span class="code">State</span> is a term describing the internal state and
         is passed to <span class="code">system_continue</span>/<span class="code">system_terminate</span>.</li>
      </ul>
      <p>In the example:</p>
      <div class="example"><pre>
loop(Chs, Parent, Deb) -&gt;
    receive
        ...

        {system, From, Request} -&gt;
            sys:handle_system_msg(Request, From, Parent,
                                  ch4, Deb, Chs)
    end.

system_continue(Parent, Deb, Chs) -&gt;
    loop(Chs, Parent, Deb).

system_terminate(Reason, Parent, Deb, Chs) -&gt;
    exit(Reason).</pre></div>
      <p>If the special process is set to trap exits, note that if
        the parent process terminates, the expected behavior is to
        terminate with the same reason:</p>
      <div class="example"><pre>
init(...) -&gt;
    ...,
    process_flag(trap_exit, true),
    ...,
    loop(...).

loop(...) -&gt;
    receive
        ...

        {'EXIT', Parent, Reason} -&gt;
            ..maybe some cleaning up here..
            exit(Reason);
        ...
    end.</pre></div>
    
  

  <h3><a name="id73359">6.3 
        User-Defined Behaviours</a></h3>
    
    <p>To implement a user-defined behaviour, write code similar to
      code for a special process but calling functions in a callback
      module for handling specific tasks.</p>
    <p>If it is desired that the compiler should warn for missing callback
    functions, as it does for the OTP behaviours, add callback attributes in the
    behaviour module to describe the expected callbacks:</p>
    <div class="example"><pre>
-callback Name1(Arg1_1, Arg1_2, ..., Arg1_N1) -&gt; Res1.
-callback Name2(Arg2_1, Arg2_2, ..., Arg2_N2) -&gt; Res2.
...
-callback NameM(ArgM_1, ArgM_2, ..., ArgM_NM) -&gt; ResM.</pre></div>
    <p>where <span class="code">NameX</span> are the names of the expected callbacks and
    <span class="code">ArgX_Y</span>, <span class="code">ResX</span> are types as they are described in Specifications
    for functions in <span class="bold_code"><a href="../reference_manual/typespec.html">Types and
    Function Specifications</a></span>. The whole syntax of spec attributes is
    supported by callback attributes.</p>
    <p>Alternatively you may directly implement and export the function:</p>
    <div class="example"><pre>
behaviour_info(callbacks) -&gt;
    [{Name1,Arity1},...,{NameN,ArityN}].</pre></div>
    <p>where each <span class="code">{Name,Arity}</span> specifies the name and arity of a callback
    function. This function is otherwise automatically generated by the compiler
    using the callback attributes.</p>
    <p>When the compiler encounters the module attribute
    <span class="code">-behaviour(Behaviour).</span> in a module <span class="code">Mod</span>, it will call
    <span class="code">Behaviour:behaviour_info(callbacks)</span> and compare the result with the
    set of functions actually exported from <span class="code">Mod</span>, and issue a warning if
    any callback function is missing.</p>
    <p>Example:</p>
    <div class="example"><pre>
%% User-defined behaviour module
-module(simple_server).
-export([start_link/2,...]).

-callback init(State :: term()) -&gt; 'ok'.
-callback handle_req(Req :: term(), State :: term()) -&gt; {'ok', Reply :: term()}.
-callback terminate() -&gt; 'ok'.

%% Alternatively you may define:
%%
%% -export([behaviour_info/1]).
%% behaviour_info(callbacks) -&gt;
%%     [{init,1},
%%      {handle_req,2},
%%      {terminate,0}].

start_link(Name, Module) -&gt;
    proc_lib:start_link(?MODULE, init, [self(), Name, Module]).

init(Parent, Name, Module) -&gt;
    register(Name, self()),
    ...,
    Dbg = sys:debug_options([]),
    proc_lib:init_ack(Parent, {ok, self()}),
    loop(Parent, Module, Deb, ...).

...</pre></div>
    <p>In a callback module:</p>
    <div class="example"><pre>
-module(db).
-behaviour(simple_server).

-export([init/0, handle_req/2, terminate/0]).

...</pre></div>
  
</div>
<div class="footer">
<hr>
<p>Copyright © 1997-2012 Ericsson AB. All Rights Reserved.</p>
</div>
</div>
</div></body>
</html>