PageRenderTime 75ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/proc/doc/proc.html

https://github.com/babo/jungerl
HTML | 698 lines | 653 code | 45 blank | 0 comment | 0 complexity | dc8081e184a9ff354c441a81c9595c94 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, AGPL-1.0
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  2. <html>
  3. <head>
  4. <title>Module proc</title>
  5. <link rel="stylesheet" type="text/css" href="stylesheet.css">
  6. </head>
  7. <body bgcolor="white">
  8. <h1>Module proc</h1>
  9. Flexible Local Process Registry.
  10. <p>Copyright © Ericsson AB 2005 All rights reserved.
  11. The information in this document is the property of Ericsson. Except
  12. as specifically authorized in writing by Ericsson, the receiver of
  13. this document shall keep the information contained herein
  14. confidential and shall protect the same in whole or in part from
  15. disclosure and dissemination to third parties. Disclosure and
  16. disseminations to the receivers employees shall only be made on a
  17. strict need to know basis.</p>
  18. <ul><li><a href="#description">Description</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>
  19. <p><b>Behaviours:</b> <a href="gen_server.html"><tt>gen_server</tt></a>.</p>
  20. <h2><a name="description">Description</a></h2><p>Flexible Local Process Registry</p>
  21. <p>This application supports local registration of processes using any
  22. erlang term. Furthermore, each process can register by several
  23. different names at the same time.</p>
  24. <h2>Semantics:</h2> <p><code>proc</code> works with unique <code>names</code> and
  25. non-unique <code>properties</code>. </p><p>A name can be any erlang term
  26. (except a pid or '_'), and each process can register itself under many
  27. different unique names.
  28. A <code>property</code> can be any term (except '_'), and must be unique
  29. within a process, but several processes can register the same
  30. property.</p>
  31. <p>Furthermore, there are "fold" and "select"
  32. functions to allow for efficient iteration over names or properties in the
  33. process registry.</p>
  34. <p>Many of the operations to access names and properties rely on
  35. the semantics given by <a href="http://www.erlang.org/edoc/doc/stdlib/doc/ets.html"><code>//stdlib/ets</code></a>, and this is often
  36. mentioned in the interface documentation. This means that it is
  37. safe to assume that the functions conform to the search semantics
  38. of ordered_set ets tables. However, it is <i>not</i> safe to assume
  39. anything about whether the data in fact resides in ets tables, and
  40. if so, what those tables are called, or indeed how the data is
  41. represented internally.</p>
  42. <h2><a name="index">Function Index</a></h2>
  43. <table width="100%" border="1"><tr><td valign="top"><a href="#add_counter-2">add_counter/2</a></td><td>Publish a counter property for the current process.</td></tr>
  44. <tr><td valign="top"><a href="#add_counter-3">add_counter/3</a></td><td>Publish a counter property on behalf of <code>Process</code>.</td></tr>
  45. <tr><td valign="top"><a href="#add_property-1">add_property/1</a></td><td>Publish a property of the current process.</td></tr>
  46. <tr><td valign="top"><a href="#add_property-2">add_property/2</a></td><td>Publish a property on behalf of another process.</td></tr>
  47. <tr><td valign="top"><a href="#await_reg-1">await_reg/1</a></td><td>Request to be notified when someone registers as <code>Name</code>.</td></tr>
  48. <tr><td valign="top"><a href="#clear_await_reg-1">clear_await_reg/1</a></td><td>Cancel waiting for notification of process registration of a
  49. given name.</td></tr>
  50. <tr><td valign="top"><a href="#del_counter-1">del_counter/1</a></td><td>Un-publish a counter property for the current process.</td></tr>
  51. <tr><td valign="top"><a href="#del_counter-2">del_counter/2</a></td><td>Un-publish a counter property on behalf of <code>Process</code>.</td></tr>
  52. <tr><td valign="top"><a href="#del_property-1">del_property/1</a></td><td>Un-publishes the property <code>Property</code> for the current process.</td></tr>
  53. <tr><td valign="top"><a href="#del_property-2">del_property/2</a></td><td>Un-publish the property <code>Property</code> on behalf of <code>Process</code>.</td></tr>
  54. <tr><td valign="top"><a href="#enable_i-0">enable_i/0</a></td><td/></tr>
  55. <tr><td valign="top"><a href="#first-1">first/1</a></td><td>Analogous to <a href="ets.html#first-1"><code>ets:first/1</code></a>.</td></tr>
  56. <tr><td valign="top"><a href="#fold_names-3">fold_names/3</a></td><td>Similar to <a href="lists.html#foldl-3"><code>lists:foldl/3</code></a>, but based on a list of select
  57. patterns, identifying a sub-set of unique names.</td></tr>
  58. <tr><td valign="top"><a href="#fold_names-4">fold_names/4</a></td><td>Like <a href="#fold_names-3"><code>fold_names/3</code></a>, but works in batches of <code>Limit</code> objects
  59. at a time, in order to improve memory characteristics.</td></tr>
  60. <tr><td valign="top"><a href="#fold_names-5">fold_names/5</a></td><td>Like <a href="#fold_names-4"><code>fold_names/4</code></a>, but applies a "Regulator function"
  61. after each batch of objects before proceeding with the next one.</td></tr>
  62. <tr><td valign="top"><a href="#fold_properties-3">fold_properties/3</a></td><td>Similar to <a href="http://www.erlang.org/edoc/doc/stdlib/doc/lists.html#foldl-3"><code>//stdlib/lists:foldl/3</code></a>, but based on a
  63. select pattern on <code>Property</code>, identifying a sub-set of
  64. published properties.</td></tr>
  65. <tr><td valign="top"><a href="#fold_properties-4">fold_properties/4</a></td><td>Like <a href="#fold_properties-3"><code>fold_properties/3</code></a>, but works in batches of <code>Limit</code>
  66. objects at a time, in order to improve raw performance.</td></tr>
  67. <tr><td valign="top"><a href="#fold_properties-5">fold_properties/5</a></td><td>Like <a href="#fold_properties-4"><code>fold_properties/4</code></a>, but applies a "Regulator function"
  68. after each batch of objects before proceeding with the next one.</td></tr>
  69. <tr><td valign="top"><a href="#guards-1">guards/1</a></td><td>Expand a list of <code>select</code> guards, allowing for the pseudo guard
  70. <code>is_counter</code>.</td></tr>
  71. <tr><td valign="top"><a href="#i-1">i/1</a></td><td>Like <a href="c.html#i-0"><code>c:i/0</code></a>, but allows for filtering output with
  72. <code>proc</code> names and properties.</td></tr>
  73. <tr><td valign="top"><a href="#info-1">info/1</a></td><td>Like <code>process_info(PidOfProcess)</code>, but with added
  74. proc-related attributes.</td></tr>
  75. <tr><td valign="top"><a href="#info-2">info/2</a></td><td>Like <code>process_info(PidOfProcess, Attr)</code> but accepts some
  76. additional attributes.</td></tr>
  77. <tr><td valign="top"><a href="#is_counter-1">is_counter/1</a></td><td>Check whether <code>Property</code> is a counter property.</td></tr>
  78. <tr><td valign="top"><a href="#is_counter-2">is_counter/2</a></td><td>Check whether <code>Propery</code> registered under <code>Process</code> is a counter
  79. property.</td></tr>
  80. <tr><td valign="top"><a href="#is_property-1">is_property/1</a></td><td>Returns <code>true</code> if <code>Property</code> is a published property of the current
  81. process.</td></tr>
  82. <tr><td valign="top"><a href="#is_property-2">is_property/2</a></td><td>Check whether Property is in fact a property registered with Process.</td></tr>
  83. <tr><td valign="top"><a href="#last-1">last/1</a></td><td>Analogous to <a href="ets.html#last-1"><code>ets:last/1</code></a>.</td></tr>
  84. <tr><td valign="top"><a href="#next-2">next/2</a></td><td>Analogous to <a href="ets.html#next-2"><code>ets:next/2</code></a>.</td></tr>
  85. <tr><td valign="top"><a href="#pids-1">pids/1</a></td><td>Returns all pids for which a property <code>Property</code> is published.</td></tr>
  86. <tr><td valign="top"><a href="#pids-2">pids/2</a></td><td>Similar to <a href="#pids-1"><code>pids/1</code></a>, but also allowing select guards.</td></tr>
  87. <tr><td valign="top"><a href="#previous-2">previous/2</a></td><td>Analogous to <a href="ets.html#previous-2"><code>ets:previous/2</code></a>.</td></tr>
  88. <tr><td valign="top"><a href="#properties_by_pid-1">properties_by_pid/1</a></td><td>Lists all properties for a given process.</td></tr>
  89. <tr><td valign="top"><a href="#properties_by_pid-2">properties_by_pid/2</a></td><td>Lists all properties for a given process that match the pattern
  90. KeyPat.</td></tr>
  91. <tr><td valign="top"><a href="#properties_by_pid-3">properties_by_pid/3</a></td><td>Like <a href="#properties_by_pid-2"><code>properties_by_pid/2</code></a>, but with an added list of guards.</td></tr>
  92. <tr><td valign="top"><a href="#read_counter-1">read_counter/1</a></td><td>Read the value of a counter property for the current process.</td></tr>
  93. <tr><td valign="top"><a href="#read_counter-2">read_counter/2</a></td><td>Read the value of a counter property published by <code>Process</code>.</td></tr>
  94. <tr><td valign="top"><a href="#reg-1">reg/1</a></td><td>Register a unique <code>Name</code>.</td></tr>
  95. <tr><td valign="top"><a href="#replace_property-2">replace_property/2</a></td><td>Equivalent to del_property(OldProperty), add_property(NewProperty),
  96. but much more efficient.</td></tr>
  97. <tr><td valign="top"><a href="#replace_property-3">replace_property/3</a></td><td>Replace <code>OldProperty</code> with <code>NewProperty</code> on behalf of <code>Process</code>.</td></tr>
  98. <tr><td valign="top"><a href="#select-1">select/1</a></td><td>Analogous to <a href="ets.html#select-1"><code>ets:select/1</code></a>.</td></tr>
  99. <tr><td valign="top"><a href="#select_fold_properties-3">select_fold_properties/3</a></td><td>Like <a href="#fold_properties-3"><code>fold_properties/3</code></a> but more flexible as it allows
  100. for combining several patterns into one query.</td></tr>
  101. <tr><td valign="top"><a href="#select_fold_properties-4">select_fold_properties/4</a></td><td>Like <a href="#select_fold_properties-3"><code>select_fold_properties/3</code></a>, but works in batches of <code>Limit</code>
  102. objects at a time, in order to improve raw performance.</td></tr>
  103. <tr><td valign="top"><a href="#select_fold_properties-5">select_fold_properties/5</a></td><td>Like <a href="#select_fold_properties-4"><code>select_fold_properties/4</code></a>, but applies a
  104. "Regulator function"
  105. after each batch of objects before proceeding with the next one.</td></tr>
  106. <tr><td valign="top"><a href="#select_names-1">select_names/1</a></td><td>Returns <code>{Name,Pid}</code> objects one at a time based on
  107. a given selection of all registered unique names.</td></tr>
  108. <tr><td valign="top"><a href="#select_names-2">select_names/2</a></td><td>Like <a href="#select_names-1"><code>select_names/1</code></a>, but works in batches of <code>Limit</code>
  109. objects at a time, in order to improve raw performance.</td></tr>
  110. <tr><td valign="top"><a href="#select_pattern-1">select_pattern/1</a></td><td>Helper function to generate select patterns from the more
  111. intuitive patterns <code>Property</code> (or <code>Name</code>, as it works equally for names).</td></tr>
  112. <tr><td valign="top"><a href="#select_pattern-2">select_pattern/2</a></td><td>As <a href="#select_pattern-1"><code>select_pattern/1</code></a>, but with the option to add Guard
  113. expressions.</td></tr>
  114. <tr><td valign="top"><a href="#select_properties-1">select_properties/1</a></td><td>Returns <code>{Property,Pid}</code> objects one at a time based on
  115. a given selection of all registered instances of <code>Key</code>.</td></tr>
  116. <tr><td valign="top"><a href="#select_properties-2">select_properties/2</a></td><td>Like <a href="#select_properties-1"><code>select_properties/1</code></a> but works in batches of <code>Limit</code>
  117. objects at a time in order to improve raw performance.</td></tr>
  118. <tr><td valign="top"><a href="#send-2">send/2</a></td><td>Analogous to <code>Name ! Msg</code>, except that send({Node,Dest}, Msg)
  119. will be interpreted as 'send to the local process registered as
  120. {Node, Dest}'.</td></tr>
  121. <tr><td valign="top"><a href="#set_access-1">set_access/1</a></td><td>Control the ability of Processes to perform certain functions
  122. on behalf of the current process.</td></tr>
  123. <tr><td valign="top"><a href="#start_link-0">start_link/0</a></td><td>Starts the proc server.</td></tr>
  124. <tr><td valign="top"><a href="#unreg-1">unreg/1</a></td><td>Unregister <code>Name</code>.</td></tr>
  125. <tr><td valign="top"><a href="#update_counter-2">update_counter/2</a></td><td>Update the counter attribute of a counter property.</td></tr>
  126. <tr><td valign="top"><a href="#update_counter-3">update_counter/3</a></td><td>Update counter attribute on behalf of <code>Process</code>.</td></tr>
  127. <tr><td valign="top"><a href="#where-1">where/1</a></td><td>Analogous to <code>erlang:whereis(Name)</code>.</td></tr>
  128. </table>
  129. <h2><a name="functions">Function Details</a></h2>
  130. <h3><a name="add_counter-2">add_counter/2</a></h3>
  131. <p><tt>add_counter(Name, InitialValue::integer()) -&gt; true</tt></p>
  132. <p>Publish a counter property for the current process.
  133. <p>Counter properties behave as normal properties with
  134. the following exceptions:</p>
  135. <ul>
  136. <li>A counter property has an integer value attached, which can be
  137. updated using <a href="#update_counter-2"><code>update_counter/2</code></a></li>
  138. <li>Counter properties cannot be replaced using
  139. <a href="#replace_property-2"><code>replace_property/2</code></a></li>
  140. </ul></p>
  141. <h3><a name="add_counter-3">add_counter/3</a></h3>
  142. <p><tt>add_counter(Process, Name, InitialValue::integer()) -&gt; true</tt></p>
  143. <p>Publish a counter property on behalf of <code>Process</code>.
  144. <p>This function is allowed only if permission to add counters
  145. has been given through <code>Process</code> calling <a href="#grant_access-2"><code>grant_access/2</code></a>.</p>
  146. <p>If permission to add counters has not been given, this function
  147. exits with <code>access</code>.</p></p>
  148. <h3><a name="add_property-1">add_property/1</a></h3>
  149. <p><tt>add_property(Property::term()) -&gt; true</tt></p>
  150. <p>Publish a property of the current process.
  151. <p>If <code>Property</code> is already published for the current process,
  152. this function exits with badarg.</p>
  153. <p>This operation can be viewed as publishing the meta-data <code>Property</code>
  154. as part of the interface of the process. Several processes may publish
  155. the same property. The process can be found (as part of a group)
  156. through this property, using one of the functions <a href="#fold_properties-3"><code>fold_properties/3</code></a>, <a href="#pids-1"><code>pids/1</code></a>, et al.</p></p>
  157. <h3><a name="add_property-2">add_property/2</a></h3>
  158. <p><tt>add_property(Process, Property) -&gt; true</tt></p>
  159. <p>Publish a property on behalf of another process.
  160. <p>Adding properties on behalf of another process is only
  161. allowed if the other process has called <a href="#set_access-1"><code>set_access/1</code></a>,
  162. giving this process the proper rights to act as proxy.</p>
  163. <p><code>Process</code> can be either a <code>pid()</code> or a registered name.</p></p>
  164. <h3><a name="await_reg-1">await_reg/1</a></h3>
  165. <p><tt>await_reg(Pid::Name) -&gt; {already_registered, pid()} | Reg</tt></p>
  166. <p>Request to be notified when someone registers as <code>Name</code>.
  167. <p>If <code>Name</code> is already registered, the function returns
  168. with the value <code>{already_registered, Pid}</code>. Otherwise, it returns
  169. a "reference" (not necessarily of type <code>reference()</code>) that can be used
  170. to recognize a future message.</p>
  171. <p>When some process <code>P</code> registers as <code>Name</code>, a message on the form
  172. <code>{sysProgReg, Ref, reg, Name, Pid}</code> is sent to each waiting process
  173. (note that Ref will be different for each waiting process.)</p></p>
  174. <h3><a name="clear_await_reg-1">clear_await_reg/1</a></h3>
  175. <p><tt>clear_await_reg(Ref) -&gt; true</tt></p>
  176. <p>Cancel waiting for notification of process registration of a
  177. given name.
  178. <p>This function exits with <code>badarg</code> if Ref does not appear to be
  179. a valid reference returned by <a href="#await_reg-1"><code>await_reg/1</code></a>; otherwise returns
  180. <code>true</code>.</p></p>
  181. <h3><a name="del_counter-1">del_counter/1</a></h3>
  182. <p><tt>del_counter(Name) -&gt; true</tt></p>
  183. <p>Un-publish a counter property for the current process.
  184. </p>
  185. <h3><a name="del_counter-2">del_counter/2</a></h3>
  186. <p><tt>del_counter(Process, Name) -&gt; true</tt></p>
  187. <p>Un-publish a counter property on behalf of <code>Process</code>.
  188. <p>This function is allowed only if permission to delete counters
  189. has been given through <code>Process</code> calling <a href="#grant_access-2"><code>grant_access/2</code></a>.</p>
  190. <p>If permission to delete counters has not been given, this function
  191. exits with <code>access</code>.</p></p>
  192. <h3><a name="del_property-1">del_property/1</a></h3>
  193. <p><tt>del_property(Property) -&gt; true</tt></p>
  194. <p>Un-publishes the property <code>Property</code> for the current process.
  195. <p>If there is no published property <code>Property</code>
  196. (see <a href="#add_property-1"><code>add_property/1</code></a>), for the current process, the function
  197. exits with <code>badarg</code>.</p></p>
  198. <h3><a name="del_property-2">del_property/2</a></h3>
  199. <p><tt>del_property(Process, Property) -&gt; true</tt></p>
  200. <p>Un-publish the property <code>Property</code> on behalf of <code>Process</code>.
  201. <p>This function is allowed only if permission to delete properties
  202. has been given through <code>Process</code> calling <a href="#grant_access-2"><code>grant_access/2</code></a>.</p>
  203. <p>If permission to delete properties has not been given, this function
  204. exits with <code>access</code>.</p></p>
  205. <h3><a name="enable_i-0">enable_i/0</a></h3>
  206. <tt>enable_i() -&gt; term()
  207. </tt>
  208. <h3><a name="first-1">first/1</a></h3>
  209. <p><tt>first(Type::names | properties) -&gt; Key | '$end_of_table'</tt></p>
  210. <p>Analogous to <a href="ets.html#first-1"><code>ets:first/1</code></a>.
  211. <p>The tables corresponding to <code>names</code> and <code>properties</code> both have
  212. <code>ordered_set</code> semantics.</p></p>
  213. <h3><a name="fold_names-3">fold_names/3</a></h3>
  214. <p><tt>fold_names(Fun::function(), Acc, Patterns) -&gt; NewAcc</tt></p>
  215. <p>Similar to <a href="lists.html#foldl-3"><code>lists:foldl/3</code></a>, but based on a list of select
  216. patterns, identifying a sub-set of unique names.
  217. <p>For each matching name, a call is made to
  218. <pre>Fun({Name1,Pid1}, Acc1)</pre>, which is expected to
  219. return <code>NewAcc</code>.</p>
  220. <p><code>Patterns</code> is a list of match specifications on the same form as
  221. that used by <a href="ets.html#select_delete-2"><code>ets:select_delete/2</code></a> and <a href="ets.html#select_count-2"><code>ets:select_count/2</code></a>,
  222. that is:</p>
  223. <pre>
  224. * Patterns = [MatchFunction] | '_'
  225. * MatchFunction = {MatchHead, [Guard], [Result]}
  226. * MatchHead = "Pattern as in ets:match"
  227. * Guard = {"Guardtest name", ...}
  228. * Result = true (if object is to be included)
  229. </pre>
  230. <p>The following expression would return a
  231. list of all registered unique names together with the processes
  232. that registered them:</p>
  233. <pre>
  234. proc:fold_names(fun(X,Acc) -&gt; [X|Acc] end, [], [{'_',[],[true]}])
  235. </pre>
  236. <p>For convenience, the special pattern '_' is also allowed. It is
  237. expanded to <code>[{'_',[],[true]}]</code>.</p>
  238. <p>This function is equivalent to <code>fold_names(Fun,Acc,Patterns,100)</code>,
  239. (see <a href="#fold_names-5"><code>fold_names/5</code></a>.)</p></p>
  240. <h3><a name="fold_names-4">fold_names/4</a></h3>
  241. <p><tt>fold_names(Fun, Acc, Patterns, Limit::integer()) -&gt; NewAcc</tt></p>
  242. <p>Like <a href="#fold_names-3"><code>fold_names/3</code></a>, but works in batches of <code>Limit</code> objects
  243. at a time, in order to improve memory characteristics.
  244. <p><code>fold_names/3</code> uses a default limit of 1 object at a time.</p>
  245. <p>This function is equivalent to
  246. <code>fold_names(Fun,Acc,Patterns,Limit,fun(_) -&gt; true end)</code>,
  247. (see <a href="#fold_names-5"><code>fold_names/5</code></a>.)</p></p>
  248. <h3><a name="fold_names-5">fold_names/5</a></h3>
  249. <p><tt>fold_names(Fun::function(), Acc, Patterns, Limit::integer(), Regulator::function()) -&gt; NewAcc</tt></p>
  250. <p>Like <a href="#fold_names-4"><code>fold_names/4</code></a>, but applies a "Regulator function"
  251. after each batch of objects before proceeding with the next one.
  252. <p>The <code>Regulator</code> function is expected to take the current accumulator
  253. as an argument and return either <code>true</code> (in which case processing
  254. continues), or <code>false</code> (in which case the <code>fold_names/5</code> function breaks
  255. and returns the current accumulator.</p></p>
  256. <h3><a name="fold_properties-3">fold_properties/3</a></h3>
  257. <p><tt>fold_properties(Fun::function(), Acc, Property) -&gt; NewAcc</tt></p>
  258. <p>Similar to <a href="http://www.erlang.org/edoc/doc/stdlib/doc/lists.html#foldl-3"><code>//stdlib/lists:foldl/3</code></a>, but based on a
  259. select pattern on <code>Property</code>, identifying a sub-set of
  260. published properties.
  261. <p>For each matching key, a call is made to
  262. <pre>Fun({Property1,Pid1}, Acc1)</pre>, which is expected to
  263. return <code>NewAcc</code>. Note that, as in <a href="#pids-1"><code>pids/1</code></a>, <code>Property</code>
  264. can be select a pattern. The following expression would return a
  265. list of all published instances of <code>Property</code> together with the processes
  266. that registered them:</p>
  267. <pre>
  268. proc:fold_properties(fun(X,Acc) -&gt; [X|Acc] end, [], '_')
  269. </pre>
  270. <p>This function is equivalent to <code>fold_properties(Fun,Acc,Property,1)</code>,
  271. (see <a href="#fold_properties-4"><code>fold_properties/4</code></a>.) See also <a href="#select_pattern-1"><code>select_pattern/1</code></a>.</p></p>
  272. <h3><a name="fold_properties-4">fold_properties/4</a></h3>
  273. <p><tt>fold_properties(Fun::function(), Acc, Properties::Key, Limit::integer()) -&gt; NewAcc</tt></p>
  274. <p>Like <a href="#fold_properties-3"><code>fold_properties/3</code></a>, but works in batches of <code>Limit</code>
  275. objects at a time, in order to improve raw performance.
  276. <p><code>fold_properties/3</code> uses a default limit of 1 object at a time.</p>
  277. <p>This function is equivalent to
  278. <code>fold_properties(Fun,Acc,Property,Limit,fun(_) -&gt; true end)</code>,
  279. (see <a href="#fold_properties-5"><code>fold_properties/5</code></a>.) See also <a href="#select_pattern-1"><code>select_pattern/1</code></a>.</p></p>
  280. <h3><a name="fold_properties-5">fold_properties/5</a></h3>
  281. <p><tt>fold_properties(Fun::function(), Acc, Property, Limit::integer(), Regulator::function()) -&gt; NewAcc</tt></p>
  282. <p>Like <a href="#fold_properties-4"><code>fold_properties/4</code></a>, but applies a "Regulator function"
  283. after each batch of objects before proceeding with the next one.
  284. <p>The <code>Regulator</code> function is expected to take the current accumulator
  285. as an argument and return either <code>true</code> (in which case processing
  286. continues), or <code>false</code> (in which case the <code>fold_properties/5</code> function
  287. breaks and returns the current accumulator. See also
  288. <a href="#select_pattern-1"><code>select_pattern/1</code></a>.</p></p>
  289. <h3><a name="guards-1">guards/1</a></h3>
  290. <p><tt>guards(Gs::List) -&gt; NewList</tt></p>
  291. <p>Expand a list of <code>select</code> guards, allowing for the pseudo guard
  292. <code>is_counter</code>.
  293. <p>How counter properties can be distinguished from regular properties
  294. internally is not defined in the proc interface. Using this function,
  295. it is however possible to specify a guard test, <code>is_counter</code>, which will
  296. expand to a legal guard. The <code>is_counter</code> test can be combined with the
  297. standard logical operators, <code>not</code>, <code>and</code>, <code>or</code>, <code>orelse</code>, <code>andalso</code>,
  298. and <code>xor</code>.</p>
  299. <p>Example:</p>
  300. <pre>
  301. proc:select_properties(
  302. [{'_', proc:guards([{'not', is_counter}]), [true]}]).
  303. </pre>
  304. <p>will list all published properties that are not counters.</p></p>
  305. <h3><a name="i-1">i/1</a></h3>
  306. <p><tt>i(Options::Option) -&gt; ok</tt>
  307. <ul><li><tt>Option = help | [{Op, Type, Patterns}]</tt></li><li><tt>Op = i | x</tt></li><li><tt>Type = names | properties</tt></li></ul></p>
  308. <p>Like <a href="c.html#i-0"><code>c:i/0</code></a>, but allows for filtering output with
  309. <code>proc</code> names and properties.
  310. <p>Usage: <code>i([{i | x, names | properties, Patterns}])</code>.<br>
  311. calls <code>c:i(Processes)</code> for a subset of all running processes.
  312. <code>{i, Type, Pattern}</code> specifies by name or property which processes
  313. to include. <code>{x, Type, Pattern}</code> specifies which processes to
  314. exclude from the listing. If no <code>{i,T,P}</code> tuples are specified,
  315. all processes are included per default, then reduced by the
  316. <code>{x,T,P}</code> patterns. Multiple tuples are allowed.
  317. <code>Pattern</code> is a match specification where the result head is <code>true</code>.</p>
  318. <p>Note that currently, using <a href="ets.html#fun2ms-1"><code>ets:fun2ms/1</code></a> may have severe impact
  319. on performance if there is a large number of registered names or
  320. keys.</p></p>
  321. <h3><a name="info-1">info/1</a></h3>
  322. <p><tt>info(NameOrPid::Process) -&gt; [{Tag, Info}] | undefined</tt></p>
  323. <p>Like <code>process_info(PidOfProcess)</code>, but with added
  324. proc-related attributes.
  325. <p>This function calls <code>process_info(PidOfProcess)</code>, and adds to the
  326. result the following info items:</p>
  327. <ul>
  328. <li><code>{pid, pid()}</code> -- the pid of the process</li>
  329. <li><code>{names, Names}</code> -- all unique proc names
  330. registered by the process</li>
  331. <li><code>{properties, Props}</code> -- all non-unique properties</li>
  332. </ul></p>
  333. <h3><a name="info-2">info/2</a></h3>
  334. <p><tt>info(NameOrPid::Process, Attr) -&gt; {Attr, Info}</tt></p>
  335. <p>Like <code>process_info(PidOfProcess, Attr)</code> but accepts some
  336. additional attributes.
  337. <p>All attributes supported by <a href="erlang.html#process_info-2"><code>erlang:process_info/2</code></a> are
  338. supported by this function. In addition, the following attributes are
  339. handled:</p>
  340. <ul>
  341. <li><code>pid</code> -- the pid of the process (mainly here for symmetry)</li>
  342. <li><code>names</code> -- all unique names registered in proc by <code>Process</code></li>
  343. <li><code>properties</code> -- all non-unique properties of <code>Process</code></li>
  344. </ul></p>
  345. <h3><a name="is_counter-1">is_counter/1</a></h3>
  346. <p><tt>is_counter(Property) -&gt; true | false</tt></p>
  347. <p>Check whether <code>Property</code> is a counter property.
  348. <p>Counter properties are created through <a href="#add_counter-2"><code>add_counter/2</code></a>, and
  349. behave as normal properties with the following exceptions:</p>
  350. <ul>
  351. <li>A counter property has an integer value attached, which can be
  352. updated using <a href="#update_counter-2"><code>update_counter/2</code></a></li>
  353. <li>Counter properties cannot be replaced using
  354. <a href="#replace_property-2"><code>replace_property/2</code></a></li>
  355. </ul></p>
  356. <h3><a name="is_counter-2">is_counter/2</a></h3>
  357. <p><tt>is_counter(Pid::Process, Property) -&gt; true | false</tt></p>
  358. <p>Check whether <code>Propery</code> registered under <code>Process</code> is a counter
  359. property.
  360. <p><code>Process</code> can be either a pid or a registered name.</p></p>
  361. <h3><a name="is_property-1">is_property/1</a></h3>
  362. <p><tt>is_property(Property) -&gt; true | false</tt></p>
  363. <p>Returns <code>true</code> if <code>Property</code> is a published property of the current
  364. process.</p>
  365. <h3><a name="is_property-2">is_property/2</a></h3>
  366. <p><tt>is_property(Pid::Process, Property) -&gt; true | false</tt></p>
  367. <p>Check whether Property is in fact a property registered with Process.
  368. <p><code>Process</code> can be either a pid or a registered name.</p></p>
  369. <h3><a name="last-1">last/1</a></h3>
  370. <p><tt>last(Type::names | properties) -&gt; Key | '$end_of_table'</tt></p>
  371. <p>Analogous to <a href="ets.html#last-1"><code>ets:last/1</code></a>.
  372. <p>The tables corresponding to <code>names</code> and <code>properties</code> both have
  373. <code>ordered_set</code> semantics.</p></p>
  374. <h3><a name="next-2">next/2</a></h3>
  375. <p><tt>next(Type::names | properties, Prev::Key) -&gt; Key | '$end_of_table'</tt></p>
  376. <p>Analogous to <a href="ets.html#next-2"><code>ets:next/2</code></a>.
  377. <p>The tables corresponding to <code>names</code> and <code>properties</code> both have
  378. <code>ordered_set</code> semantics. The key format of the <code>properties</code> table is
  379. <code>{Property, Pid}</code>, while the key format of the <code>names</code> table is
  380. simply the name. Note that <code>names</code> and <code>properties</code> are not likely
  381. the physical names of the actual tables.</p></p>
  382. <h3><a name="pids-1">pids/1</a></h3>
  383. <p><tt>pids(Property) -&gt; [pid()]</tt></p>
  384. <p>Returns all pids for which a property <code>Property</code> is published.
  385. <p>To be more precise, <code>Property</code> can be any pattern that would be
  386. accepted by <a href="http://www.erlang.org/edoc/doc/stdlib/doc/ets.html#select-2"><code>//stdlib/ets:select/2</code></a>, e.g. '_'</p>
  387. <p>If one imagines an <code>ordered_set ets</code> table <code>Tab</code> where all properties
  388. are stored on the form <code>{{Property,Pid},1}</code>, then calling
  389. this function is equivalent to calling
  390. <pre>ets:select(Tab, [{{{Property,'$1'},'_'}, [], ['$1']}]).</pre></p>
  391. <p>Note that this is also true as regards performance. If the <code>Key</code>
  392. pattern is unbound, the operation will be a linear search.</p></p>
  393. <h3><a name="pids-2">pids/2</a></h3>
  394. <p><tt>pids(Property, Guards::list()) -&gt; [pid()]</tt></p>
  395. <p>Similar to <a href="#pids-1"><code>pids/1</code></a>, but also allowing select guards.
  396. <p>If one imagines an <code>ordered_set ets</code> table <code>Tab</code> where all non-unique
  397. keys are stored on the form <code>{{Property,Pid},1}</code>, then calling
  398. this function is equivalent to calling
  399. <pre>ets:select(Tab, [{{{Property,'$1'},'_'}, Guards, ['$1']}]).</pre>
  400. </p>
  401. <p>Note that this is also true as regards performance. If the <code>Property</code>
  402. pattern is unbound, the operation will be a linear search.</p></p>
  403. <h3><a name="previous-2">previous/2</a></h3>
  404. <p><tt>previous(Type::names | properties, Next::Key) -&gt; Key | '$end_of_table'</tt></p>
  405. <p>Analogous to <a href="ets.html#previous-2"><code>ets:previous/2</code></a>.
  406. <p>The tables corresponding to <code>names</code> and <code>properties</code> both have
  407. <code>ordered_set</code> semantics. The key format of the <code>properties</code> table is
  408. <code>{Property, Pid}</code>, while the key format of the <code>names</code> table is
  409. simply the name. Note that <code>names</code> and <code>properties</code> are not likely
  410. the physical names of the actual tables.</p></p>
  411. <h3><a name="properties_by_pid-1">properties_by_pid/1</a></h3>
  412. <p><tt>properties_by_pid(P::pid()) -&gt; [Property]</tt></p>
  413. <p>Lists all properties for a given process.
  414. </p>
  415. <h3><a name="properties_by_pid-2">properties_by_pid/2</a></h3>
  416. <p><tt>properties_by_pid(P::pid(), KeyPat) -&gt; [Property]</tt></p>
  417. <p>Lists all properties for a given process that match the pattern
  418. KeyPat.
  419. <p>Equivalend to <code>properties_by_pid(P, KeyPat, [])</code>.</p></p>
  420. <h3><a name="properties_by_pid-3">properties_by_pid/3</a></h3>
  421. <p><tt>properties_by_pid(P::pid(), KeyPat, Guards) -&gt; [Property]</tt></p>
  422. <p>Like <a href="#properties_by_pid-2"><code>properties_by_pid/2</code></a>, but with an added list of guards.
  423. <p>The Guards list may be one returned from the function <a href="#guards-1"><code>guards/1</code></a>.
  424. </p></p>
  425. <h3><a name="read_counter-1">read_counter/1</a></h3>
  426. <p><tt>read_counter(Name) -&gt; integer()</tt></p>
  427. <p>Read the value of a counter property for the current process.
  428. </p>
  429. <h3><a name="read_counter-2">read_counter/2</a></h3>
  430. <p><tt>read_counter(Pid::Process, Name) -&gt; integer()</tt></p>
  431. <p>Read the value of a counter property published by <code>Process</code>.
  432. </p>
  433. <h3><a name="reg-1">reg/1</a></h3>
  434. <p><tt>reg(Pid::Name) -&gt; true</tt></p>
  435. <p>Register a unique <code>Name</code>. Returns <code>true</code> or exits.
  436. <p>This function differs from <code>erlang:register(Name,Pid)</code> in
  437. the following ways:</p>
  438. <ul>
  439. <li>Pid is implicit: always the current process.</li>
  440. <li>Name can be any term (except a pid or '_'), not just an atom.</li>
  441. <li>A process can be registered under several unique names.</li>
  442. </ul></p>
  443. <h3><a name="replace_property-2">replace_property/2</a></h3>
  444. <p><tt>replace_property(OldProp::OldProperty, NewProperty) -&gt; true</tt></p>
  445. <p>Equivalent to del_property(OldProperty), add_property(NewProperty),
  446. but much more efficient.
  447. <p>If <code>OldProperty</code> is not a published property of the current process
  448. (see <a href="#add_property-1"><code>add_property/1</code></a>), the function exits with <code>badarg</code>.</p>
  449. <p>One could use properties as a "published process dictionary",
  450. e.g. by replacing <code>put(Tag,Value)</code> with
  451. <code>proc:add_property({Tag,Value})</code>, and <code>get(Tag)</code> with (roughly)
  452. <code>proc:properties_by_pid(self(),Tag)</code>.
  453. While this would be somewhat less efficient than the built-in process
  454. dictionary, it has the advantage of allowing other processes to key
  455. on process meta-data in a much more efficient and disciplined way than
  456. <code>{_,Dict} = process_info(Pid,dictionary), lists:keysearch(Tag,1,Dict)</code>
  457. (Which makes no distinction between public and private data, and therefore
  458. is rightfully frowned upon, and hopefully never attempted.)"</p>
  459. <p><i>Note:</i> This function does not work on counter properties.</p></p>
  460. <h3><a name="replace_property-3">replace_property/3</a></h3>
  461. <p><tt>replace_property(Process, OldProperty, NewProperty) -&gt; true</tt></p>
  462. <p>Replace <code>OldProperty</code> with <code>NewProperty</code> on behalf of <code>Process</code>.
  463. <p>This function is allowed only if permission to replace properties
  464. has been given through <code>Process</code> calling <a href="#grant_access-2"><code>grant_access/2</code></a>.</p>
  465. <p>If permission to replace properties has not been given, this function
  466. exits with <code>access</code>.</p></p>
  467. <h3><a name="select-1">select/1</a></h3>
  468. <p><tt>select(Continuation) -&gt; {[Obj], NewContinuation} | '$end_of_table'</tt></p>
  469. <p>Analogous to <a href="ets.html#select-1"><code>ets:select/1</code></a>.
  470. <p>This function is intended to be called with a <code>Continuation</code>
  471. returned from <a href="#select_names-1"><code>select_names/1</code></a> or <a href="#select_properties-2"><code>select_properties/2</code></a>.</p></p>
  472. <h3><a name="select_fold_properties-3">select_fold_properties/3</a></h3>
  473. <p><tt>select_fold_properties(Fun, Acc, Patterns) -&gt; NewAcc</tt></p>
  474. <p>Like <a href="#fold_properties-3"><code>fold_properties/3</code></a> but more flexible as it allows
  475. for combining several patterns into one query.
  476. <p><code>Patterns</code> is composed as for <a href="#select_properties-1"><code>select_properties/1</code></a>.</p></p>
  477. <h3><a name="select_fold_properties-4">select_fold_properties/4</a></h3>
  478. <p><tt>select_fold_properties(Fun, Acc, Patterns, Limit) -&gt; NewAcc</tt></p>
  479. <p>Like <a href="#select_fold_properties-3"><code>select_fold_properties/3</code></a>, but works in batches of <code>Limit</code>
  480. objects at a time, in order to improve raw performance.
  481. <p><code>select_fold_properties/3</code> uses a default limit of 1 object at a
  482. time.</p>
  483. <p>This function is equivalent to
  484. <code>select_fold_properties(Fun,Acc,Patterns,Limit,fun(_) -&gt; true end)</code>,
  485. (see <a href="#select_fold_properties-5"><code>select_fold_properties/5</code></a>.)</p></p>
  486. <h3><a name="select_fold_properties-5">select_fold_properties/5</a></h3>
  487. <p><tt>select_fold_properties(Fun::function(), Acc, Patterns::Property, Limit::integer(), Regulator::function()) -&gt; NewAcc</tt></p>
  488. <p>Like <a href="#select_fold_properties-4"><code>select_fold_properties/4</code></a>, but applies a
  489. "Regulator function"
  490. after each batch of objects before proceeding with the next one.
  491. <p>The <code>Regulator</code> function is expected to take the current accumulator
  492. as an argument and return either <code>true</code> (in which case processing
  493. continues), or <code>false</code> (in which case the <code>select_fold_properties/5</code>
  494. function breaks and returns the current accumulator.</p></p>
  495. <h3><a name="select_names-1">select_names/1</a></h3>
  496. <p><tt>select_names(Patterns) -&gt; {Objs, Continuation} | '$end_of_table'</tt></p>
  497. <p>Returns <code>{Name,Pid}</code> objects one at a time based on
  498. a given selection of all registered unique names.
  499. <p><code>Patterns</code> can be written as follows:</p>
  500. <pre>
  501. * Patterns = [MatchFunction] | '_'
  502. * MatchFunction = {MatchHead, [Guard], [Result]}
  503. * MatchHead = "Pattern as in ets:match"
  504. * Guard = {"Guardtest name", ...}
  505. * Result = true (if object is to be included)
  506. </pre>
  507. <p>or generated using <a href="#select_pattern-1"><code>select_pattern/1</code></a> or
  508. <a href="#select_pattern-2"><code>select_pattern/2</code></a>.</p>
  509. <p>The function is <i>almost</i> equivalent to
  510. <code>ets:select(Tab,Patterns, 100)</code> on an <code>ordered_set</code> table <code>Tab</code>
  511. with the following representation:</p>
  512. <pre>{{Key, Value}, Pid}</pre>
  513. <p>The difference compared to <code>ets:select/3</code> is the <code>Result</code> expression.
  514. In this function, <code>Result</code> is expected to be 'true' for those
  515. objects that are to be included.</p>
  516. <p>For convenience, the special pattern '_' is accepted,
  517. and expanded to <code>[{'_', [], [true]}]</code>.</p>
  518. <p>Any other patterns are ignored.</p>
  519. <p>The <code>Continuation</code> returned can be used when calling <a href="#select-1"><code>select/1</code></a>
  520. in order to continue processing.</p></p>
  521. <h3><a name="select_names-2">select_names/2</a></h3>
  522. <p><tt>select_names(Patterns0::Patterns, Limit) -&gt; {Objs, Continuation} | '$end_of_table'</tt></p>
  523. <p>Like <a href="#select_names-1"><code>select_names/1</code></a>, but works in batches of <code>Limit</code>
  524. objects at a time, in order to improve raw performance.
  525. </p>
  526. <h3><a name="select_pattern-1">select_pattern/1</a></h3>
  527. <p><tt>select_pattern(What) -&gt; Patterns</tt></p>
  528. <p>Helper function to generate select patterns from the more
  529. intuitive patterns <code>Property</code> (or <code>Name</code>, as it works equally for names).
  530. <p>The return value from this function can be used in e.g.
  531. <a href="#select_properties-1"><code>select_properties/1</code></a>, <a href="#select_properties-2"><code>select_properties/2</code></a>,
  532. <a href="#select_fold_properties-3"><code>select_fold_properties/3</code></a>,
  533. <a href="#select_fold_properties-4"><code>select_fold_properties/4</code></a> or <a href="#select_fold_properties-5"><code>select_fold_properties/5</code></a>,
  534. or similarly, <a href="#select_names-1"><code>select_names/1</code></a>, <a href="#select_names-2"><code>select_names/2</code></a>,
  535. <a href="#select_fold_names-3"><code>select_fold_names/3</code></a>, <a href="#select_fold_names-4"><code>select_fold_names/4</code></a>, or
  536. <a href="#select_fold_names-5"><code>select_fold_names/5</code></a>.</p>
  537. <p><code>Patterns</code> is a list of match specifications on the same form as
  538. that used by <a href="http://www.erlang.org/edoc/doc/stdlib/doc/ets.html#select_delete-2"><code>//stdlib/ets:select_delete/2</code></a> and
  539. <a href="http://www.erlang.org/edoc/doc/stdlib/doc/ets.html#select_count-2"><code>//stdlib/ets:select_count/2</code></a>,
  540. that is:</p>
  541. <pre>
  542. * Patterns = [MatchFunction] | '_'
  543. * MatchFunction = {MatchHead, [Guard], [Result]}
  544. * MatchHead = "Pattern as in ets:match"
  545. * Guard = {"Guardtest name", ...}
  546. * Result = true (if object is to be included)
  547. </pre></p>
  548. <h3><a name="select_pattern-2">select_pattern/2</a></h3>
  549. <p><tt>select_pattern(What, Guards) -&gt; Patterns</tt></p>
  550. <p>As <a href="#select_pattern-1"><code>select_pattern/1</code></a>, but with the option to add Guard
  551. expressions.
  552. </p>
  553. <h3><a name="select_properties-1">select_properties/1</a></h3>
  554. <p><tt>select_properties(Patterns) -&gt; {Objs, Continuation} | '$end_of_table'</tt></p>
  555. <p>Returns <code>{Property,Pid}</code> objects one at a time based on
  556. a given selection of all registered instances of <code>Key</code>.
  557. <p><code>Patterns</code> can be written as follows:</p>
  558. <pre>
  559. * Patterns = [MatchFunction] | '_'
  560. * MatchFunction = {MatchHead, [Guard], [Result]}
  561. * MatchHead = "Pattern as in ets:match"
  562. * Guard = {"Guardtest name", ...}
  563. * Result = true (if object is to be included)
  564. </pre>
  565. <p>or generated using <a href="#select_pattern-1"><code>select_pattern/1</code></a> or
  566. <a href="#select_pattern-2"><code>select_pattern/2</code></a>.</p>
  567. <p>For convenience, the special pattern '_' is also accepted.
  568. It expands to <code>[{'_', [], [true]}]</code>.</p>
  569. <p>The <code>Continuation</code> returned can be used when calling <a href="#select-1"><code>select/1</code></a>
  570. in order to continue processing.</p></p>
  571. <h3><a name="select_properties-2">select_properties/2</a></h3>
  572. <p><tt>select_properties(Patterns0::Patterns, Limit::integer()) -&gt; {Objs, Continuation} | '$end_of_table'</tt></p>
  573. <p>Like <a href="#select_properties-1"><code>select_properties/1</code></a> but works in batches of <code>Limit</code>
  574. objects at a time in order to improve raw performance.
  575. </p>
  576. <h3><a name="send-2">send/2</a></h3>
  577. <p><tt>send(Pid::Name, Msg) -&gt; Msg</tt></p>
  578. <p>Analogous to <code>Name ! Msg</code>, except that send({Node,Dest}, Msg)
  579. will be interpreted as 'send to the local process registered as
  580. {Node, Dest}'. If Name is a pid, this function will send the message
  581. to the process with process identifier Name (recall that it is not
  582. possible to register a pid as a unique name in proc.)</p>
  583. <h3><a name="set_access-1">set_access/1</a></h3>
  584. <p><tt>set_access(Access::[{Action, Processes, Ops}]) -&gt; true</tt>
  585. <ul><li><tt>Action = grant | revoke</tt></li><li><tt>Ops = [Op]</tt></li><li><tt>Op = add_property | replace_property | del_property | properties | add_counter | update_counter | del_counter | counters</tt></li></ul></p>
  586. <p>Control the ability of Processes to perform certain functions
  587. on behalf of the current process.
  588. <p><code>Op</code> must be one of</p>
  589. <ul>
  590. <li><code>add_property</code></li>
  591. <li><code>replace_property</code></li>
  592. <li><code>del_property</code></li>
  593. <li><code>properties</code> (perform all operations on properties)</li>
  594. <li><code>add_counter</code></li>
  595. <li><code>update_counter</code></li>
  596. <li><code>del_counter</code></li>
  597. <li><code>counters</code> (perform all operations on counters)</li>
  598. </ul>
  599. <p><code>Processes</code> is a list of registered names and/or pids.</p>
  600. <p>Example:</p><pre>
  601. set_access([{grant, ["foo","bar"], [update_counter]},
  602. {revoke, ["baz"], [properties]}])</pre>
  603. <p>Allows the processes registered as <code>"foo"</code> and <code>"bar"</code> to update
  604. counters, and makes sure that <code>"baz"</code> is no longer able to add, delete
  605. or replace properties.</p></p>
  606. <h3><a name="start_link-0">start_link/0</a></h3>
  607. <p><tt>start_link() -&gt; {ok, pid()}</tt></p>
  608. <p>Starts the proc server.
  609. <p><code>proc</code> assumes that the <code>proc_tabs</code> module is available, and that
  610. the <code>proc_tabs</code> process is running.</p></p>
  611. <h3><a name="unreg-1">unreg/1</a></h3>
  612. <p><tt>unreg(Name) -&gt; true</tt></p>
  613. <p>Unregister <code>Name</code>
  614. <p>This function exits if <code>Name</code> isn't registered to the current
  615. process.</p></p>
  616. <h3><a name="update_counter-2">update_counter/2</a></h3>
  617. <p><tt>update_counter(Name, Incr) -&gt; integer()</tt></p>
  618. <p>Update the counter attribute of a counter property.
  619. <p>This function only works on counter properties. The <code>Incr</code> argument
  620. is passed as-is to <a href="http://www.erlang.org/edoc/doc/stlib/doc/ets.html#update_counter-3"><code>//stlib/ets:update_counter/3</code></a>.
  621. If a complex option, such as <code>{Pos, Incr}</code> is used,
  622. <code>Pos</code> must be equal to 2.</p></p>
  623. <h3><a name="update_counter-3">update_counter/3</a></h3>
  624. <p><tt>update_counter(Process, Name, Value::Incr) -&gt; integer()</tt></p>
  625. <p>Update counter attribute on behalf of <code>Process</code>.
  626. <p>This function is allowed only if permission to update counters
  627. has been given through <code>Process</code> calling <a href="#grant_access-2"><code>grant_access/2</code></a>.</p>
  628. <p>If permission to update counters has not been given, this function
  629. exits with <code>access</code>.</p></p>
  630. <h3><a name="where-1">where/1</a></h3>
  631. <p><tt>where(Name) -&gt; pid() | undefined</tt></p>
  632. <p>Analogous to <code>erlang:whereis(Name)</code>
  633. </p>
  634. </body>
  635. </html>