Просмотр исходного кода

added documentation

git-svn-id: http://svn.ulf.wiger.net/gproc/branches/experimental-0906/gproc@34 f3948e33-8234-0410-8a80-a07eae3b6c4d
uwiger 15 лет назад
Родитель
Сommit
ab7ea18fd7
16 измененных файлов с 848 добавлено и 226 удалено
  1. 3 0
      doc/edoc-info
  2. BIN
      doc/erlang.png
  3. 176 153
      doc/gproc.html
  4. 43 0
      doc/gproc_app.html
  5. 154 0
      doc/gproc_dist.html
  6. 36 0
      doc/gproc_init.html
  7. 23 0
      doc/gproc_lib.html
  8. 37 0
      doc/gproc_sup.html
  9. 17 0
      doc/index.html
  10. 17 0
      doc/modules-frame.html
  11. 37 0
      doc/overview-summary.html
  12. 26 0
      doc/overview.edoc
  13. 11 0
      doc/packages-frame.html
  14. 55 0
      doc/stylesheet.css
  15. 10 1
      src/Makefile
  16. 203 72
      src/gproc.erl

+ 3 - 0
doc/edoc-info

@@ -0,0 +1,3 @@
+{application,gproc}.
+{packages,[]}.
+{modules,[gproc,gproc_app,gproc_dist,gproc_init,gproc_lib,gproc_sup]}.

BIN
doc/erlang.png


+ 176 - 153
doc/gproc.html

@@ -9,213 +9,228 @@
 <hr>
 
 <h1>Module gproc</h1>
-<ul class="index"><li><a href="#description">Description</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>Extended process registry.
+<ul class="index"><li><a href="#description">Description</a></li><li><a href="#types">Data Types</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>Extended process registry.
 
-<p><b>Behaviours:</b> <a href="gen_leader.html"><tt>gen_leader</tt></a>.</p>
+<p><b>Behaviours:</b> <a href="gen_server.html"><tt>gen_server</tt></a>.</p>
 <p><b>Authors:</b> Ulf Wiger (<a href="mailto:ulf.wiger@ericsson.com"><tt>ulf.wiger@ericsson.com</tt></a>).</p>
 
 <h2><a name="description">Description</a></h2>Extended process registry
   <p>This module implements an extended process registry</p>
   <p>For a detailed description, see gproc/doc/erlang07-wiger.pdf.</p>
-<h2><a name="index">Function Index</a></h2>
-<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#code_change-4">code_change/4</a></td><td></td></tr>
-<tr><td valign="top"><a href="#elected-2">elected/2</a></td><td></td></tr>
-<tr><td valign="top"><a href="#first-1">first/1</a></td><td></td></tr>
-<tr><td valign="top"><a href="#from_leader-3">from_leader/3</a></td><td></td></tr>
-<tr><td valign="top"><a href="#get_value-1">get_value/1</a></td><td>Read the value stored with a key registered to the current process.</td></tr>
-<tr><td valign="top"><a href="#go_global-0">go_global/0</a></td><td></td></tr>
-<tr><td valign="top"><a href="#go_global-1">go_global/1</a></td><td></td></tr>
-<tr><td valign="top"><a href="#handle_DOWN-3">handle_DOWN/3</a></td><td></td></tr>
-<tr><td valign="top"><a href="#handle_call-3">handle_call/3</a></td><td></td></tr>
-<tr><td valign="top"><a href="#handle_cast-2">handle_cast/2</a></td><td></td></tr>
-<tr><td valign="top"><a href="#handle_info-2">handle_info/2</a></td><td></td></tr>
-<tr><td valign="top"><a href="#handle_leader_call-4">handle_leader_call/4</a></td><td></td></tr>
-<tr><td valign="top"><a href="#handle_leader_cast-3">handle_leader_cast/3</a></td><td></td></tr>
-<tr><td valign="top"><a href="#info-1">info/1</a></td><td></td></tr>
-<tr><td valign="top"><a href="#info-2">info/2</a></td><td></td></tr>
-<tr><td valign="top"><a href="#init-1">init/1</a></td><td></td></tr>
-<tr><td valign="top"><a href="#last-1">last/1</a></td><td></td></tr>
-<tr><td valign="top"><a href="#mreg-3">mreg/3</a></td><td></td></tr>
-<tr><td valign="top"><a href="#next-2">next/2</a></td><td></td></tr>
-<tr><td valign="top"><a href="#prev-2">prev/2</a></td><td></td></tr>
-<tr><td valign="top"><a href="#reg-2">reg/2</a></td><td>
-      Class = n  - unique name
-            | p  - non-unique property
-            | c  - counter
-            | a  - aggregated counter
-      Scope = l | g (global or local).</td></tr>
-<tr><td valign="top"><a href="#select-1">select/1</a></td><td></td></tr>
-<tr><td valign="top"><a href="#select-2">select/2</a></td><td></td></tr>
-<tr><td valign="top"><a href="#send-2">send/2</a></td><td></td></tr>
-<tr><td valign="top"><a href="#set_value-2">set_value/2</a></td><td></td></tr>
-<tr><td valign="top"><a href="#start_link-0">start_link/0</a></td><td></td></tr>
-<tr><td valign="top"><a href="#start_link-1">start_link/1</a></td><td></td></tr>
-<tr><td valign="top"><a href="#start_local-0">start_local/0</a></td><td></td></tr>
-<tr><td valign="top"><a href="#surrendered-3">surrendered/3</a></td><td></td></tr>
-<tr><td valign="top"><a href="#table-1">table/1</a></td><td></td></tr>
-<tr><td valign="top"><a href="#table-2">table/2</a></td><td></td></tr>
-<tr><td valign="top"><a href="#terminate-2">terminate/2</a></td><td></td></tr>
-<tr><td valign="top"><a href="#unreg-1">unreg/1</a></td><td></td></tr>
-<tr><td valign="top"><a href="#update_counter-2">update_counter/2</a></td><td></td></tr>
-</table>
+ 
+<h2><a name="types">Data Types</a></h2>
 
-<h2><a name="functions">Function Details</a></h2>
+<h3 class="typedecl"><a name="type-context">context()</a></h3>
+<p><tt>context() = {<a href="#type-scope">scope()</a>, <a href="#type-type">type()</a>} | <a href="#type-type">type()</a></tt></p>
+<p>Local scope is the default</p>
 
-<h3 class="function"><a name="code_change-4">code_change/4</a></h3>
-<div class="spec">
-<p><tt>code_change(FromVsn, S, Extra, E) -&gt; any()</tt></p>
-</div>
+<h3 class="typedecl"><a name="type-headpat">headpat()</a></h3>
+<p><tt>headpat() = {<a href="#type-keypat">keypat()</a>, <a href="#type-pidpat">pidpat()</a>, ValPat}</tt></p>
 
-<h3 class="function"><a name="elected-2">elected/2</a></h3>
-<div class="spec">
-<p><tt>elected(S, E) -&gt; any()</tt></p>
-</div>
 
-<h3 class="function"><a name="first-1">first/1</a></h3>
-<div class="spec">
-<p><tt>first(Scope) -&gt; any()</tt></p>
-</div>
+<h3 class="typedecl"><a name="type-key">key()</a></h3>
+<p><tt>key() = {<a href="#type-type">type()</a>, <a href="#type-scope">scope()</a>, any()}</tt></p>
 
-<h3 class="function"><a name="from_leader-3">from_leader/3</a></h3>
-<div class="spec">
-<p><tt>from_leader(Ops, S, E) -&gt; any()</tt></p>
-</div>
 
-<h3 class="function"><a name="get_value-1">get_value/1</a></h3>
-<div class="spec">
-<p><tt>get_value(Key) -&gt; Value</tt></p>
-</div><p>Read the value stored with a key registered to the current process.
-  </p>
+<h3 class="typedecl"><a name="type-keypat">keypat()</a></h3>
+<p><tt>keypat() = {<a href="#type-sel_type">sel_type()</a> | <a href="#type-sel_var">sel_var()</a>, l | g | <a href="#type-sel_var">sel_var()</a>, any()}</tt></p>
 
-<h3 class="function"><a name="go_global-0">go_global/0</a></h3>
-<div class="spec">
-<p><tt>go_global() -&gt; any()</tt></p>
-</div>
 
-<h3 class="function"><a name="go_global-1">go_global/1</a></h3>
-<div class="spec">
-<p><tt>go_global(Nodes) -&gt; any()</tt></p>
-</div>
+<h3 class="typedecl"><a name="type-pidpat">pidpat()</a></h3>
+<p><tt>pidpat() = pid() | <a href="#type-sel_var">sel_var()</a></tt></p>
+<p>sel_var() = DollarVar | '_'.</p>
 
-<h3 class="function"><a name="handle_DOWN-3">handle_DOWN/3</a></h3>
-<div class="spec">
-<p><tt>handle_DOWN(Node, S, E) -&gt; any()</tt></p>
-</div>
+<h3 class="typedecl"><a name="type-scope">scope()</a></h3>
+<p><tt>scope() = l | g</tt></p>
+<p>l = local registration; g = global registration</p>
 
-<h3 class="function"><a name="handle_call-3">handle_call/3</a></h3>
-<div class="spec">
-<p><tt>handle_call(X1, X2, S) -&gt; any()</tt></p>
-</div>
+<h3 class="typedecl"><a name="type-sel_pattern">sel_pattern()</a></h3>
+<p><tt>sel_pattern() = [{<a href="#type-headpat">headpat()</a>, Guards, Prod}]</tt></p>
 
-<h3 class="function"><a name="handle_cast-2">handle_cast/2</a></h3>
-<div class="spec">
-<p><tt>handle_cast(X1, S) -&gt; any()</tt></p>
-</div>
 
-<h3 class="function"><a name="handle_info-2">handle_info/2</a></h3>
-<div class="spec">
-<p><tt>handle_info(X1, S) -&gt; any()</tt></p>
-</div>
+<h3 class="typedecl"><a name="type-sel_type">sel_type()</a></h3>
+<p><tt>sel_type() = n | p | c | a | names | props | counters | aggr_counters</tt></p>
+
+
+<h3 class="typedecl"><a name="type-type">type()</a></h3>
+<p><tt>type() = n | p | c | a</tt></p>
+<p>n = name; p = property; c = counter;
+                                 a = aggregate_counter</p>
+
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#first-1">first/1</a></td><td>Behaves as ets:first(Tab) for a given type of registration object.</td></tr>
+<tr><td valign="top"><a href="#get_value-1">get_value/1</a></td><td>Read the value stored with a key registered to the current process.</td></tr>
+<tr><td valign="top"><a href="#info-1">info/1</a></td><td>Similar to <code>process_info(Pid)</code> but with additional gproc info.</td></tr>
+<tr><td valign="top"><a href="#info-2">info/2</a></td><td>Similar to process_info(Pid, Item), but with additional gproc info.</td></tr>
+<tr><td valign="top"><a href="#last-1">last/1</a></td><td>Behaves as ets:last(Tab) for a given type of registration object.</td></tr>
+<tr><td valign="top"><a href="#lookup_pid-1">lookup_pid/1</a></td><td>Lookup the Pid stored with a key.</td></tr>
+<tr><td valign="top"><a href="#lookup_pids-1">lookup_pids/1</a></td><td>Returns a list of pids with the published key Key.</td></tr>
+<tr><td valign="top"><a href="#mreg-3">mreg/3</a></td><td>Register multiple {Key,Value} pairs of a given type and scope.</td></tr>
+<tr><td valign="top"><a href="#next-2">next/2</a></td><td>Behaves as ets:next(Tab,Key) for a given type of registration object.</td></tr>
+<tr><td valign="top"><a href="#prev-2">prev/2</a></td><td>Behaves as ets:prev(Tab,Key) for a given type of registration object.</td></tr>
+<tr><td valign="top"><a href="#reg-1">reg/1</a></td><td>Equivalent to <a href="#reg-2"><tt>reg(Key, undefined)</tt></a>.
+</td></tr>
+<tr><td valign="top"><a href="#reg-2">reg/2</a></td><td>Register a name or property for the current process.</td></tr>
+<tr><td valign="top"><a href="#select-1">select/1</a></td><td>Equivalent to <a href="#select-2"><tt>select(all, Pat)</tt></a>.
+</td></tr>
+<tr><td valign="top"><a href="#select-2">select/2</a></td><td>Perform a select operation on the process registry.</td></tr>
+<tr><td valign="top"><a href="#select-3">select/3</a></td><td>Like <a href="#select-2"><code>select/2</code></a> but returns Limit objects at a time.</td></tr>
+<tr><td valign="top"><a href="#send-2">send/2</a></td><td>Sends a message to the process, or processes, corresponding to Key.</td></tr>
+<tr><td valign="top"><a href="#set_value-2">set_value/2</a></td><td>Sets the value of the registeration entry given by Key.</td></tr>
+<tr><td valign="top"><a href="#start_link-0">start_link/0</a></td><td></td></tr>
+<tr><td valign="top"><a href="#table-1">table/1</a></td><td></td></tr>
+<tr><td valign="top"><a href="#table-2">table/2</a></td><td></td></tr>
+<tr><td valign="top"><a href="#unreg-1">unreg/1</a></td><td>Unregister a name or property.</td></tr>
+<tr><td valign="top"><a href="#update_counter-2">update_counter/2</a></td><td>Updates the counter registered as Key for the current process.</td></tr>
+<tr><td valign="top"><a href="#where-1">where/1</a></td><td>Returns the pid registered as Key.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
 
-<h3 class="function"><a name="handle_leader_call-4">handle_leader_call/4</a></h3>
+<h3 class="function"><a name="first-1">first/1</a></h3>
 <div class="spec">
-<p><tt>handle_leader_call(X1, From, State, E) -&gt; any()</tt></p>
-</div>
+<p><tt>first(Type::<a href="#type-type">type()</a>) -&gt; <a href="#type-key">key()</a> | '$end_of_table'</tt></p>
+</div><p><p>Behaves as ets:first(Tab) for a given type of registration object.</p>
+ 
+  See <a href="http://www.erlang.org/doc/man/ets.html#first-1" target="_top"><tt>http://www.erlang.org/doc/man/ets.html#first-1</tt></a>.
+   The registry behaves as an ordered_set table.</p>
 
-<h3 class="function"><a name="handle_leader_cast-3">handle_leader_cast/3</a></h3>
+<h3 class="function"><a name="get_value-1">get_value/1</a></h3>
 <div class="spec">
-<p><tt>handle_leader_cast(X1, State, E) -&gt; any()</tt></p>
-</div>
+<p><tt>get_value(Key) -&gt; Value</tt></p>
+</div><p><p>Read the value stored with a key registered to the current process.</p>
+ 
+  If no such key is registered to the current process, this function exits.</p>
 
 <h3 class="function"><a name="info-1">info/1</a></h3>
 <div class="spec">
-<p><tt>info(Pid) -&gt; any()</tt></p>
-</div>
+<p><tt>info(Pid::pid()) -&gt; ProcessInfo</tt>
+<ul class="definitions"><li><tt>ProcessInfo = [{gproc, [{Key, Value}]} | ProcessInfo]</tt></li>
+</ul></p>
+</div><p><p>Similar to <code>process_info(Pid)</code> but with additional gproc info.</p>
+ 
+  Returns the same information as process_info(Pid), but with the
+  addition of a <code>gproc</code> information item, containing the <code>{Key,Value}</code>
+  pairs registered to the process.</p>
 
 <h3 class="function"><a name="info-2">info/2</a></h3>
 <div class="spec">
-<p><tt>info(Pid, I) -&gt; any()</tt></p>
-</div>
+<p><tt>info(Pid::pid(), Item::atom()) -&gt; {Item, Info}</tt></p>
+</div><p><p>Similar to process_info(Pid, Item), but with additional gproc info.</p>
+ 
+  For <code>Item = gproc</code>, this function returns a list of <code>{Key, Value}</code> pairs
+  registered to the process Pid. For other values of Item, it returns the
+  same as <a href="http://www.erlang.org/doc/man/erlang.html#process_info-2" target="_top"><tt>http://www.erlang.org/doc/man/erlang.html#process_info-2</tt></a>.</p>
 
-<h3 class="function"><a name="init-1">init/1</a></h3>
+<h3 class="function"><a name="last-1">last/1</a></h3>
 <div class="spec">
-<p><tt>init(X1) -&gt; any()</tt></p>
-</div>
+<p><tt>last(Context::<a href="#type-context">context()</a>) -&gt; <a href="#type-key">key()</a> | '$end_of_table'</tt></p>
+</div><p><p>Behaves as ets:last(Tab) for a given type of registration object.</p>
+ 
+  See <a href="http://www.erlang.org/doc/man/ets.html#last-1" target="_top"><tt>http://www.erlang.org/doc/man/ets.html#last-1</tt></a>.
+  The registry behaves as an ordered_set table.</p>
 
-<h3 class="function"><a name="last-1">last/1</a></h3>
+<h3 class="function"><a name="lookup_pid-1">lookup_pid/1</a></h3>
 <div class="spec">
-<p><tt>last(Scope) -&gt; any()</tt></p>
-</div>
+<p><tt>lookup_pid(Key) -&gt; Pid</tt></p>
+</div><p>Lookup the Pid stored with a key.
+ </p>
+
+<h3 class="function"><a name="lookup_pids-1">lookup_pids/1</a></h3>
+<div class="spec">
+<p><tt>lookup_pids(Key::<a href="#type-key">key()</a>) -&gt; [pid()]</tt></p>
+</div><p><p>Returns a list of pids with the published key Key</p>
+ 
+  If the type of registration entry is either name or aggregated counter,
+  this function will return either an empty list, or a list of one pid.
+  For non-unique types, the return value can be a list of any length.</p>
 
 <h3 class="function"><a name="mreg-3">mreg/3</a></h3>
 <div class="spec">
-<p><tt>mreg(T, X2, KVL) -&gt; any()</tt></p>
-</div>
+<p><tt>mreg(T::<a href="#type-type">type()</a>, X2::<a href="#type-scope">scope()</a>, KVL::[{Key::any(), Value::any()}]) -&gt; true</tt></p>
+</div><p><p>Register multiple {Key,Value} pairs of a given type and scope.</p>
+ 
+  This function is more efficient than calling <a href="#reg-2"><code>reg/2</code></a> repeatedly.</p>
 
 <h3 class="function"><a name="next-2">next/2</a></h3>
 <div class="spec">
-<p><tt>next(Scope, K) -&gt; any()</tt></p>
-</div>
+<p><tt>next(Context::<a href="#type-context">context()</a>, Key::<a href="#type-key">key()</a>) -&gt; <a href="#type-key">key()</a> | '$end_of_table'</tt></p>
+</div><p><p>Behaves as ets:next(Tab,Key) for a given type of registration object.</p>
+ 
+  See <a href="http://www.erlang.org/doc/man/ets.html#next-2" target="_top"><tt>http://www.erlang.org/doc/man/ets.html#next-2</tt></a>.
+  The registry behaves as an ordered_set table.</p>
 
 <h3 class="function"><a name="prev-2">prev/2</a></h3>
 <div class="spec">
-<p><tt>prev(Scope, K) -&gt; any()</tt></p>
-</div>
+<p><tt>prev(Context::<a href="#type-context">context()</a>, Key::<a href="#type-key">key()</a>) -&gt; <a href="#type-key">key()</a> | '$end_of_table'</tt></p>
+</div><p><p>Behaves as ets:prev(Tab,Key) for a given type of registration object.</p>
+ 
+  See <a href="http://www.erlang.org/doc/man/ets.html#prev-2" target="_top"><tt>http://www.erlang.org/doc/man/ets.html#prev-2</tt></a>.
+  The registry behaves as an ordered_set table.</p>
+
+<h3 class="function"><a name="reg-1">reg/1</a></h3>
+<div class="spec">
+<p><tt>reg(Key::<a href="#type-key">key()</a>) -&gt; true</tt></p>
+</div><p>Equivalent to <a href="#reg-2"><tt>reg(Key, undefined)</tt></a>.</p>
+
 
 <h3 class="function"><a name="reg-2">reg/2</a></h3>
 <div class="spec">
-<p><tt>reg(Key, Value) -&gt; any()</tt></p>
-</div><p>
-      Class = n  - unique name
-            | p  - non-unique property
-            | c  - counter
-            | a  - aggregated counter
-      Scope = l | g (global or local)
-  </p>
+<p><tt>reg(Key::<a href="#type-key">key()</a>, Value) -&gt; true</tt></p>
+</div><p><p>Register a name or property for the current process</p>
+ 
+ </p>
 
 <h3 class="function"><a name="select-1">select/1</a></h3>
 <div class="spec">
-<p><tt>select(Pat) -&gt; any()</tt></p>
-</div>
+<p><tt>select(Pat::<a href="#type-select_pattern">select_pattern()</a>) -&gt; list(<a href="#type-sel_object">sel_object()</a>)</tt></p>
+</div><p>Equivalent to <a href="#select-2"><tt>select(all, Pat)</tt></a>.</p>
+
 
 <h3 class="function"><a name="select-2">select/2</a></h3>
 <div class="spec">
-<p><tt>select(Scope, Pat) -&gt; any()</tt></p>
-</div>
+<p><tt>select(Type::<a href="#type-sel_type">sel_type()</a>, Pat::<a href="#type-sel_pattern">sel_pattern()</a>) -&gt; [{Key, Pid, Value}]</tt></p>
+</div><p><p>Perform a select operation on the process registry.</p>
+ 
+  The physical representation in the registry may differ from the above,
+  but the select patterns are transformed appropriately.</p>
+
+<h3 class="function"><a name="select-3">select/3</a></h3>
+<div class="spec">
+<p><tt>select(Type::<a href="#type-sel_type">sel_type()</a>, Pat::<a href="#type-sel_patten">sel_patten()</a>, Limit::integer()) -&gt; [{Key, Pid, Value}]</tt></p>
+</div><p><p>Like <a href="#select-2"><code>select/2</code></a> but returns Limit objects at a time.</p>
+ 
+  See <a href="http://www.erlang.org/doc/man/ets.html#select-3" target="_top"><tt>http://www.erlang.org/doc/man/ets.html#select-3</tt></a>.</p>
 
 <h3 class="function"><a name="send-2">send/2</a></h3>
 <div class="spec">
-<p><tt>send(Key, Msg) -&gt; any()</tt></p>
-</div>
+<p><tt>send(Key::<a href="#type-key">key()</a>, Msg::any()) -&gt; Msg</tt></p>
+</div><p><p>Sends a message to the process, or processes, corresponding to Key.</p>
+ 
+  If Key belongs to a unique object (name or aggregated counter), this
+  function will send a message to the corresponding process, or fail if there
+  is no such process. If Key is for a non-unique object type (counter or
+  property), Msg will be send to all processes that have such an object.</p>
 
 <h3 class="function"><a name="set_value-2">set_value/2</a></h3>
 <div class="spec">
-<p><tt>set_value(Key, Value) -&gt; any()</tt></p>
-</div>
+<p><tt>set_value(Key::<a href="#type-key">key()</a>, Value) -&gt; true</tt></p>
+</div><p><p>Sets the value of the registeration entry given by Key</p>
+ 
+  <p>Key is assumed to exist and belong to the calling process.  
+If it doesn't, this function will exit.</p>
+ 
+  Value can be any term, unless the object is a counter, in which case
+  it must be an integer.</p>
 
 <h3 class="function"><a name="start_link-0">start_link/0</a></h3>
 <div class="spec">
 <p><tt>start_link() -&gt; any()</tt></p>
 </div>
 
-<h3 class="function"><a name="start_link-1">start_link/1</a></h3>
-<div class="spec">
-<p><tt>start_link(Nodes) -&gt; any()</tt></p>
-</div>
-
-<h3 class="function"><a name="start_local-0">start_local/0</a></h3>
-<div class="spec">
-<p><tt>start_local() -&gt; any()</tt></p>
-</div>
-
-<h3 class="function"><a name="surrendered-3">surrendered/3</a></h3>
-<div class="spec">
-<p><tt>surrendered(S, X2, E) -&gt; any()</tt></p>
-</div>
-
 <h3 class="function"><a name="table-1">table/1</a></h3>
 <div class="spec">
-<p><tt>table(Scope) -&gt; any()</tt></p>
+<p><tt>table(Type) -&gt; any()</tt></p>
 </div>
 
 <h3 class="function"><a name="table-2">table/2</a></h3>
@@ -223,23 +238,31 @@
 <p><tt>table(T, Opts) -&gt; any()</tt></p>
 </div>
 
-<h3 class="function"><a name="terminate-2">terminate/2</a></h3>
-<div class="spec">
-<p><tt>terminate(Reason, S) -&gt; any()</tt></p>
-</div>
-
 <h3 class="function"><a name="unreg-1">unreg/1</a></h3>
 <div class="spec">
-<p><tt>unreg(Key) -&gt; any()</tt></p>
-</div>
+<p><tt>unreg(Key::<a href="#type-key">key()</a>) -&gt; true</tt></p>
+</div><p>Unregister a name or property.</p>
 
 <h3 class="function"><a name="update_counter-2">update_counter/2</a></h3>
 <div class="spec">
-<p><tt>update_counter(Key, Incr) -&gt; any()</tt></p>
-</div>
+<p><tt>update_counter(Key::<a href="#type-key">key()</a>, Incr::integer()) -&gt; integer()</tt></p>
+</div><p><p>Updates the counter registered as Key for the current process.</p>
+ 
+  This function works like ets:update_counter/3
+  (see <a href="http://www.erlang.org/doc/man/ets.html#update_counter-3" target="_top"><tt>http://www.erlang.org/doc/man/ets.html#update_counter-3</tt></a>), but
+  will fail if the type of object referred to by Key is not a counter.</p>
+
+<h3 class="function"><a name="where-1">where/1</a></h3>
+<div class="spec">
+<p><tt>where(Key::<a href="#type-key">key()</a>) -&gt; pid()</tt></p>
+</div><p><p>Returns the pid registered as Key</p>
+ 
+  The type of registration entry must be either name or aggregated counter.
+  Otherwise this function will exit. Use <a href="#lookup_pids-1"><code>lookup_pids/1</code></a> in these
+  cases.</p>
 <hr>
 
 <div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
-<p><i>Generated by EDoc, Sep 4 2008, 11:29:40.</i></p>
+<p><i>Generated by EDoc, Sep 20 2009, 09:15:40.</i></p>
 </body>
 </html>

+ 43 - 0
doc/gproc_app.html

@@ -0,0 +1,43 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Module gproc_app</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module gproc_app</h1>
+<ul class="index"><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>
+
+<p><b>Behaviours:</b> <a href="application.html"><tt>application</tt></a>.</p>
+
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#start-0">start/0</a></td><td></td></tr>
+<tr><td valign="top"><a href="#start-2">start/2</a></td><td></td></tr>
+<tr><td valign="top"><a href="#stop-1">stop/1</a></td><td></td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="start-0">start/0</a></h3>
+<div class="spec">
+<p><tt>start() -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="start-2">start/2</a></h3>
+<div class="spec">
+<p><tt>start(Type, StartArgs) -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="stop-1">stop/1</a></h3>
+<div class="spec">
+<p><tt>stop(State) -&gt; any()</tt></p>
+</div>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Sep 20 2009, 09:15:40.</i></p>
+</body>
+</html>

+ 154 - 0
doc/gproc_dist.html

@@ -0,0 +1,154 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Module gproc_dist</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module gproc_dist</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>Extended process registry.
+
+<p><b>Behaviours:</b> <a href="gen_leader.html"><tt>gen_leader</tt></a>.</p>
+<p><b>Authors:</b> Ulf Wiger (<a href="mailto:ulf.wiger@ericsson.com"><tt>ulf.wiger@ericsson.com</tt></a>).</p>
+
+<h2><a name="description">Description</a></h2>Extended process registry
+  <p>This module implements an extended process registry</p>
+  <p>For a detailed description, see gproc/doc/erlang07-wiger.pdf.</p>
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#code_change-4">code_change/4</a></td><td></td></tr>
+<tr><td valign="top"><a href="#elected-2">elected/2</a></td><td></td></tr>
+<tr><td valign="top"><a href="#from_leader-3">from_leader/3</a></td><td></td></tr>
+<tr><td valign="top"><a href="#handle_DOWN-3">handle_DOWN/3</a></td><td></td></tr>
+<tr><td valign="top"><a href="#handle_call-3">handle_call/3</a></td><td></td></tr>
+<tr><td valign="top"><a href="#handle_cast-2">handle_cast/2</a></td><td></td></tr>
+<tr><td valign="top"><a href="#handle_info-2">handle_info/2</a></td><td></td></tr>
+<tr><td valign="top"><a href="#handle_leader_call-4">handle_leader_call/4</a></td><td></td></tr>
+<tr><td valign="top"><a href="#handle_leader_cast-3">handle_leader_cast/3</a></td><td></td></tr>
+<tr><td valign="top"><a href="#init-1">init/1</a></td><td></td></tr>
+<tr><td valign="top"><a href="#mreg-2">mreg/2</a></td><td></td></tr>
+<tr><td valign="top"><a href="#reg-2">reg/2</a></td><td>
+      Class = n  - unique name
+            | p  - non-unique property
+            | c  - counter
+            | a  - aggregated counter
+      Scope = l | g (global or local).</td></tr>
+<tr><td valign="top"><a href="#set_value-2">set_value/2</a></td><td></td></tr>
+<tr><td valign="top"><a href="#start_link-0">start_link/0</a></td><td></td></tr>
+<tr><td valign="top"><a href="#start_link-1">start_link/1</a></td><td></td></tr>
+<tr><td valign="top"><a href="#surrendered-3">surrendered/3</a></td><td></td></tr>
+<tr><td valign="top"><a href="#terminate-2">terminate/2</a></td><td></td></tr>
+<tr><td valign="top"><a href="#unreg-1">unreg/1</a></td><td></td></tr>
+<tr><td valign="top"><a href="#update_counter-2">update_counter/2</a></td><td></td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="code_change-4">code_change/4</a></h3>
+<div class="spec">
+<p><tt>code_change(FromVsn, S, Extra, E) -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="elected-2">elected/2</a></h3>
+<div class="spec">
+<p><tt>elected(S, E) -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="from_leader-3">from_leader/3</a></h3>
+<div class="spec">
+<p><tt>from_leader(Ops, S, E) -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="handle_DOWN-3">handle_DOWN/3</a></h3>
+<div class="spec">
+<p><tt>handle_DOWN(Node, S, E) -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="handle_call-3">handle_call/3</a></h3>
+<div class="spec">
+<p><tt>handle_call(X1, X2, S) -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="handle_cast-2">handle_cast/2</a></h3>
+<div class="spec">
+<p><tt>handle_cast(Msg, S) -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="handle_info-2">handle_info/2</a></h3>
+<div class="spec">
+<p><tt>handle_info(X1, S) -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="handle_leader_call-4">handle_leader_call/4</a></h3>
+<div class="spec">
+<p><tt>handle_leader_call(X1, From, S, E) -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="handle_leader_cast-3">handle_leader_cast/3</a></h3>
+<div class="spec">
+<p><tt>handle_leader_cast(X1, S, E) -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="init-1">init/1</a></h3>
+<div class="spec">
+<p><tt>init(X1) -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="mreg-2">mreg/2</a></h3>
+<div class="spec">
+<p><tt>mreg(T, KVL) -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="reg-2">reg/2</a></h3>
+<div class="spec">
+<p><tt>reg(Key, Value) -&gt; any()</tt></p>
+</div><p>
+      Class = n  - unique name
+            | p  - non-unique property
+            | c  - counter
+            | a  - aggregated counter
+      Scope = l | g (global or local)
+  </p>
+
+<h3 class="function"><a name="set_value-2">set_value/2</a></h3>
+<div class="spec">
+<p><tt>set_value(Key, Value) -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="start_link-0">start_link/0</a></h3>
+<div class="spec">
+<p><tt>start_link() -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="start_link-1">start_link/1</a></h3>
+<div class="spec">
+<p><tt>start_link(Nodes) -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="surrendered-3">surrendered/3</a></h3>
+<div class="spec">
+<p><tt>surrendered(S, X2, E) -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="terminate-2">terminate/2</a></h3>
+<div class="spec">
+<p><tt>terminate(Reason, S) -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="unreg-1">unreg/1</a></h3>
+<div class="spec">
+<p><tt>unreg(Key) -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="update_counter-2">update_counter/2</a></h3>
+<div class="spec">
+<p><tt>update_counter(Key, Incr) -&gt; any()</tt></p>
+</div>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Sep 20 2009, 09:15:40.</i></p>
+</body>
+</html>

+ 36 - 0
doc/gproc_init.html

@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Module gproc_init</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module gproc_init</h1>
+<ul class="index"><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>
+
+
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#hard_reset-0">hard_reset/0</a></td><td></td></tr>
+<tr><td valign="top"><a href="#soft_reset-0">soft_reset/0</a></td><td></td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="hard_reset-0">hard_reset/0</a></h3>
+<div class="spec">
+<p><tt>hard_reset() -&gt; any()</tt></p>
+</div>
+
+<h3 class="function"><a name="soft_reset-0">soft_reset/0</a></h3>
+<div class="spec">
+<p><tt>soft_reset() -&gt; any()</tt></p>
+</div>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Sep 20 2009, 09:15:40.</i></p>
+</body>
+</html>

+ 23 - 0
doc/gproc_lib.html

@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Module gproc_lib</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module gproc_lib</h1>
+<ul class="index"><li><a href="#description">Description</a></li></ul>Extended process registry.
+
+<p><b>Authors:</b> Ulf Wiger (<a href="mailto:ulf.wiger@ericsson.com"><tt>ulf.wiger@ericsson.com</tt></a>).</p>
+
+<h2><a name="description">Description</a></h2>Extended process registry
+  <p>This module implements an extended process registry</p>
+  <p>For a detailed description, see gproc/doc/erlang07-wiger.pdf.</p><hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Sep 20 2009, 09:15:40.</i></p>
+</body>
+</html>

+ 37 - 0
doc/gproc_sup.html

@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Module gproc_sup</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module gproc_sup</h1>
+<ul class="index"><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>
+
+<p><b>Behaviours:</b> <a href="supervisor.html"><tt>supervisor</tt></a>.</p>
+
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#init-1">init/1</a></td><td>The main GPROC supervisor.</td></tr>
+<tr><td valign="top"><a href="#start_link-1">start_link/1</a></td><td></td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="init-1">init/1</a></h3>
+<div class="spec">
+<p><tt>init(Args) -&gt; any()</tt></p>
+</div><p>The main GPROC supervisor.</p>
+
+<h3 class="function"><a name="start_link-1">start_link/1</a></h3>
+<div class="spec">
+<p><tt>start_link(Args) -&gt; any()</tt></p>
+</div>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Sep 20 2009, 09:15:40.</i></p>
+</body>
+</html>

+ 17 - 0
doc/index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>The gproc application</title>
+</head>
+<frameset cols="20%,80%">
+<frame src="modules-frame.html" name="modulesFrame" title="">
+
+<frame src="overview-summary.html" name="overviewFrame" title="">
+<noframes>
+<h2>This page uses frames</h2>
+<p>Your browser does not accept frames.
+<br>You should go to the <a href="overview-summary.html">non-frame version</a> instead.
+</p>
+</noframes>
+</frameset>
+</html>

+ 17 - 0
doc/modules-frame.html

@@ -0,0 +1,17 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>The gproc application</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<h2 class="indextitle">Modules</h2>
+<table width="100%" border="0" summary="list of modules">
+<tr><td><a href="gproc.html" target="overviewFrame" class="module">gproc</a></td></tr>
+<tr><td><a href="gproc_app.html" target="overviewFrame" class="module">gproc_app</a></td></tr>
+<tr><td><a href="gproc_dist.html" target="overviewFrame" class="module">gproc_dist</a></td></tr>
+<tr><td><a href="gproc_init.html" target="overviewFrame" class="module">gproc_init</a></td></tr>
+<tr><td><a href="gproc_lib.html" target="overviewFrame" class="module">gproc_lib</a></td></tr>
+<tr><td><a href="gproc_sup.html" target="overviewFrame" class="module">gproc_sup</a></td></tr></table>
+</body>
+</html>

+ 37 - 0
doc/overview-summary.html

@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>The gproc application</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<h1>The gproc application</h1>
+<p><b>Authors:</b> Ulf Wiger (<a href="mailto:ulf.wiger@erlang-consulting.com"><tt>ulf.wiger@erlang-consulting.com</tt></a>), Joseph Wayne Norton (<a href="mailto:norton@geminimobile.com"><tt>norton@geminimobile.com</tt></a>).</p>
+Extended process dictionary
+<h2>Introduction</h2>
+
+<p>This application was designed to meet the following requirements:</p>
+
+<p><li>
+  <ul>A process can register itself using any term.</ul>
+  <ul>A process can register more than one name</ul>
+  <ul>A process can publish non-unique {Key,Value} 'properties' </ul>
+  <ul>The registry must be efficiently searchable</ul>
+</li></p>
+
+<p>As additional features, the registry was designed to allow global
+registration, and a special {Key,Value} property called a counter.
+It is also possible to create an 'aggregate counter', which will
+continuously reflect the sum of all counters with the same name.</p>
+
+<em>In its current state, the global registration facility is broken
+and should not be used. It will be migrated over to a new version of 
+gen_leader. This work will be done with low priority unless people
+express a strong urge to use this functionality.</em>
+
+<hr>
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Sep 20 2009, 09:15:40.</i></p>
+</body>
+</html>

+ 26 - 0
doc/overview.edoc

@@ -0,0 +1,26 @@
+@author Ulf Wiger <ulf.wiger@erlang-consulting.com>
+@author Joseph Wayne Norton <norton@geminimobile.com>
+
+@doc Extended process dictionary
+<h2>Introduction</h2>
+
+This application was designed to meet the following requirements:
+
+<li>
+  <ul>A process can register itself using any term.</ul>
+  <ul>A process can register more than one name</ul>
+  <ul>A process can publish non-unique {Key,Value} 'properties' </ul>
+  <ul>The registry must be efficiently searchable</ul>
+</li>
+
+As additional features, the registry was designed to allow global
+registration, and a special {Key,Value} property called a counter.
+It is also possible to create an 'aggregate counter', which will
+continuously reflect the sum of all counters with the same name.
+
+<em>In its current state, the global registration facility is broken
+and should not be used. It will be migrated over to a new version of 
+gen_leader. This work will be done with low priority unless people
+express a strong urge to use this functionality.</em>
+
+@end

+ 11 - 0
doc/packages-frame.html

@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>The gproc application</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<h2 class="indextitle">Packages</h2>
+<table width="100%" border="0" summary="list of packages"></table>
+</body>
+</html>

+ 55 - 0
doc/stylesheet.css

@@ -0,0 +1,55 @@
+/* standard EDoc style sheet */
+body {
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+      	margin-left: .25in;
+       	margin-right: .2in;
+       	margin-top: 0.2in;
+       	margin-bottom: 0.2in;
+       	color: #000000;
+       	background-color: #ffffff;
+}
+h1,h2 {
+ 	margin-left: -0.2in;
+}
+div.navbar {
+	background-color: #add8e6;
+	padding: 0.2em;
+}
+h2.indextitle {
+	padding: 0.4em;
+	background-color: #add8e6;
+}
+h3.function,h3.typedecl {
+	background-color: #add8e6;
+ 	padding-left: 1em;
+}
+div.spec {
+ 	margin-left: 2em;
+	background-color: #eeeeee;
+}
+a.module,a.package {
+	text-decoration:none
+}
+a.module:hover,a.package:hover {
+	background-color: #eeeeee;
+}
+ul.definitions {
+	list-style-type: none;
+}
+ul.index {
+	list-style-type: none;
+	background-color: #eeeeee;
+}
+
+/*
+ * Minor style tweaks
+ */
+ul {
+	list-style-type: square;
+}
+table {
+	border-collapse: collapse;
+}
+td {
+	padding: 3
+}

+ 10 - 1
src/Makefile

@@ -23,17 +23,21 @@
 
 .SUFFIXES: .erl .beam
 
+APP = gproc
+
 vpath %.beam ../ebin
 vpath %.pdf ../doc
 
 ERLC = erlc -W -I ../include -o ../ebin
 ERLC += +debug_info
 
-EQC ?= /host/dev/eqc-1.16/ebin
+EQC ?= /host/dev/eqc-1.16
 
 EQC_ERLC = $(ERLC) -I $(EQC)/include
 EQC_ERL = erl -pz ../ebin -pz $(EQC)/ebin -pz ./Unit-Quick-Files -kernel error_logger silent
 
+SOURCES = $(wildcard *.erl)
+
 beams = gproc.beam \
 	gproc_app.beam \
 	gproc_dist.beam \
@@ -51,6 +55,11 @@ $(beams) : %.beam : %.erl
 ./Unit-Quick-Files/gproc_eqc.beam : ./Unit-Quick-Files/gproc_eqc.erl
 	$(EQC_ERLC) $<
 
+doc: ../doc/edoc-info
+
+../doc/edoc-info: ../doc/overview.edoc $(SOURCES)
+	erl -noshell -eval 'edoc:application($(APP),"..",[])' -s init stop
+
 ## test targets
 test : all ./Unit-Quick-Files/gproc_eqc.beam
 	$(EQC_ERL) -s gproc_eqc run -s erlang halt

+ 203 - 72
src/gproc.erl

@@ -18,6 +18,21 @@
 %% @doc Extended process registry
 %% <p>This module implements an extended process registry</p>
 %% <p>For a detailed description, see gproc/doc/erlang07-wiger.pdf.</p>
+%%
+%% @type type()  = n | p | c | a. n = name; p = property; c = counter; 
+%%                                a = aggregate_counter
+%% @type scope() = l | g. l = local registration; g = global registration
+%% @type context() = {scope(), type()} | type(). Local scope is the default
+%% @type sel_type() = n | p | c | a |
+%%                    names | props | counters | aggr_counters.
+%% @type headpat() = {keypat(),pidpat(),ValPat}.
+%% @type keypat() = {sel_type() | sel_var(),
+%%                   l | g | sel_var(),
+%%                   any()}.
+%% @type pidpat() = pid() | sel_var().
+%% sel_var() = DollarVar | '_'.
+%% @type sel_pattern() = [{headpat(), Guards, Prod}].
+%% @type key()   = {type(), scope(), any()}
 %% @end
 -module(gproc).
 -behaviour(gen_server).
@@ -33,7 +48,7 @@
          update_counter/2,
          send/2,
          info/1, info/2,
-         select/1, select/2,
+         select/1, select/2, select/3,
          first/1,
          next/2,
          prev/2,
@@ -69,26 +84,20 @@ start_link() ->
     gen_server:start({local, ?SERVER}, ?MODULE, [], []).
 
 
-%%% @spec({Class,Scope, Key}) -> true
-%%% {@equiv reg(Key, undefined)}
-%%%    Class = n  - unique name
-%%%          | p  - non-unique property
-%%%          | c  - counter
-%%%          | a  - aggregated counter
-%%%    Scope = l | g (global or local)
-%%%
+%% @spec reg(Key::key()) -> true
+%%
+%% @doc
+%% @equiv reg(Key, undefined)
+%% @end
 reg(Key) ->
     reg(Key, undefined).
 
 
-%%% @spec({Class,Scope, Key}, Value) -> true
-%%% @doc
-%%%    Class = n  - unique name
-%%%          | p  - non-unique property
-%%%          | c  - counter
-%%%          | a  - aggregated counter
-%%%    Scope = l | g (global or local)
-%%%
+%% @spec reg(Key::key(), Value) -> true
+%%
+%% @doc Register a name or property for the current process
+%%
+%%
 reg({_,g,_} = Key, Value) ->
     %% anything global
     ?CHK_DIST,
@@ -109,6 +118,12 @@ reg({_,l,_} = Key, Value) ->
 reg(_, _) ->
     erlang:error(badarg).
 
+%% @spec mreg(type(), scope(), [{Key::any(), Value::any()}]) -> true
+%%
+%% @doc Register multiple {Key,Value} pairs of a given type and scope.
+%% 
+%% This function is more efficient than calling {@link reg/2} repeatedly.
+%% @end
 mreg(T, g, KVL) ->
     ?CHK_DIST,
     gproc_dist:mreg(T, KVL);
@@ -123,6 +138,10 @@ mreg(p, l, KVL) ->
 mreg(_, _, _) ->
     erlang:error(badarg).
 
+%% @spec (Key:: key()) -> true
+%%
+%% @doc Unregister a name or property.
+%% @end
 unreg(Key) ->
     case Key of
         {_, g, _} ->
@@ -139,14 +158,31 @@ unreg(Key) ->
             end
     end.
 
+%% @spec (select_pattern()) -> list(sel_object())
+%% @doc
+%% @equiv select(all, Pat)
+%% @end
 select(Pat) ->
     select(all, Pat).
 
-select(Scope, Pat) ->
-    ets:select(?TAB, pattern(Pat, Scope)).
+%% @spec (Type::sel_type(), Pat::sel_pattern()) -> [{Key, Pid, Value}]
+%%
+%% @doc Perform a select operation on the process registry.
+%%
+%% The physical representation in the registry may differ from the above,
+%% but the select patterns are transformed appropriately.
+%% @end
+select(Type, Pat) ->
+    ets:select(?TAB, pattern(Pat, Type)).
 
-select(Scope, Pat, NObjs) ->
-    ets:select(?TAB, pattern(Pat, Scope), NObjs).
+%% @spec (Type::sel_type(), Pat::sel_patten(), Limit::integer()) ->
+%%          [{Key, Pid, Value}]
+%% @doc Like {@link select/2} but returns Limit objects at a time.
+%%
+%% See [http://www.erlang.org/doc/man/ets.html#select-3].
+%% @end
+select(Type, Pat, Limit) ->
+    ets:select(?TAB, pattern(Pat, Type), Limit).
 
 
 %%% Local properties can be registered in the local process, since
@@ -168,7 +204,16 @@ local_mreg(T, [_|_] = KVL) ->
 
 
 
-
+%% @spec (Key :: key(), Value) -> true
+%% @doc Sets the value of the registeration entry given by Key
+%% 
+%% Key is assumed to exist and belong to the calling process.
+%% If it doesn't, this function will exit.
+%%
+%% Value can be any term, unless the object is a counter, in which case
+%% it must be an integer.
+%% @end
+%%
 set_value({_,g,_} = Key, Value) ->
     ?CHK_DIST,
     gproc_dist:set_value(Key, Value);
@@ -194,9 +239,11 @@ set_value(_, _) ->
 
 
 
-%%% @spec (Key) -> Value
-%%% @doc Read the value stored with a key registered to the current process.
-%%%
+%% @spec (Key) -> Value
+%% @doc Read the value stored with a key registered to the current process.
+%%
+%% If no such key is registered to the current process, this function exits.
+%% @end
 get_value(Key) ->
     get_value(Key, self()).
 
@@ -213,16 +260,24 @@ get_value(_, _) ->
     erlang:error(badarg).
 
 
-%%% @spec (Key) -> Pid
-%%% @doc Lookup the Pid stored with a key.
-%%%
+%% @spec (Key) -> Pid
+%% @doc Lookup the Pid stored with a key.
+%%
 lookup_pid({_T,_,_} = Key) ->
     case where(Key) of
         undefined -> erlang:error(badarg);
         P -> P
     end.
 
-
+%% @spec (Key::key()) -> pid()
+%%
+%% @doc Returns the pid registered as Key
+%% 
+%% The type of registration entry must be either name or aggregated counter.
+%% Otherwise this function will exit. Use {@link lookup_pids/1} in these
+%% cases.
+%% @end
+%%
 where({T,_,_}=Key) ->
     if T==n orelse T==a ->
             case ets:lookup(?TAB, {Key,T}) of
@@ -235,6 +290,15 @@ where({T,_,_}=Key) ->
             erlang:error(badarg)
     end.
 
+%% @spec (Key::key()) -> [pid()]
+%%
+%% @doc Returns a list of pids with the published key Key
+%%
+%% If the type of registration entry is either name or aggregated counter,
+%% this function will return either an empty list, or a list of one pid.
+%% For non-unique types, the return value can be a list of any length.
+%% @end
+%%
 lookup_pids({T,_,_} = Key) ->
     if T==n orelse T==a ->
             ets:select(?TAB, [{{{Key,T}, '$1', '_'},[],['$1']}]);
@@ -244,7 +308,15 @@ lookup_pids({T,_,_} = Key) ->
             erlang:error(badarg)
     end.
 
-
+%% @spec (Key::key(), Incr::integer()) -> integer()
+%%
+%% @doc Updates the counter registered as Key for the current process.
+%%
+%% This function works like ets:update_counter/3
+%% (see [http://www.erlang.org/doc/man/ets.html#update_counter-3]), but 
+%% will fail if the type of object referred to by Key is not a counter.
+%% @end
+%%
 update_counter({c,l,_} = Key, Incr) when is_integer(Incr) ->
     gproc_lib:update_counter(Key, Incr, self());
 update_counter({c,g,_} = Key, Incr) when is_integer(Incr) ->
@@ -255,7 +327,16 @@ update_counter(_, _) ->
 
 
 
-
+%% @spec (Key::key(), Msg::any()) -> Msg
+%%
+%% @doc Sends a message to the process, or processes, corresponding to Key.
+%%
+%% If Key belongs to a unique object (name or aggregated counter), this 
+%% function will send a message to the corresponding process, or fail if there
+%% is no such process. If Key is for a non-unique object type (counter or 
+%% property), Msg will be send to all processes that have such an object.
+%% @end
+%%
 send({T,C,_} = Key, Msg) when C==l; C==g ->
     if T == n orelse T == a ->
             case ets:lookup(?TAB, {Key, T}) of
@@ -280,8 +361,16 @@ send(_, _) ->
     erlang:error(badarg).
 
 
-first(Scope) ->
-    {HeadPat,_} = headpat(Scope, '_', '_', '_'),
+%% @spec (Type :: type()) -> key() | '$end_of_table'
+%%
+%% @doc Behaves as ets:first(Tab) for a given type of registration object.
+%%
+%% See [http://www.erlang.org/doc/man/ets.html#first-1].
+%%  The registry behaves as an ordered_set table.
+%% @end
+%%
+first(Type) ->
+    {HeadPat,_} = headpat(Type, '_', '_', '_'),
     case ets:select(?TAB, [{HeadPat,[],[{element,1,'$_'}]}], 1) of
         {[First], _} ->
             First;
@@ -289,21 +378,46 @@ first(Scope) ->
             '$end_of_table'
     end.
 
-last(Scope) ->
-    {C, T} = get_c_t(Scope),
-    C1 = if C == '_'; C == l -> m;
-            C == g -> h
+%% @spec (Context :: context()) -> key() | '$end_of_table'
+%%
+%% @doc Behaves as ets:last(Tab) for a given type of registration object.
+%%
+%% See [http://www.erlang.org/doc/man/ets.html#last-1].
+%% The registry behaves as an ordered_set table.
+%% @end
+%%
+last(Context) ->
+    {S, T} = get_s_t(Context),
+    S1 = if S == '_'; S == l -> m;
+            S == g -> h
          end,
-    Beyond = {{T,C1,[]},[]},
-    step(ets:prev(?TAB, Beyond), C, T).
+    Beyond = {{T,S1,[]},[]},
+    step(ets:prev(?TAB, Beyond), S, T).
+
 
-next(Scope, K) ->
-    {C,T} = get_c_t(Scope),
-    step(ets:next(?TAB,K), C, T).
+%% @spec (Context::context(), Key::key()) -> key() | '$end_of_table'
+%%
+%% @doc Behaves as ets:next(Tab,Key) for a given type of registration object.
+%%
+%% See [http://www.erlang.org/doc/man/ets.html#next-2].
+%% The registry behaves as an ordered_set table.
+%% @end
+%%
+next(Context, K) ->
+    {S,T} = get_s_t(Context),
+    step(ets:next(?TAB,K), S, T).
 
-prev(Scope, K) ->
-    {C, T} = get_c_t(Scope),
-    step(ets:prev(?TAB, K), C, T).
+%% @spec (Context::context(), Key::key()) -> key() | '$end_of_table'
+%%
+%% @doc Behaves as ets:prev(Tab,Key) for a given type of registration object.
+%%
+%% See [http://www.erlang.org/doc/man/ets.html#prev-2].
+%% The registry behaves as an ordered_set table.
+%% @end
+%%
+prev(Context, K) ->
+    {S, T} = get_s_t(Context),
+    step(ets:prev(?TAB, K), S, T).
 
 step(Key, '_', '_') ->
     case Key of
@@ -315,23 +429,39 @@ step(Key, '_', T) ->
         {{T,_,_},_} -> Key;
         _ -> '$end_of_table'
     end;
-step(Key, C, '_') ->
+step(Key, S, '_') ->
     case Key of
-        {{_, C, _}, _} -> Key;
+        {{_, S, _}, _} -> Key;
         _ -> '$end_of_table'
     end;
-step(Key, C, T) ->
+step(Key, S, T) ->
     case Key of
-        {{T,C,_},_} -> Key;
+        {{T, S, _}, _} -> Key;
         _ -> '$end_of_table'
     end.
 
 
-
+%% @spec (Pid::pid()) -> ProcessInfo
+%% ProcessInfo = [{gproc, [{Key,Value}]} | ProcessInfo]
+%%
+%% @doc Similar to `process_info(Pid)' but with additional gproc info.
+%% 
+%% Returns the same information as process_info(Pid), but with the 
+%% addition of a `gproc' information item, containing the `{Key,Value}'
+%% pairs registered to the process.
+%% @end
 info(Pid) when is_pid(Pid) ->
     Items = [?MODULE | [ I || {I,_} <- process_info(self())]],
     [info(Pid,I) || I <- Items].
 
+%% @spec (Pid::pid(), Item::atom()) -> {Item, Info}
+%%
+%% @doc Similar to process_info(Pid, Item), but with additional gproc info.
+%%
+%% For `Item = gproc', this function returns a list of `{Key, Value}' pairs
+%% registered to the process Pid. For other values of Item, it returns the 
+%% same as [http://www.erlang.org/doc/man/erlang.html#process_info-2].
+%% @end
 info(Pid, ?MODULE) ->
     Keys = ets:select(?TAB, [{ {{Pid,'$1'}}, [], ['$1'] }]),
     {?MODULE, lists:zf(
@@ -351,11 +481,12 @@ info(Pid, I) ->
 
 %%% ==========================================================
 
-
+%% @hidden
 handle_cast({monitor_me, Pid}, S) ->
     erlang:monitor(process, Pid),
     {noreply, S}.
 
+%% @hidden
 handle_call({reg, {_T,l,_} = Key, Val}, {Pid,_}, S) ->
     case try_insert_reg(Key, Val, Pid) of
         true ->
@@ -389,6 +520,7 @@ handle_call({set, {_,l,_} = Key, Value}, {Pid,_}, S) ->
 handle_call(_, _, S) ->
     {reply, badarg, S}.
 
+%% @hidden
 handle_info({'DOWN', _MRef, process, Pid, _}, S) ->
     process_is_down(Pid),
     {noreply, S};
@@ -396,10 +528,11 @@ handle_info(_, S) ->
     {noreply, S}.
 
 
-
+%% @hidden
 code_change(_FromVsn, S, _Extra) ->
     {ok, S}.
 
+%% @hidden
 terminate(_Reason, _S) ->
     ok.
 
@@ -448,6 +581,8 @@ process_is_down(Pid) ->
 create_tabs() ->
     ets:new(?MODULE, [ordered_set, public, named_table]).
 
+
+%% @hidden
 init([]) ->
     {ok, #state{}}.
 
@@ -508,8 +643,8 @@ obj_prod_l() ->
       {element,3,'$_'} ].
 
 
-headpat({C, T}, V1,V2,V3) when C==global; C==local; C==all ->
-    headpat(type(T), ctxt(C), V1,V2,V3);
+headpat({S, T}, V1,V2,V3) when S==global; S==local; S==all ->
+    headpat(type(T), scope(S), V1,V2,V3);
 headpat(T, V1, V2, V3) when is_atom(T) ->
     headpat(type(T), l, V1, V2, V3);
 headpat(_, _, _, _) -> erlang:error(badarg).
@@ -542,7 +677,7 @@ headpat(T, C, V1,V2,V3) ->
                 end,
     {{{Kp,K2},V2,V3}, Vars}.
 
-l(L) -> L.
+%% l(L) -> L.
     
 
 
@@ -556,24 +691,25 @@ subst(X, V, F, Vs) ->
             {V, Vs}
     end.
 
-ctxt(all)    -> '_';
-ctxt(global) -> g;
-ctxt(local)  -> l.
+scope(all)    -> '_';
+scope(global) -> g;
+scope(local)  -> l.
 
 type(all)   -> '_';
+type(T) when T==n; T==p; T==c; T==a -> T;
 type(names) -> n;
 type(props) -> p;
 type(counters) -> c;
 type(aggr_counters) -> a.
 
-keypat(Scope) ->
-    {C,T} = get_c_t(Scope),
-    {{T,C,'_'},'_'}.
+keypat(Context) ->
+    {S,T} = get_s_t(Context),
+    {{T,S,'_'},'_'}.
 
 
 
-get_c_t({C,T}) -> {ctxt(C), type(T)};
-get_c_t(T) when is_atom(T) ->
+get_s_t({S,T}) -> {scope(S), type(T)};
+get_s_t(T) when is_atom(T) ->
     {l, type(T)}.
 
 is_var('$1') -> {true,1};
@@ -599,11 +735,6 @@ is_var(X) when is_atom(X) ->
     end;
 is_var(_) -> false.
 
-vars(N) when N > 3 ->
-    {'$1','$2','$3'};
-vars(_) ->
-    {'$4','$5','$6'}.
-
 
 rewrite(Gs, R) ->
     [rewrite1(G, R) || G <- Gs].
@@ -632,8 +763,8 @@ rewrite1(Expr, _) ->
     Expr.
 
 
-table(Scope) ->
-    table(Scope, []).
+table(Type) ->
+    table(Type, []).
 
 table(T, Opts) ->
     [Traverse, NObjs] = [proplists:get_value(K,Opts,Def) ||
@@ -643,9 +774,9 @@ table(T, Opts) ->
                  fun() -> qlc_next(T, first(T)) end;
              last_prev -> fun() -> qlc_prev(T, last(T)) end;
              select ->
-                 fun(MS) -> qlc_select(select(T,MS,NObjs)) end;
+                 fun(MS) -> qlc_select(select(T, MS, NObjs)) end;
              {select,MS} ->
-                 fun() -> qlc_select(select(T,MS,NObjs)) end;
+                 fun() -> qlc_select(select(T, MS, NObjs)) end;
              _ ->
                  erlang:error(badarg, [T,Opts])
          end,