Skip to content
Browse files

more accurate exceptions

  • Loading branch information...
1 parent e99363c commit d9314f347e2a0f224e26a8b50827a4711fe92f54 @uwiger uwiger committed with Jan 11, 2012
Showing with 244 additions and 152 deletions.
  1. +47 −47 doc/gproc.md
  2. +1 −1 doc/gproc_dist.md
  3. +2 −2 doc/gproc_lib.md
  4. +2 −2 doc/gproc_monitor.md
  5. +165 −100 src/gproc.erl
  6. +27 −0 src/gproc_int.hrl
View
94 doc/gproc.md
@@ -56,7 +56,7 @@ will improve performance.
-<pre>context() = {<a href="#type-scope">scope()</a>, <a href="#type-type">type()</a>} | <a href="#type-type">type()</a></pre>
+<pre>context() = {[scope()](#type-scope), [type()](#type-type)} | [type()](#type-type)</pre>
{'all','all'} is the default
@@ -67,39 +67,39 @@ will improve performance.
-<pre>headpat() = {<a href="#type-keypat">keypat()</a>, <a href="#type-pidpat">pidpat()</a>, ValPat}</pre>
+<pre>headpat() = {[keypat()](#type-keypat), [pidpat()](#type-pidpat), ValPat}</pre>
###<a name="type-key">key()</a>##
-<pre>key() = {<a href="#type-type">type()</a>, <a href="#type-scope">scope()</a>, any()}</pre>
+<pre>key() = {[type()](#type-type), [scope()](#type-scope), any()}</pre>
###<a name="type-keypat">keypat()</a>##
-<pre>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()}</pre>
+<pre>keypat() = {[sel_type()](#type-sel_type) | [sel_var()](#type-sel_var), l | g | [sel_var()](#type-sel_var), any()}</pre>
###<a name="type-pidpat">pidpat()</a>##
-<pre>pidpat() = pid() | <a href="#type-sel_var">sel_var()</a></pre>
+<pre>pidpat() = pid() | [sel_var()](#type-sel_var)</pre>
###<a name="type-reg_id">reg_id()</a>##
-<pre>reg_id() = {<a href="#type-type">type()</a>, <a href="#type-scope">scope()</a>, any()}</pre>
+<pre>reg_id() = {[type()](#type-type), [scope()](#type-scope), any()}</pre>
@@ -118,7 +118,7 @@ l = local registration; g = global registration
-<pre>sel_pattern() = [{<a href="#type-headpat">headpat()</a>, Guards, Prod}]</pre>
+<pre>sel_pattern() = [{[headpat()](#type-headpat), Guards, Prod}]</pre>
@@ -134,7 +134,7 @@ l = local registration; g = global registration
-<pre>sel_type() = <a href="#type-type">type()</a> | names | props | counters | aggr_counters</pre>
+<pre>sel_type() = [type()](#type-type) | names | props | counters | aggr_counters</pre>
@@ -161,7 +161,7 @@ a = aggregate_counter
-<pre>unique_id() = {n | a, <a href="#type-scope">scope()</a>, any()}</pre>
+<pre>unique_id() = {n | a, [scope()](#type-scope), any()}</pre>
<a name="index"></a>
##Function Index##
@@ -303,7 +303,7 @@ Registers a local shared (unique) counter.<a name="audit_process-1"></a>
-<pre>await(Key::<a href="#type-key">key()</a>) -> {pid(), Value}</pre>
+<pre>await(Key::[key()](#type-key)) -&gt; {pid(), Value}</pre>
<br></br>
@@ -316,7 +316,7 @@ Equivalent to [`await(Key, infinity)`](#await-2).<a name="await-2"></a>
-<pre>await(Key::<a href="#type-key">key()</a>, Timeout) -> {pid(), Value}</pre>
+<pre>await(Key::[key()](#type-key), Timeout) -&gt; {pid(), Value}</pre>
<ul class="definitions"><li><pre>Timeout = integer() | infinity</pre></li></ul>
@@ -334,7 +334,7 @@ registered (the difference: await/2 also returns the value).<a name="cancel_wait
-<pre>cancel_wait(Key::<a href="#type-key">key()</a>, Ref) -> ok</pre>
+<pre>cancel_wait(Key::[key()](#type-key), Ref) -&gt; ok</pre>
<ul class="definitions"><li><pre>Ref = all | reference()</pre></li></ul>
@@ -369,7 +369,7 @@ are canceled.<a name="cancel_wait_or_monitor-1"></a>
-<pre>demonitor(Key::<a href="#type-key">key()</a>, Ref::reference()) -> ok</pre>
+<pre>demonitor(Key::[key()](#type-key), Ref::reference()) -&gt; ok</pre>
<br></br>
@@ -384,7 +384,7 @@ set on a unique name. This function always succeeds given legal input.<a name="f
-<pre>first(Context::<a href="#type-context">context()</a>) -> <a href="#type-key">key()</a> | '$end_of_table'</pre>
+<pre>first(Context::[context()](#type-context)) -&gt; [key()](#type-key) | '$end_of_table'</pre>
<br></br>
@@ -402,7 +402,7 @@ The registry behaves as an ordered_set table.<a name="get_env-3"></a>
-<pre>get_env(Scope::<a href="#type-scope">scope()</a>, App::atom(), Key::atom()) -> term()</pre>
+<pre>get_env(Scope::[scope()](#type-scope), App::atom(), Key::atom()) -&gt; term()</pre>
<br></br>
@@ -415,8 +415,8 @@ Equivalent to [`get_env(Scope, App, Key, [app_env])`](#get_env-4).<a name="get_e
-<pre>get_env(Scope::<a href="#type-scope">scope()</a>, App::atom(), Key::atom(), Strategy) -> term()</pre>
-<ul class="definitions"><li><pre>Strategy = [Alternative]</pre></li><li><pre>Alternative = app_env | os_env | inherit | {inherit, pid()} | {inherit, <a href="#type-unique_id">unique_id()</a>} | init_arg | {mnesia, ActivityType, Oid, Pos} | {default, term()} | error</pre></li></ul>
+<pre>get_env(Scope::[scope()](#type-scope), App::atom(), Key::atom(), Strategy) -&gt; term()</pre>
+<ul class="definitions"><li><pre>Strategy = [Alternative]</pre></li><li><pre>Alternative = app_env | os_env | inherit | {inherit, pid()} | {inherit, &lt;a href="#type-unique_id"&gt;unique_id()&lt;/a&gt;} | init_arg | {mnesia, ActivityType, Oid, Pos} | {default, term()} | error</pre></li></ul>
@@ -475,7 +475,7 @@ e.g. `get_env(l, mnesia, dir, [app_env, error])`.<a name="get_set_env-3"></a>
-<pre>get_set_env(Scope::<a href="#type-scope">scope()</a>, App::atom(), Key::atom()) -> term()</pre>
+<pre>get_set_env(Scope::[scope()](#type-scope), App::atom(), Key::atom()) -&gt; term()</pre>
<br></br>
@@ -488,7 +488,7 @@ Equivalent to [`get_set_env(Scope, App, Key, [app_env])`](#get_set_env-4).<a nam
-<pre>get_set_env(Scope::<a href="#type-scope">scope()</a>, App::atom(), Key::atom(), Strategy) -> Value</pre>
+<pre>get_set_env(Scope::[scope()](#type-scope), App::atom(), Key::atom(), Strategy) -&gt; Value</pre>
<br></br>
@@ -545,7 +545,7 @@ will be read.<a name="give_away-2"></a>
-<pre>give_away(From::<a href="#type-key">key()</a>, To::pid() | <a href="#type-key">key()</a>) -> undefined | pid()</pre>
+<pre>give_away(From::[key()](#type-key), To::pid() | [key()](#type-key)) -&gt; undefined | pid()</pre>
<br></br>
@@ -650,7 +650,7 @@ same as [`http://www.erlang.org/doc/man/erlang.html#process_info-2`](http://www.
-<pre>last(Context::<a href="#type-context">context()</a>) -> <a href="#type-key">key()</a> | '$end_of_table'</pre>
+<pre>last(Context::[context()](#type-context)) -&gt; [key()](#type-key) | '$end_of_table'</pre>
<br></br>
@@ -808,7 +808,7 @@ Lookup the Pid stored with a key.
-<pre>lookup_pids(Key::<a href="#type-key">key()</a>) -> [pid()]</pre>
+<pre>lookup_pids(Key::[key()](#type-key)) -&gt; [pid()]</pre>
<br></br>
@@ -841,7 +841,7 @@ Lookup the value stored with a key.
-<pre>lookup_values(Key::<a href="#type-key">key()</a>) -> [{pid(), Value}]</pre>
+<pre>lookup_values(Key::[key()](#type-key)) -&gt; [{pid(), Value}]</pre>
<br></br>
@@ -860,7 +860,7 @@ object, the return value can be a list of any length.<a name="monitor-1"></a>
-<pre>monitor(Key::<a href="#type-key">key()</a>) -> reference()</pre>
+<pre>monitor(Key::[key()](#type-key)) -&gt; reference()</pre>
<br></br>
@@ -881,7 +881,7 @@ If the name is not yet registered, the same message is sent immediately.<a name=
-<pre>mreg(T::<a href="#type-type">type()</a>, X2::<a href="#type-scope">scope()</a>, KVL::[{Key::any(), Value::any()}]) -> true</pre>
+<pre>mreg(T::[type()](#type-type), C::[scope()](#type-scope), KVL::[{Key::any(), Value::any()}]) -&gt; true</pre>
<br></br>
@@ -900,7 +900,7 @@ or none are.<a name="munreg-3"></a>
-<pre>munreg(T::<a href="#type-type">type()</a>, X2::<a href="#type-scope">scope()</a>, L::[Key::any()]) -> true</pre>
+<pre>munreg(T::[type()](#type-type), C::[scope()](#type-scope), L::[Key::any()]) -&gt; true</pre>
<br></br>
@@ -918,7 +918,7 @@ repeatedly.<a name="nb_wait-1"></a>
-<pre>nb_wait(Key::<a href="#type-key">key()</a>) -> Ref</pre>
+<pre>nb_wait(Key::[key()](#type-key)) -&gt; Ref</pre>
<br></br>
@@ -933,7 +933,7 @@ The caller can expect to receive a message,
-<pre>next(Context::<a href="#type-context">context()</a>, Key::<a href="#type-key">key()</a>) -> <a href="#type-key">key()</a> | '$end_of_table'</pre>
+<pre>next(Context::[context()](#type-context), Key::[key()](#type-key)) -&gt; [key()](#type-key) | '$end_of_table'</pre>
<br></br>
@@ -951,7 +951,7 @@ The registry behaves as an ordered_set table.<a name="prev-2"></a>
-<pre>prev(Context::<a href="#type-context">context()</a>, Key::<a href="#type-key">key()</a>) -> <a href="#type-key">key()</a> | '$end_of_table'</pre>
+<pre>prev(Context::[context()](#type-context), Key::[key()](#type-key)) -&gt; [key()](#type-key) | '$end_of_table'</pre>
<br></br>
@@ -969,7 +969,7 @@ The registry behaves as an ordered_set table.<a name="reg-1"></a>
-<pre>reg(Key::<a href="#type-key">key()</a>) -> true</pre>
+<pre>reg(Key::[key()](#type-key)) -&gt; true</pre>
<br></br>
@@ -982,7 +982,7 @@ Equivalent to [`reg(Key, default(Key))`](#reg-2).<a name="reg-2"></a>
-<pre>reg(Key::<a href="#type-key">key()</a>, Value) -> true</pre>
+<pre>reg(Key::[key()](#type-key), Value) -&gt; true</pre>
<br></br>
@@ -999,7 +999,7 @@ Register a name or property for the current process
-<pre>reg_shared(Key::<a href="#type-key">key()</a>) -> true</pre>
+<pre>reg_shared(Key::[key()](#type-key)) -&gt; true</pre>
<br></br>
@@ -1017,7 +1017,7 @@ Register a resource, but don't tie it to a particular process.
-<pre>reg_shared(Key::<a href="#type-key">key()</a>, Value) -> true</pre>
+<pre>reg_shared(Key::[key()](#type-key), Value) -&gt; true</pre>
<br></br>
@@ -1044,7 +1044,7 @@ an aggregated counter which is owned by a process.<a name="register_name-2"></a>
-<pre>register_name(Name::<a href="#type-key">key()</a>, Pid::pid()) -> yes | no</pre>
+<pre>register_name(Name::[key()](#type-key), Pid::pid()) -&gt; yes | no</pre>
<br></br>
@@ -1090,7 +1090,7 @@ see http://www.erlang.org/doc/man/ets.html#select-1<a name="select-2"></a>
-<pre>select(Context::<a href="#type-context">context()</a>, Pat::<a href="#type-sel_pattern">sel_pattern()</a>) -> [{Key, Pid, Value}]</pre>
+<pre>select(Context::[context()](#type-context), Pat::[sel_pattern()](#type-sel_pattern)) -&gt; [{Key, Pid, Value}]</pre>
<br></br>
@@ -1108,7 +1108,7 @@ but the select patterns are transformed appropriately.<a name="select-3"></a>
-<pre>select(Context::<a href="#type-context">context()</a>, Pat::<a href="#type-sel_patten">sel_patten()</a>, Limit::integer()) -> {[Match], Continuation} | '$end_of_table'</pre>
+<pre>select(Context::[context()](#type-context), Pat::[sel_patten()](#type-sel_patten), Limit::integer()) -&gt; {[Match], Continuation} | '$end_of_table'</pre>
<br></br>
@@ -1125,7 +1125,7 @@ See [`http://www.erlang.org/doc/man/ets.html#select-3`](http://www.erlang.org/do
-<pre>select_count(Pat::<a href="#type-select_pattern">select_pattern()</a>) -> [<a href="#type-sel_object">sel_object()</a>]</pre>
+<pre>select_count(Pat::[select_pattern()](#type-select_pattern)) -&gt; [[sel_object()](#type-sel_object)]</pre>
<br></br>
@@ -1138,7 +1138,7 @@ Equivalent to [`select_count(all, Pat)`](#select_count-2).<a name="select_count-
-<pre>select_count(Context::<a href="#type-context">context()</a>, Pat::<a href="#type-sel_pattern">sel_pattern()</a>) -> [{Key, Pid, Value}]</pre>
+<pre>select_count(Context::[context()](#type-context), Pat::[sel_pattern()](#type-sel_pattern)) -&gt; [{Key, Pid, Value}]</pre>
<br></br>
@@ -1156,7 +1156,7 @@ but the select patterns are transformed appropriately.<a name="send-2"></a>
-<pre>send(Key::<a href="#type-key">key()</a>, Msg::any()) -> Msg</pre>
+<pre>send(Key::[key()](#type-key), Msg::any()) -&gt; Msg</pre>
<br></br>
@@ -1176,7 +1176,7 @@ property), Msg will be send to all processes that have such an object.<a name="s
-<pre>set_env(Scope::<a href="#type-scope">scope()</a>, App::atom(), Key::atom(), Value::term(), Strategy) -> Value</pre>
+<pre>set_env(Scope::[scope()](#type-scope), App::atom(), Key::atom(), Value::term(), Strategy) -&gt; Value</pre>
<ul class="definitions"><li><pre>Strategy = [Alternative]</pre></li><li><pre>Alternative = app_env | os_env | {os_env, VAR} | {mnesia, ActivityType, Oid, Pos}</pre></li></ul>
@@ -1202,7 +1202,7 @@ to `undefined`.<a name="set_value-2"></a>
-<pre>set_value(Key::<a href="#type-key">key()</a>, Value) -> true</pre>
+<pre>set_value(Key::[key()](#type-key), Value) -&gt; true</pre>
<br></br>
@@ -1256,7 +1256,7 @@ Equivalent to [`table({all, all})`](#table-1).<a name="table-1"></a>
-<pre>table(Context::<a href="#type-context">context()</a>) -> any()</pre>
+<pre>table(Context::[context()](#type-context)) -&gt; any()</pre>
<br></br>
@@ -1269,7 +1269,7 @@ Equivalent to [`table(Context, [])`](#table-2).<a name="table-2"></a>
-<pre>table(Context::<a href="#type-context">context()</a>, Opts) -> any()</pre>
+<pre>table(Context::[context()](#type-context), Opts) -&gt; any()</pre>
<br></br>
@@ -1284,7 +1284,7 @@ See [`http://www.erlang.org/doc/man/qlc.html`](http://www.erlang.org/doc/man/qlc
-<pre>unreg(Key::<a href="#type-key">key()</a>) -> true</pre>
+<pre>unreg(Key::[key()](#type-key)) -&gt; true</pre>
<br></br>
@@ -1297,7 +1297,7 @@ Unregister a name or property.<a name="unreg_shared-1"></a>
-<pre>unreg_shared(Key::<a href="#type-key">key()</a>) -> true</pre>
+<pre>unreg_shared(Key::[key()](#type-key)) -&gt; true</pre>
<br></br>
@@ -1321,7 +1321,7 @@ Equivalent to `unreg / 1`.<a name="update_counter-2"></a>
-<pre>update_counter(Key::<a href="#type-key">key()</a>, Incr::integer()) -> integer()</pre>
+<pre>update_counter(Key::[key()](#type-key), Incr::integer()) -&gt; integer()</pre>
<br></br>
@@ -1349,7 +1349,7 @@ will fail if the type of object referred to by Key is not a counter.<a name="upd
-<pre>where(Key::<a href="#type-key">key()</a>) -> pid()</pre>
+<pre>where(Key::[key()](#type-key)) -&gt; pid()</pre>
<br></br>
View
2 doc/gproc_dist.md
@@ -10,7 +10,7 @@ Extended process registry.
-__Behaviours:__ [`gen_leader`](/Users/uwiger/FL/git/gproc/deps/gen_leader/doc/gen_leader.md).
+__Behaviours:__ [`gen_leader`](/Users/uwiger/ETC/git/gproc/deps/gen_leader/doc/gen_leader.md).
__Authors:__ Ulf Wiger ([`ulf.wiger@erlang-solutions.com`](mailto:ulf.wiger@erlang-solutions.com)).<a name="description"></a>
View
4 doc/gproc_lib.md
@@ -82,7 +82,7 @@ For a detailed description, see gproc/doc/erlang07-wiger.pdf.<a name="index"></a
-<pre>insert_many(T::<a href="#type-type">type()</a>, Scope::<a href="#type-scope">scope()</a>, KVL::[{<a href="#type-key">key()</a>, any()}], Pid::pid()) -> {true, list()} | false</pre>
+<pre>insert_many(T::[type()](#type-type), Scope::[scope()](#type-scope), KVL::[{[key()](#type-key), any()}], Pid::pid()) -&gt; {true, list()} | false</pre>
<br></br>
@@ -93,7 +93,7 @@ For a detailed description, see gproc/doc/erlang07-wiger.pdf.<a name="index"></a
-<pre>insert_reg(K::<a href="#type-key">key()</a>, Value::any(), Pid::pid() | shared, Scope::<a href="#type-scope">scope()</a>) -> boolean()</pre>
+<pre>insert_reg(K::[key()](#type-key), Value::any(), Pid::pid() | shared, Scope::[scope()](#type-scope)) -&gt; boolean()</pre>
<br></br>
View
4 doc/gproc_monitor.md
@@ -52,7 +52,7 @@ Starts the server
-<pre>subscribe(Key::<a href="#type-key">key()</a>) -> ok</pre>
+<pre>subscribe(Key::[key()](#type-key)) -&gt; ok</pre>
<br></br>
@@ -78,7 +78,7 @@ sent immediately, indicating the current status of the name.<a name="unsubscribe
-<pre>unsubscribe(Key::<a href="#type-key">key()</a>) -> ok</pre>
+<pre>unsubscribe(Key::[key()](#type-key)) -&gt; ok</pre>
<br></br>
View
265 src/gproc.erl
@@ -138,7 +138,7 @@
%% this shouldn't be necessary
-export([audit_process/1]).
-
+-include("gproc_int.hrl").
-include("gproc.hrl").
-include_lib("eunit/include/eunit.hrl").
@@ -149,7 +149,7 @@
-define(CHK_DIST,
case whereis(gproc_dist) of
undefined ->
- erlang:error(local_only);
+ ?THROW(local_only);
_ ->
ok
end).
@@ -174,38 +174,38 @@ start_link() ->
%% @doc Registers a local (unique) name. @equiv reg({n,l,Name})
%% @end
%%
-add_local_name(Name) -> reg({n,l,Name}, undefined).
+add_local_name(Name) -> ?CATCH(reg1({n,l,Name}, undefined), [Name]).
%% spec(Name::any()) -> true
%%
%% @doc Registers a global (unique) name. @equiv reg({n,g,Name})
%% @end
%%
-add_global_name(Name) -> reg({n,g,Name}, undefined).
+add_global_name(Name) -> ?CATCH(reg1({n,g,Name}, undefined), [Name]).
%% spec(Name::any(), Value::any()) -> true
%%
%% @doc Registers a local (non-unique) property. @equiv reg({p,l,Name},Value)
%% @end
%%
-add_local_property(Name , Value) -> reg({p,l,Name}, Value).
+add_local_property(Name , Value) -> ?CATCH(reg1({p,l,Name}, Value), [Name, Value]).
%% spec(Name::any(), Value::any()) -> true
%%
%% @doc Registers a global (non-unique) property. @equiv reg({p,g,Name},Value)
%% @end
%%
-add_global_property(Name, Value) -> reg({p,g,Name}, Value).
+add_global_property(Name, Value) -> ?CATCH(reg1({p,g,Name}, Value), [Name, Value]).
%% spec(Name::any(), Initial::integer()) -> true
%%
%% @doc Registers a local (non-unique) counter. @equiv reg({c,l,Name},Value)
%% @end
%%
add_local_counter(Name, Initial) when is_integer(Initial) ->
- reg({c,l,Name}, Initial).
+ ?CATCH(reg1({c,l,Name}, Initial), [Name, Initial]).
%% spec(Name::any(), Initial::integer()) -> true
@@ -224,23 +224,23 @@ add_shared_local_counter(Name, Initial) when is_integer(Initial) ->
%% @end
%%
add_global_counter(Name, Initial) when is_integer(Initial) ->
- reg({c,g,Name}, Initial).
+ ?CATCH(reg1({c,g,Name}, Initial), [Name, Initial]).
%% spec(Name::any()) -> true
%%
%% @doc Registers a local (unique) aggregated counter.
%% @equiv reg({a,l,Name})
%% @end
%%
-add_local_aggr_counter(Name) -> reg({a,l,Name}).
+add_local_aggr_counter(Name) -> ?CATCH(reg1({a,l,Name}), [Name]).
%% spec(Name::any()) -> true
%%
%% @doc Registers a global (unique) aggregated counter.
%% @equiv reg({a,g,Name})
%% @end
%%
-add_global_aggr_counter(Name) -> reg({a,g,Name}).
+add_global_aggr_counter(Name) -> ?CATCH(reg1({a,g,Name}), [Name]).
%% @spec (Name::any()) -> pid()
@@ -513,7 +513,7 @@ lookup_env(Scope, App, Key, P) ->
end.
cache_env(Scope, App, Key, Value) ->
- reg({p, Scope, {gproc_env, App, Key}}, Value).
+ ?CATCH(reg1({p, Scope, {gproc_env, App, Key}}, Value), [Scope,App,Key,Value]).
update_cached_env(Scope, App, Key, Value) ->
case lookup_env(Scope, App, Key, self()) of
@@ -581,7 +581,10 @@ is_string(S) ->
%% @equiv reg(Key, default(Key))
%% @end
reg(Key) ->
- reg(Key, default(Key)).
+ ?CATCH(reg1(Key), [Key]).
+
+reg1(Key) ->
+ reg1(Key, default(Key)).
default({T,_,_}) when T==c -> 0;
default(_) -> undefined.
@@ -590,7 +593,7 @@ default(_) -> undefined.
%% @equiv await(Key,infinity)
%%
await(Key) ->
- await(Key, infinity).
+ ?CATCH(await1(Key, infinity), [Key]).
%% @spec await(Key::key(), Timeout) -> {pid(),Value}
%% Timeout = integer() | infinity
@@ -604,10 +607,13 @@ await(Key) ->
%% registered (the difference: await/2 also returns the value).
%% @end
%%
-await({n,g,_} = Key, Timeout) ->
+await(Key, Timeout) ->
+ ?CATCH(await1(Key, Timeout), [Key, Timeout]).
+
+await1({n,g,_} = Key, Timeout) ->
?CHK_DIST,
request_wait(Key, Timeout);
-await({n,l,_} = Key, Timeout) ->
+await1({n,l,_} = Key, Timeout) ->
case ets:lookup(?TAB, {Key, n}) of
[{_, Pid, Value}] ->
case is_process_alive(Pid) of
@@ -626,16 +632,16 @@ await({n,l,_} = Key, Timeout) ->
_ ->
request_wait(Key, Timeout)
end;
-await(K, T) ->
- erlang:error(badarg, [K, T]).
+await1(_, _) ->
+ throw(badarg).
request_wait({n,C,_} = Key, Timeout) when C==l; C==g ->
TRef = case Timeout of
infinity -> no_timer;
T when is_integer(T), T > 0 ->
erlang:start_timer(T, self(), gproc_timeout);
_ ->
- erlang:error(badarg, [Key, Timeout])
+ ?THROW(badarg)
end,
WRef = case {call({await,Key,self()}, C), C} of
{{R, {Kg,Pg,Vg}}, g} ->
@@ -653,7 +659,7 @@ request_wait({n,C,_} = Key, Timeout) when C==l; C==g ->
{Pid, V};
{timeout, TRef, gproc_timeout} ->
cancel_wait(Key, WRef),
- erlang:error(timeout, [Key, Timeout])
+ ?THROW(timeout)
end.
@@ -664,13 +670,16 @@ request_wait({n,C,_} = Key, Timeout) when C==l; C==g ->
%% {gproc, Ref, registered, {Key, Pid, Value}}, once the name is registered.
%% @end
%%
-nb_wait({n,g,_} = Key) ->
+nb_wait(Key) ->
+ ?CATCH(nb_wait1(Key), [Key]).
+
+nb_wait1({n,g,_} = Key) ->
?CHK_DIST,
call({await, Key, self()}, g);
-nb_wait({n,l,_} = Key) ->
+nb_wait1({n,l,_} = Key) ->
call({await, Key, self()}, l);
-nb_wait(Key) ->
- erlang:error(badarg, [Key]).
+nb_wait1(_) ->
+ ?THROW(badarg).
%% @spec cancel_wait(Key::key(), Ref) -> ok
%% Ref = all | reference()
@@ -681,19 +690,25 @@ nb_wait(Key) ->
%% are canceled.
%% @end
%%
-cancel_wait({_,g,_} = Key, Ref) ->
+cancel_wait(Key, Ref) ->
+ ?CATCH(cancel_wait1(Key, Ref), [Key, Ref]).
+
+cancel_wait1({_,g,_} = Key, Ref) ->
?CHK_DIST,
cast({cancel_wait, self(), Key, Ref}, g),
ok;
-cancel_wait({_,l,_} = Key, Ref) ->
+cancel_wait1({_,l,_} = Key, Ref) ->
cast({cancel_wait, self(), Key, Ref}, l),
ok.
-cancel_wait_or_monitor({_,g,_} = Key) ->
+cancel_wait_or_monitor(Key) ->
+ ?CATCH(cancel_wait_or_monitor1(Key), [Key]).
+
+cancel_wait_or_monitor1({_,g,_} = Key) ->
?CHK_DIST,
cast({cancel_wait_or_monitor, self(), Key}, g),
ok;
-cancel_wait_or_monitor({_,l,_} = Key) ->
+cancel_wait_or_monitor1({_,l,_} = Key) ->
cast({cancel_wait_or_monitor, self(), Key}, l),
ok.
@@ -708,47 +723,56 @@ cancel_wait_or_monitor({_,l,_} = Key) ->
%%
%% If the name is not yet registered, the same message is sent immediately.
%% @end
-monitor({T,g,_} = Key) when T==n; T==a ->
+monitor(Key) ->
+ ?CATCH(monitor1(Key), [Key]).
+
+monitor1({T,g,_} = Key) when T==n; T==a ->
?CHK_DIST,
call({monitor, Key, self()}, g);
-monitor({T,l,_} = Key) when T==n; T==a ->
+monitor1({T,l,_} = Key) when T==n; T==a ->
call({monitor, Key, self()}, l);
-monitor(Key) ->
- erlang:error(badarg, [Key]).
+monitor1(_) ->
+ ?THROW(badarg).
%% @spec demonitor(key(), reference()) -> ok
%%
%% @doc Remove a monitor on a registered name
%% This function is the reverse of monitor/1. It removes a monitor previously
%% set on a unique name. This function always succeeds given legal input.
%% @end
-demonitor({T,g,_} = Key, Ref) when T==n; T==a ->
+demonitor(Key, Ref) ->
+ ?CATCH(demonitor1(Key, Ref), [Key, Ref]).
+
+demonitor1({T,g,_} = Key, Ref) when T==n; T==a ->
?CHK_DIST,
call({demonitor, Key, Ref, self()}, g);
-demonitor({T,l,_} = Key, Ref) when T==n; T==a ->
+demonitor1({T,l,_} = Key, Ref) when T==n; T==a ->
call({demonitor, Key, Ref, self()}, l);
-demonitor(Key, Ref) ->
- erlang:error(badarg, [Key, Ref]).
+demonitor1(_, _) ->
+ ?THROW(badarg).
%% @spec reg(Key::key(), Value) -> true
%%
%% @doc Register a name or property for the current process
%%
%%
-reg({_,g,_} = Key, Value) ->
+reg(Key, Value) ->
+ ?CATCH(reg1(Key, Value), [Key, Value]).
+
+reg1({_,g,_} = Key, Value) ->
%% anything global
?CHK_DIST,
gproc_dist:reg(Key, Value);
-reg({p,l,_} = Key, Value) ->
+reg1({p,l,_} = Key, Value) ->
local_reg(Key, Value);
-reg({a,l,_} = Key, undefined) ->
+reg1({a,l,_} = Key, undefined) ->
call({reg, Key, undefined});
-reg({c,l,_} = Key, Value) when is_integer(Value) ->
+reg1({c,l,_} = Key, Value) when is_integer(Value) ->
call({reg, Key, Value});
-reg({n,l,_} = Key, Value) ->
+reg1({n,l,_} = Key, Value) ->
call({reg, Key, Value});
-reg(_, _) ->
- erlang:error(badarg).
+reg1(_, _) ->
+ ?THROW(badarg).
%% @spec reg_shared(Key::key()) -> true
@@ -758,9 +782,12 @@ reg(_, _) ->
%% `reg_shared({c,l,C}) -> reg_shared({c,l,C}, 0).'
%% `reg_shared({a,l,A}) -> reg_shared({a,l,A}, undefined).'
%% @end
-reg_shared({c,_,_} = Key) ->
+reg_shared(Key) ->
+ ?CATCH(reg_shared1(Key), [Key]).
+
+reg_shared1({c,_,_} = Key) ->
reg_shared(Key, 0);
-reg_shared({a,_,_} = Key) ->
+reg_shared1({a,_,_} = Key) ->
reg_shared(Key, undefined).
@@ -779,16 +806,19 @@ reg_shared({a,_,_} = Key) ->
%% an aggregated counter which is owned by a process.
%% @end
%%
-reg_shared({_,g,_} = Key, Value) ->
+reg_shared(Key, Value) ->
+ ?CATCH(reg_shared1(Key, Value), [Key, Value]).
+
+reg_shared1({_,g,_} = Key, Value) ->
%% anything global
?CHK_DIST,
gproc_dist:reg_shared(Key, Value);
-reg_shared({a,l,_} = Key, undefined) ->
+reg_shared1({a,l,_} = Key, undefined) ->
call({reg_shared, Key, undefined});
-reg_shared({c,l,_} = Key, Value) when is_integer(Value) ->
+reg_shared1({c,l,_} = Key, Value) when is_integer(Value) ->
call({reg_shared, Key, Value});
-reg_shared(_, _) ->
- erlang:error(badarg).
+reg_shared1(_, _) ->
+ ?THROW(badarg).
%% @spec mreg(type(), scope(), [{Key::any(), Value::any()}]) -> true
%%
@@ -798,19 +828,22 @@ reg_shared(_, _) ->
%% It is also atomic in regard to unique names; either all names are registered
%% or none are.
%% @end
-mreg(T, g, KVL) ->
+mreg(T, C, KVL) ->
+ ?CATCH(mreg1(T, C, KVL), [T, C, KVL]).
+
+mreg1(T, g, KVL) ->
?CHK_DIST,
gproc_dist:mreg(T, KVL);
-mreg(T, l, KVL) when T==a; T==n ->
+mreg1(T, l, KVL) when T==a; T==n ->
if is_list(KVL) ->
call({mreg, T, l, KVL});
true ->
erlang:error(badarg)
end;
-mreg(p, l, KVL) ->
+mreg1(p, l, KVL) ->
local_mreg(p, KVL);
-mreg(_, _, _) ->
- erlang:error(badarg).
+mreg1(_, _, _) ->
+ ?THROW(badarg).
%% @spec munreg(type(), scope(), [Key::any()]) -> true
%%
@@ -819,19 +852,22 @@ mreg(_, _, _) ->
%% This function is usually more efficient than calling {@link unreg/1}
%% repeatedly.
%% @end
-munreg(T, g, L) ->
+munreg(T, C, L) ->
+ ?CATCH(munreg1(T, C, L), [T, C, L]).
+
+munreg1(T, g, L) ->
?CHK_DIST,
gproc_dist:munreg(T, existing(T,g,L));
-munreg(T, l, L) when T==a; T==n ->
+munreg1(T, l, L) when T==a; T==n ->
if is_list(L) ->
call({munreg, T, l, existing(T,l,L)});
true ->
erlang:error(badarg)
end;
-munreg(p, l, L) ->
+munreg1(p, l, L) ->
local_munreg(p, existing(p,l,L));
-munreg(_, _, _) ->
- erlang:error(badarg).
+munreg1(_, _, _) ->
+ ?THROW(badarg).
existing(T,Scope,L) ->
Keys = if T==p; T==c ->
@@ -851,6 +887,9 @@ existing(T,Scope,L) ->
%% @doc Unregister a name or property.
%% @end
unreg(Key) ->
+ ?CATCH(unreg1(Key), [Key]).
+
+unreg1(Key) ->
case Key of
{_, g, _} ->
?CHK_DIST,
@@ -863,7 +902,7 @@ unreg(Key) ->
_ = gproc_lib:remove_reg(Key, self(), unreg),
true;
false ->
- erlang:error(badarg)
+ ?THROW(badarg)
end
end.
@@ -872,14 +911,17 @@ unreg(Key) ->
%% @doc Unregister a shared resource.
%% @end
unreg_shared(Key) ->
+ ?CATCH(unreg_shared1(Key), [Key]).
+
+unreg_shared1(Key) ->
case Key of
{_, g, _} ->
?CHK_DIST,
gproc_dist:unreg_shared(Key);
{T, l, _} when T == c;
T == a -> call({unreg_shared, Key});
_ ->
- erlang:error(badarg)
+ ?THROW(badarg)
end.
%% @spec (key(), pid()) -> yes | no
@@ -946,22 +988,22 @@ select_count(Pat) ->
%% but the select patterns are transformed appropriately.
%% @end
select_count(Context, Pat) ->
- ets: select_count(?TAB, pattern(Pat, Context)).
+ ets:select_count(?TAB, pattern(Pat, Context)).
%%% Local properties can be registered in the local process, since
%%% no other process can interfere.
%%%
local_reg(Key, Value) ->
case gproc_lib:insert_reg(Key, Value, self(), l) of
- false -> erlang:error(badarg);
+ false -> ?THROW(badarg);
true -> monitor_me()
end.
local_mreg(_, []) -> true;
local_mreg(T, [_|_] = KVL) ->
case gproc_lib:insert_many(T, l, KVL, self()) of
- false -> erlang:error(badarg);
+ false -> ?THROW(badarg);
{true,_} -> monitor_me()
end.
@@ -979,35 +1021,38 @@ local_munreg(T, L) when T==p; T==c ->
%% it must be an integer.
%% @end
%%
-set_value({_,g,_} = Key, Value) ->
+set_value(Key, Value) ->
+ ?CATCH(set_value1(Key, Value), [Key, Value]).
+
+set_value1({_,g,_} = Key, Value) ->
?CHK_DIST,
gproc_dist:set_value(Key, Value);
-set_value({a,l,_} = Key, Value) when is_integer(Value) ->
+set_value1({a,l,_} = Key, Value) when is_integer(Value) ->
call({set, Key, Value});
-set_value({n,l,_} = Key, Value) ->
+set_value1({n,l,_} = Key, Value) ->
%% we cannot do this locally, since we have to check that the object
%% exists first - not an atomic update.
call({set, Key, Value});
-set_value({p,l,_} = Key, Value) ->
+set_value1({p,l,_} = Key, Value) ->
%% we _can_ to this locally, since there is no race condition - no
%% other process can update our properties.
case gproc_lib:do_set_value(Key, Value, self()) of
true -> true;
false ->
erlang:error(badarg)
end;
-set_value({c,l,_} = Key, Value) when is_integer(Value) ->
+set_value1({c,l,_} = Key, Value) when is_integer(Value) ->
gproc_lib:do_set_counter_value(Key, Value, self());
-set_value(_, _) ->
- erlang:error(badarg).
+set_value1(_, _) ->
+ ?THROW(badarg).
%% @spec (Key) -> Value
%% @doc Reads 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()).
+ ?CATCH(get_value1(Key, self()), [Key]).
%% @spec (Key, Pid) -> Value
%% @doc Reads the value stored with a key registered to the process Pid.
@@ -1016,26 +1061,29 @@ get_value(Key) ->
%% will be read.
%% @end
%%
-get_value({T,_,_} = Key, Pid) when is_pid(Pid) ->
+get_value(Key, Pid) ->
+ ?CATCH(get_value1(Key, Pid), [Key, Pid]).
+
+get_value1({T,_,_} = Key, Pid) when is_pid(Pid) ->
if T==n orelse T==a ->
case ets:lookup(?TAB, {Key, T}) of
[{_, P, Value}] when P == Pid -> Value;
- _ -> erlang:error(badarg)
+ _ -> ?THROW(badarg)
end;
true ->
ets:lookup_element(?TAB, {Key, Pid}, 3)
end;
-get_value({T,_,_} = K, shared) when T==c; T==a ->
+get_value1({T,_,_} = K, shared) when T==c; T==a ->
Key = case T of
c -> {K, shared};
a -> {K, a}
end,
case ets:lookup(?TAB, Key) of
[{_, shared, Value}] -> Value;
- _ -> erlang:error(badarg)
+ _ -> ?THROW(badarg)
end;
-get_value(_, _) ->
- erlang:error(badarg).
+get_value1(_, _) ->
+ ?THROW(badarg).
%% @spec (Key) -> Pid
@@ -1066,7 +1114,10 @@ lookup_value({T,_,_} = Key) ->
%% cases.
%% @end
%%
-where({T,_,_}=Key) ->
+where(Key) ->
+ ?CATCH(where1(Key), [Key]).
+
+where1({T,_,_}=Key) ->
if T==n orelse T==a ->
case ets:lookup(?TAB, {Key,T}) of
[{_, P, _Value}] ->
@@ -1079,12 +1130,12 @@ where({T,_,_}=Key) ->
undefined
end;
true ->
- erlang:error(badarg)
+ ?THROW(badarg)
end.
%% @equiv where/1
whereis_name(Key) ->
- where(Key).
+ ?CATCH(where1(Key), [Key]).
%% @spec (Key::key()) -> [pid()]
%%
@@ -1138,13 +1189,16 @@ lookup_values({T,_,_} = Key) ->
%% 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) ->
+update_counter(Key, Incr) ->
+ ?CATCH(update_counter1(Key, Incr), [Key, Incr]).
+
+update_counter1({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) ->
+update_counter1({c,g,_} = Key, Incr) when is_integer(Incr) ->
?CHK_DIST,
gproc_dist:update_counter(Key, Incr);
-update_counter(_, _) ->
- erlang:error(badarg).
+update_counter1(_, _) ->
+ ?THROW(badarg).
%% @spec (Key) -> {ValueBefore, ValueAfter}
@@ -1161,10 +1215,13 @@ update_counter(_, _) ->
%% updates. Aggregated counters are updated accordingly.
%% @end
%%
-reset_counter({c,g,_} = Key) ->
+reset_counter(Key) ->
+ ?CATCH(reset_counter1(Key), [Key]).
+
+reset_counter1({c,g,_} = Key) ->
?CHK_DIST,
gproc_dist:reset_counter(Key);
-reset_counter({c,l,_} = Key) ->
+reset_counter1({c,l,_} = Key) ->
Current = ets:lookup_element(?TAB, {Key, self()}, 3),
Initial = case ets:lookup(?TAB, {self(), Key}) of
[{_, r}] -> 0;
@@ -1173,11 +1230,13 @@ reset_counter({c,l,_} = Key) ->
end,
{Current, update_counter(Key, Initial - Current)}.
+update_shared_counter(Key, Incr) ->
+ ?CATCH(update_shared_counter1(Key, Incr), [Key, Incr]).
-update_shared_counter({c,g,_} = Key, Incr) ->
+update_shared_counter1({c,g,_} = Key, Incr) ->
?CHK_DIST,
gproc_dist:update_shared_counter(Key, Incr);
-update_shared_counter({c,l,_} = Key, Incr) ->
+update_shared_counter1({c,l,_} = Key, Incr) ->
gproc_lib:update_counter(Key, Incr, shared).
%% @spec (From::key(), To::pid() | key()) -> undefined | pid()
@@ -1198,11 +1257,14 @@ update_shared_counter({c,l,_} = Key, Incr) ->
%% Fails with `badarg' if the calling process does not have a `From' key
%% registered.
%% @end
-give_away({_,l,_} = Key, ToPid) when is_pid(ToPid), node(ToPid) == node() ->
+give_away(Key, ToPid) ->
+ ?CATCH(give_away1(Key, ToPid), [Key, ToPid]).
+
+give_away1({_,l,_} = Key, ToPid) when is_pid(ToPid), node(ToPid) == node() ->
call({give_away, Key, ToPid});
-give_away({_,l,_} = Key, {n,l,_} = ToKey) ->
+give_away1({_,l,_} = Key, {n,l,_} = ToKey) ->
call({give_away, Key, ToKey});
-give_away({_,g,_} = Key, To) ->
+give_away1({_,g,_} = Key, To) ->
?CHK_DIST,
gproc_dist:give_away(Key, To).
@@ -1227,13 +1289,16 @@ goodbye() ->
%% property), Msg will be send to all processes that have such an object.
%% @end
%%
-send({T,C,_} = Key, Msg) when C==l; C==g ->
+send(Key, Msg) ->
+ ?CATCH(send1(Key, Msg), [Key, Msg]).
+
+send1({T,C,_} = Key, Msg) when C==l; C==g ->
if T == n orelse T == a ->
case ets:lookup(?TAB, {Key, T}) of
[{_, Pid, _}] ->
Pid ! Msg;
_ ->
- erlang:error(badarg)
+ ?THROW(badarg)
end;
T==p orelse T==c ->
%% BUG - if the key part contains select wildcards, we may end up
@@ -1245,8 +1310,8 @@ send({T,C,_} = Key, Msg) when C==l; C==g ->
true ->
erlang:error(badarg)
end;
-send(_, _) ->
- erlang:error(badarg).
+send1(_, _) ->
+ ?THROW(badarg).
%% @spec (Context :: context()) -> key() | '$end_of_table'
@@ -1583,13 +1648,13 @@ call(Req) ->
call(Req, l).
call(Req, l) ->
- chk_reply(gen_server:call(?MODULE, Req), Req);
+ chk_reply(gen_server:call(?MODULE, Req));
call(Req, g) ->
- chk_reply(gproc_dist:leader_call(Req), Req).
+ chk_reply(gproc_dist:leader_call(Req)).
-chk_reply(Reply, Req) ->
+chk_reply(Reply) ->
case Reply of
- badarg -> erlang:error(badarg, Req);
+ badarg -> ?THROW(badarg);
_ -> Reply
end.
View
27 src/gproc_int.hrl
@@ -0,0 +1,27 @@
+%% ``The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved via the world wide web at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+%% AB. All Rights Reserved.''
+%%
+%% @author Ulf Wiger <ulf.wiger@feuerlabs.com
+%%
+%% gproc_int.hrl: Shared internal definitions
+
+-define(CATCH(Expr, Args),
+ try Expr
+ catch
+ throw:{gproc_error, GprocError} ->
+ erlang:error(GprocError, Args)
+ end).
+
+-define(THROW(E), throw({gproc_error, E})).

0 comments on commit d9314f3

Please sign in to comment.
Something went wrong with that request. Please try again.