Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

renamed CATCH/THROW macros, counter thresholds

  • Loading branch information...
commit b1855cb88195b1a760fba43b3680d63db884066e 1 parent 0f84360
@uwiger authored
View
38 doc/gproc.md
@@ -173,7 +173,7 @@ to forget about the calling process.</td></tr><tr><td valign="top"><a href="#i-0
about names and properties registered in Gproc, where applicable.</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_global_aggr_counter-1">lookup_global_aggr_counter/1</a></td><td>Lookup a global (unique) aggregated counter and returns its value.</td></tr><tr><td valign="top"><a href="#lookup_global_counters-1">lookup_global_counters/1</a></td><td>Look up all global (non-unique) instances of a given Counter.</td></tr><tr><td valign="top"><a href="#lookup_global_name-1">lookup_global_name/1</a></td><td>Lookup a global unique name.</td></tr><tr><td valign="top"><a href="#lookup_global_properties-1">lookup_global_properties/1</a></td><td>Look up all global (non-unique) instances of a given Property.</td></tr><tr><td valign="top"><a href="#lookup_local_aggr_counter-1">lookup_local_aggr_counter/1</a></td><td>Lookup a local (unique) aggregated counter and returns its value.</td></tr><tr><td valign="top"><a href="#lookup_local_counters-1">lookup_local_counters/1</a></td><td>Look up all local (non-unique) instances of a given Counter.</td></tr><tr><td valign="top"><a href="#lookup_local_name-1">lookup_local_name/1</a></td><td>Lookup a local unique name.</td></tr><tr><td valign="top"><a href="#lookup_local_properties-1">lookup_local_properties/1</a></td><td>Look up all local (non-unique) instances of a given Property.</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="#lookup_value-1">lookup_value/1</a></td><td>Lookup the value stored with a key.</td></tr><tr><td valign="top"><a href="#lookup_values-1">lookup_values/1</a></td><td>Retrieve the <code>{Pid,Value}</code> pairs corresponding to Key.</td></tr><tr><td valign="top"><a href="#monitor-1">monitor/1</a></td><td>monitor a registered name
This function works much like erlang:monitor(process, Pid), but monitors
a unique name registered via gproc.</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="#munreg-3">munreg/3</a></td><td>Unregister multiple Key items of a given type and scope.</td></tr><tr><td valign="top"><a href="#nb_wait-1">nb_wait/1</a></td><td>Wait for a local name to be registered.</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, default(Key))</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="#reg_shared-1">reg_shared/1</a></td><td>Register a resource, but don't tie it to a particular process.</td></tr><tr><td valign="top"><a href="#reg_shared-2">reg_shared/2</a></td><td>Register a resource, but don't tie it to a particular process.</td></tr><tr><td valign="top"><a href="#register_name-2">register_name/2</a></td><td>Behaviour support callback.</td></tr><tr><td valign="top"><a href="#reset_counter-1">reset_counter/1</a></td><td>Reads and resets a counter in a "thread-safe" way.</td></tr><tr><td valign="top"><a href="#select-1">select/1</a></td><td>
-see http://www.erlang.org/doc/man/ets.html#select-1.</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="#select_count-1">select_count/1</a></td><td>Equivalent to <a href="#select_count-2"><tt>select_count(all, Pat)</tt></a>.</td></tr><tr><td valign="top"><a href="#select_count-2">select_count/2</a></td><td>Perform a select_count operation on the process registry.</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_env-5">set_env/5</a></td><td>Updates the cached value as well as underlying environment.</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>Starts the gproc server.</td></tr><tr><td valign="top"><a href="#table-0">table/0</a></td><td>Equivalent to <a href="#table-1"><tt>table({all, all})</tt></a>.</td></tr><tr><td valign="top"><a href="#table-1">table/1</a></td><td>Equivalent to <a href="#table-2"><tt>table(Context, [])</tt></a>.</td></tr><tr><td valign="top"><a href="#table-2">table/2</a></td><td>QLC table generator for the gproc registry.</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="#unreg_shared-1">unreg_shared/1</a></td><td>Unregister a shared resource.</td></tr><tr><td valign="top"><a href="#unregister_name-1">unregister_name/1</a></td><td>Equivalent to <tt>unreg / 1</tt>.</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="#update_shared_counter-2">update_shared_counter/2</a></td><td></td></tr><tr><td valign="top"><a href="#where-1">where/1</a></td><td>Returns the pid registered as Key.</td></tr><tr><td valign="top"><a href="#whereis_name-1">whereis_name/1</a></td><td>Equivalent to <tt>where / 1</tt>.</td></tr></table>
+see http://www.erlang.org/doc/man/ets.html#select-1.</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="#select_count-1">select_count/1</a></td><td>Equivalent to <a href="#select_count-2"><tt>select_count(all, Pat)</tt></a>.</td></tr><tr><td valign="top"><a href="#select_count-2">select_count/2</a></td><td>Perform a select_count operation on the process registry.</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_env-5">set_env/5</a></td><td>Updates the cached value as well as underlying environment.</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>Starts the gproc server.</td></tr><tr><td valign="top"><a href="#table-0">table/0</a></td><td>Equivalent to <a href="#table-1"><tt>table({all, all})</tt></a>.</td></tr><tr><td valign="top"><a href="#table-1">table/1</a></td><td>Equivalent to <a href="#table-2"><tt>table(Context, [])</tt></a>.</td></tr><tr><td valign="top"><a href="#table-2">table/2</a></td><td>QLC table generator for the gproc registry.</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="#unreg_shared-1">unreg_shared/1</a></td><td>Unregister a shared resource.</td></tr><tr><td valign="top"><a href="#unregister_name-1">unregister_name/1</a></td><td>Equivalent to <tt>unreg / 1</tt>.</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="#update_shared_counter-2">update_shared_counter/2</a></td><td>Updates the shared counter registered as Key.</td></tr><tr><td valign="top"><a href="#where-1">where/1</a></td><td>Returns the pid registered as Key.</td></tr><tr><td valign="top"><a href="#whereis_name-1">whereis_name/1</a></td><td>Equivalent to <tt>where / 1</tt>.</td></tr></table>
<a name="functions"></a>
@@ -1321,9 +1321,8 @@ Equivalent to `unreg / 1`.<a name="update_counter-2"></a>
-<pre>update_counter(Key::<a href="#type-key">key()</a>, Incr::integer()) -> integer()</pre>
-<br></br>
-
+<pre>update_counter(Key::<a href="#type-key">key()</a>, Incr) -> integer() | [integer()]</pre>
+<ul class="definitions"><li><pre>Incr = IncrVal | UpdateOp | [UpdateOp]</pre></li><li><pre>UpdateOp = IncrVal | {IncrVal, Threshold, SetValue}</pre></li><li><pre>IncrVal = integer()</pre></li></ul>
@@ -1331,18 +1330,39 @@ Equivalent to `unreg / 1`.<a name="update_counter-2"></a>
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`](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.<a name="update_shared_counter-2"></a>
+
+
+This function works almost exactly like ets:update_counter/3
+(see [`http://www.erlang.org/doc/man/ets.html#update_counter-3`](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.
+
+Aggregated counters with the same name will be updated automatically.
+The `UpdateOp` patterns are the same as for `ets:update_counter/3`, except
+that the position is omitted; in gproc, the value position is always `3`.<a name="update_shared_counter-2"></a>
###update_shared_counter/2##
-`update_shared_counter(Key, Incr) -> any()`
+<pre>update_shared_counter(Key::<a href="#type-key">key()</a>, Incr) -> integer() | [integer()]</pre>
+<ul class="definitions"><li><pre>Incr = IncrVal | UpdateOp | [UpdateOp]</pre></li><li><pre>UpdateOp = IncrVal | {IncrVal, Threshold, SetValue}</pre></li><li><pre>IncrVal = integer()</pre></li></ul>
+
+
+
+
+
+Updates the shared counter registered as Key.
+
+
+
+This function works almost exactly like ets:update_counter/3
+(see [`http://www.erlang.org/doc/man/ets.html#update_counter-3`](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.
-<a name="where-1"></a>
+Aggregated counters with the same name will be updated automatically.
+The `UpdateOp` patterns are the same as for `ets:update_counter/3`, except
+that the position is omitted; in gproc, the value position is always `3`.<a name="where-1"></a>
###where/1##
View
149 src/gproc.erl
@@ -149,7 +149,7 @@
-define(CHK_DIST,
case whereis(gproc_dist) of
undefined ->
- ?THROW(local_only);
+ ?THROW_GPROC_ERROR(local_only);
_ ->
ok
end).
@@ -174,7 +174,7 @@ start_link() ->
%% @doc Registers a local (unique) name. @equiv reg({n,l,Name})
%% @end
%%
-add_local_name(Name) -> ?CATCH(reg1({n,l,Name}, undefined), [Name]).
+add_local_name(Name) -> ?CATCH_GPROC_ERROR(reg1({n,l,Name}, undefined), [Name]).
%% spec(Name::any()) -> true
@@ -182,7 +182,7 @@ add_local_name(Name) -> ?CATCH(reg1({n,l,Name}, undefined), [Name]).
%% @doc Registers a global (unique) name. @equiv reg({n,g,Name})
%% @end
%%
-add_global_name(Name) -> ?CATCH(reg1({n,g,Name}, undefined), [Name]).
+add_global_name(Name) -> ?CATCH_GPROC_ERROR(reg1({n,g,Name}, undefined), [Name]).
%% spec(Name::any(), Value::any()) -> true
@@ -190,14 +190,16 @@ add_global_name(Name) -> ?CATCH(reg1({n,g,Name}, undefined), [Name]).
%% @doc Registers a local (non-unique) property. @equiv reg({p,l,Name},Value)
%% @end
%%
-add_local_property(Name , Value) -> ?CATCH(reg1({p,l,Name}, Value), [Name, Value]).
+add_local_property(Name , Value) ->
+ ?CATCH_GPROC_ERROR(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) -> ?CATCH(reg1({p,g,Name}, Value), [Name, Value]).
+add_global_property(Name, Value) ->
+ ?CATCH_GPROC_ERROR(reg1({p,g,Name}, Value), [Name, Value]).
%% spec(Name::any(), Initial::integer()) -> true
%%
@@ -205,7 +207,7 @@ add_global_property(Name, Value) -> ?CATCH(reg1({p,g,Name}, Value), [Name, Value
%% @end
%%
add_local_counter(Name, Initial) when is_integer(Initial) ->
- ?CATCH(reg1({c,l,Name}, Initial), [Name, Initial]).
+ ?CATCH_GPROC_ERROR(reg1({c,l,Name}, Initial), [Name, Initial]).
%% spec(Name::any(), Initial::integer()) -> true
@@ -224,7 +226,7 @@ add_shared_local_counter(Name, Initial) when is_integer(Initial) ->
%% @end
%%
add_global_counter(Name, Initial) when is_integer(Initial) ->
- ?CATCH(reg1({c,g,Name}, Initial), [Name, Initial]).
+ ?CATCH_GPROC_ERROR(reg1({c,g,Name}, Initial), [Name, Initial]).
%% spec(Name::any()) -> true
%%
@@ -232,7 +234,7 @@ add_global_counter(Name, Initial) when is_integer(Initial) ->
%% @equiv reg({a,l,Name})
%% @end
%%
-add_local_aggr_counter(Name) -> ?CATCH(reg1({a,l,Name}), [Name]).
+add_local_aggr_counter(Name) -> ?CATCH_GPROC_ERROR(reg1({a,l,Name}), [Name]).
%% spec(Name::any()) -> true
%%
@@ -240,7 +242,7 @@ add_local_aggr_counter(Name) -> ?CATCH(reg1({a,l,Name}), [Name]).
%% @equiv reg({a,g,Name})
%% @end
%%
-add_global_aggr_counter(Name) -> ?CATCH(reg1({a,g,Name}), [Name]).
+add_global_aggr_counter(Name) -> ?CATCH_GPROC_ERROR(reg1({a,g,Name}), [Name]).
%% @spec (Name::any()) -> pid()
@@ -513,7 +515,9 @@ lookup_env(Scope, App, Key, P) ->
end.
cache_env(Scope, App, Key, Value) ->
- ?CATCH(reg1({p, Scope, {gproc_env, App, Key}}, Value), [Scope,App,Key,Value]).
+ ?CATCH_GPROC_ERROR(
+ 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 +585,7 @@ is_string(S) ->
%% @equiv reg(Key, default(Key))
%% @end
reg(Key) ->
- ?CATCH(reg1(Key), [Key]).
+ ?CATCH_GPROC_ERROR(reg1(Key), [Key]).
reg1(Key) ->
reg1(Key, default(Key)).
@@ -593,7 +597,7 @@ default(_) -> undefined.
%% @equiv await(Key,infinity)
%%
await(Key) ->
- ?CATCH(await1(Key, infinity), [Key]).
+ ?CATCH_GPROC_ERROR(await1(Key, infinity), [Key]).
%% @spec await(Key::key(), Timeout) -> {pid(),Value}
%% Timeout = integer() | infinity
@@ -608,7 +612,7 @@ await(Key) ->
%% @end
%%
await(Key, Timeout) ->
- ?CATCH(await1(Key, Timeout), [Key, Timeout]).
+ ?CATCH_GPROC_ERROR(await1(Key, Timeout), [Key, Timeout]).
await1({n,g,_} = Key, Timeout) ->
?CHK_DIST,
@@ -641,7 +645,7 @@ request_wait({n,C,_} = Key, Timeout) when C==l; C==g ->
T when is_integer(T), T > 0 ->
erlang:start_timer(T, self(), gproc_timeout);
_ ->
- ?THROW(badarg)
+ ?THROW_GPROC_ERROR(badarg)
end,
WRef = case {call({await,Key,self()}, C), C} of
{{R, {Kg,Pg,Vg}}, g} ->
@@ -659,7 +663,7 @@ request_wait({n,C,_} = Key, Timeout) when C==l; C==g ->
{Pid, V};
{timeout, TRef, gproc_timeout} ->
cancel_wait(Key, WRef),
- ?THROW(timeout)
+ ?THROW_GPROC_ERROR(timeout)
end.
@@ -671,7 +675,7 @@ request_wait({n,C,_} = Key, Timeout) when C==l; C==g ->
%% @end
%%
nb_wait(Key) ->
- ?CATCH(nb_wait1(Key), [Key]).
+ ?CATCH_GPROC_ERROR(nb_wait1(Key), [Key]).
nb_wait1({n,g,_} = Key) ->
?CHK_DIST,
@@ -679,7 +683,7 @@ nb_wait1({n,g,_} = Key) ->
nb_wait1({n,l,_} = Key) ->
call({await, Key, self()}, l);
nb_wait1(_) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
%% @spec cancel_wait(Key::key(), Ref) -> ok
%% Ref = all | reference()
@@ -691,7 +695,7 @@ nb_wait1(_) ->
%% @end
%%
cancel_wait(Key, Ref) ->
- ?CATCH(cancel_wait1(Key, Ref), [Key, Ref]).
+ ?CATCH_GPROC_ERROR(cancel_wait1(Key, Ref), [Key, Ref]).
cancel_wait1({_,g,_} = Key, Ref) ->
?CHK_DIST,
@@ -702,7 +706,7 @@ cancel_wait1({_,l,_} = Key, Ref) ->
ok.
cancel_wait_or_monitor(Key) ->
- ?CATCH(cancel_wait_or_monitor1(Key), [Key]).
+ ?CATCH_GPROC_ERROR(cancel_wait_or_monitor1(Key), [Key]).
cancel_wait_or_monitor1({_,g,_} = Key) ->
?CHK_DIST,
@@ -724,7 +728,7 @@ cancel_wait_or_monitor1({_,l,_} = Key) ->
%% If the name is not yet registered, the same message is sent immediately.
%% @end
monitor(Key) ->
- ?CATCH(monitor1(Key), [Key]).
+ ?CATCH_GPROC_ERROR(monitor1(Key), [Key]).
monitor1({T,g,_} = Key) when T==n; T==a ->
?CHK_DIST,
@@ -732,7 +736,7 @@ monitor1({T,g,_} = Key) when T==n; T==a ->
monitor1({T,l,_} = Key) when T==n; T==a ->
call({monitor, Key, self()}, l);
monitor1(_) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
%% @spec demonitor(key(), reference()) -> ok
%%
@@ -741,7 +745,7 @@ monitor1(_) ->
%% set on a unique name. This function always succeeds given legal input.
%% @end
demonitor(Key, Ref) ->
- ?CATCH(demonitor1(Key, Ref), [Key, Ref]).
+ ?CATCH_GPROC_ERROR(demonitor1(Key, Ref), [Key, Ref]).
demonitor1({T,g,_} = Key, Ref) when T==n; T==a ->
?CHK_DIST,
@@ -749,7 +753,7 @@ demonitor1({T,g,_} = Key, Ref) when T==n; T==a ->
demonitor1({T,l,_} = Key, Ref) when T==n; T==a ->
call({demonitor, Key, Ref, self()}, l);
demonitor1(_, _) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
%% @spec reg(Key::key(), Value) -> true
%%
@@ -757,7 +761,7 @@ demonitor1(_, _) ->
%%
%%
reg(Key, Value) ->
- ?CATCH(reg1(Key, Value), [Key, Value]).
+ ?CATCH_GPROC_ERROR(reg1(Key, Value), [Key, Value]).
reg1({_,g,_} = Key, Value) ->
%% anything global
@@ -772,7 +776,7 @@ reg1({c,l,_} = Key, Value) when is_integer(Value) ->
reg1({n,l,_} = Key, Value) ->
call({reg, Key, Value});
reg1(_, _) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
%% @spec reg_shared(Key::key()) -> true
@@ -783,7 +787,7 @@ reg1(_, _) ->
%% `reg_shared({a,l,A}) -> reg_shared({a,l,A}, undefined).'
%% @end
reg_shared(Key) ->
- ?CATCH(reg_shared1(Key), [Key]).
+ ?CATCH_GPROC_ERROR(reg_shared1(Key), [Key]).
reg_shared1({c,_,_} = Key) ->
reg_shared(Key, 0);
@@ -807,7 +811,7 @@ reg_shared1({a,_,_} = Key) ->
%% @end
%%
reg_shared(Key, Value) ->
- ?CATCH(reg_shared1(Key, Value), [Key, Value]).
+ ?CATCH_GPROC_ERROR(reg_shared1(Key, Value), [Key, Value]).
reg_shared1({_,g,_} = Key, Value) ->
%% anything global
@@ -818,7 +822,7 @@ reg_shared1({a,l,_} = Key, undefined) ->
reg_shared1({c,l,_} = Key, Value) when is_integer(Value) ->
call({reg_shared, Key, Value});
reg_shared1(_, _) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
%% @spec mreg(type(), scope(), [{Key::any(), Value::any()}]) -> true
%%
@@ -829,7 +833,7 @@ reg_shared1(_, _) ->
%% or none are.
%% @end
mreg(T, C, KVL) ->
- ?CATCH(mreg1(T, C, KVL), [T, C, KVL]).
+ ?CATCH_GPROC_ERROR(mreg1(T, C, KVL), [T, C, KVL]).
mreg1(T, g, KVL) ->
?CHK_DIST,
@@ -843,7 +847,7 @@ mreg1(T, l, KVL) when T==a; T==n ->
mreg1(p, l, KVL) ->
local_mreg(p, KVL);
mreg1(_, _, _) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
%% @spec munreg(type(), scope(), [Key::any()]) -> true
%%
@@ -853,7 +857,7 @@ mreg1(_, _, _) ->
%% repeatedly.
%% @end
munreg(T, C, L) ->
- ?CATCH(munreg1(T, C, L), [T, C, L]).
+ ?CATCH_GPROC_ERROR(munreg1(T, C, L), [T, C, L]).
munreg1(T, g, L) ->
?CHK_DIST,
@@ -867,7 +871,7 @@ munreg1(T, l, L) when T==a; T==n ->
munreg1(p, l, L) ->
local_munreg(p, existing(p,l,L));
munreg1(_, _, _) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
existing(T,Scope,L) ->
Keys = if T==p; T==c ->
@@ -887,7 +891,7 @@ existing(T,Scope,L) ->
%% @doc Unregister a name or property.
%% @end
unreg(Key) ->
- ?CATCH(unreg1(Key), [Key]).
+ ?CATCH_GPROC_ERROR(unreg1(Key), [Key]).
unreg1(Key) ->
case Key of
@@ -902,7 +906,7 @@ unreg1(Key) ->
_ = gproc_lib:remove_reg(Key, self(), unreg),
true;
false ->
- ?THROW(badarg)
+ ?THROW_GPROC_ERROR(badarg)
end
end.
@@ -911,7 +915,7 @@ unreg1(Key) ->
%% @doc Unregister a shared resource.
%% @end
unreg_shared(Key) ->
- ?CATCH(unreg_shared1(Key), [Key]).
+ ?CATCH_GPROC_ERROR(unreg_shared1(Key), [Key]).
unreg_shared1(Key) ->
case Key of
@@ -921,7 +925,7 @@ unreg_shared1(Key) ->
{T, l, _} when T == c;
T == a -> call({unreg_shared, Key});
_ ->
- ?THROW(badarg)
+ ?THROW_GPROC_ERROR(badarg)
end.
%% @spec (key(), pid()) -> yes | no
@@ -996,14 +1000,14 @@ select_count(Context, Pat) ->
%%%
local_reg(Key, Value) ->
case gproc_lib:insert_reg(Key, Value, self(), l) of
- false -> ?THROW(badarg);
+ false -> ?THROW_GPROC_ERROR(badarg);
true -> monitor_me()
end.
local_mreg(_, []) -> true;
local_mreg(T, [_|_] = KVL) ->
case gproc_lib:insert_many(T, l, KVL, self()) of
- false -> ?THROW(badarg);
+ false -> ?THROW_GPROC_ERROR(badarg);
{true,_} -> monitor_me()
end.
@@ -1022,7 +1026,7 @@ local_munreg(T, L) when T==p; T==c ->
%% @end
%%
set_value(Key, Value) ->
- ?CATCH(set_value1(Key, Value), [Key, Value]).
+ ?CATCH_GPROC_ERROR(set_value1(Key, Value), [Key, Value]).
set_value1({_,g,_} = Key, Value) ->
?CHK_DIST,
@@ -1044,7 +1048,7 @@ set_value1({p,l,_} = Key, Value) ->
set_value1({c,l,_} = Key, Value) when is_integer(Value) ->
gproc_lib:do_set_counter_value(Key, Value, self());
set_value1(_, _) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
%% @spec (Key) -> Value
%% @doc Reads the value stored with a key registered to the current process.
@@ -1052,7 +1056,7 @@ set_value1(_, _) ->
%% If no such key is registered to the current process, this function exits.
%% @end
get_value(Key) ->
- ?CATCH(get_value1(Key, self()), [Key]).
+ ?CATCH_GPROC_ERROR(get_value1(Key, self()), [Key]).
%% @spec (Key, Pid) -> Value
%% @doc Reads the value stored with a key registered to the process Pid.
@@ -1062,13 +1066,13 @@ get_value(Key) ->
%% @end
%%
get_value(Key, Pid) ->
- ?CATCH(get_value1(Key, Pid), [Key, Pid]).
+ ?CATCH_GPROC_ERROR(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;
- _ -> ?THROW(badarg)
+ _ -> ?THROW_GPROC_ERROR(badarg)
end;
true ->
ets:lookup_element(?TAB, {Key, Pid}, 3)
@@ -1080,10 +1084,10 @@ get_value1({T,_,_} = K, shared) when T==c; T==a ->
end,
case ets:lookup(?TAB, Key) of
[{_, shared, Value}] -> Value;
- _ -> ?THROW(badarg)
+ _ -> ?THROW_GPROC_ERROR(badarg)
end;
get_value1(_, _) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
%% @spec (Key) -> Pid
@@ -1115,7 +1119,7 @@ lookup_value({T,_,_} = Key) ->
%% @end
%%
where(Key) ->
- ?CATCH(where1(Key), [Key]).
+ ?CATCH_GPROC_ERROR(where1(Key), [Key]).
where1({T,_,_}=Key) ->
if T==n orelse T==a ->
@@ -1130,12 +1134,12 @@ where1({T,_,_}=Key) ->
undefined
end;
true ->
- ?THROW(badarg)
+ ?THROW_GPROC_ERROR(badarg)
end.
%% @equiv where/1
whereis_name(Key) ->
- ?CATCH(where1(Key), [Key]).
+ ?CATCH_GPROC_ERROR(where1(Key), [Key]).
%% @spec (Key::key()) -> [pid()]
%%
@@ -1180,25 +1184,32 @@ lookup_values({T,_,_} = Key) ->
end,
[Pair || {P,_} = Pair <- L, my_is_process_alive(P)].
-%% @spec (Key::key(), Incr::integer()) -> integer()
+%% @spec (Key::key(), Incr) -> integer() | [integer()]
+%% Incr = IncrVal | UpdateOp | [UpdateOp]
+%% UpdateOp = IncrVal | {IncrVal, Threshold, SetValue}
+%% IncrVal = integer()
%%
%% @doc Updates the counter registered as Key for the current process.
%%
-%% This function works like ets:update_counter/3
+%% This function works almost exactly 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.
+%%
+%% Aggregated counters with the same name will be updated automatically.
+%% The `UpdateOp' patterns are the same as for `ets:update_counter/3', except
+%% that the position is omitted; in gproc, the value position is always `3'.
%% @end
%%
update_counter(Key, Incr) ->
- ?CATCH(update_counter1(Key, Incr), [Key, Incr]).
+ ?CATCH_GPROC_ERROR(update_counter1(Key, Incr), [Key, Incr]).
-update_counter1({c,l,_} = Key, Incr) when is_integer(Incr) ->
+update_counter1({c,l,_} = Key, Incr) ->
gproc_lib:update_counter(Key, Incr, self());
-update_counter1({c,g,_} = Key, Incr) when is_integer(Incr) ->
+update_counter1({c,g,_} = Key, Incr) ->
?CHK_DIST,
gproc_dist:update_counter(Key, Incr);
update_counter1(_, _) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
%% @spec (Key) -> {ValueBefore, ValueAfter}
@@ -1216,7 +1227,7 @@ update_counter1(_, _) ->
%% @end
%%
reset_counter(Key) ->
- ?CATCH(reset_counter1(Key), [Key]).
+ ?CATCH_GPROC_ERROR(reset_counter1(Key), [Key]).
reset_counter1({c,g,_} = Key) ->
?CHK_DIST,
@@ -1230,8 +1241,24 @@ reset_counter1({c,l,_} = Key) ->
end,
{Current, update_counter(Key, Initial - Current)}.
+%% @spec (Key::key(), Incr) -> integer() | [integer()]
+%% Incr = IncrVal | UpdateOp | [UpdateOp]
+%% UpdateOp = IncrVal | {IncrVal, Threshold, SetValue}
+%% IncrVal = integer()
+%%
+%% @doc Updates the shared counter registered as Key.
+%%
+%% This function works almost exactly 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.
+%%
+%% Aggregated counters with the same name will be updated automatically.
+%% The `UpdateOp' patterns are the same as for `ets:update_counter/3', except
+%% that the position is omitted; in gproc, the value position is always `3'.
+%% @end
+%%
update_shared_counter(Key, Incr) ->
- ?CATCH(update_shared_counter1(Key, Incr), [Key, Incr]).
+ ?CATCH_GPROC_ERROR(update_shared_counter1(Key, Incr), [Key, Incr]).
update_shared_counter1({c,g,_} = Key, Incr) ->
?CHK_DIST,
@@ -1258,7 +1285,7 @@ update_shared_counter1({c,l,_} = Key, Incr) ->
%% registered.
%% @end
give_away(Key, ToPid) ->
- ?CATCH(give_away1(Key, ToPid), [Key, ToPid]).
+ ?CATCH_GPROC_ERROR(give_away1(Key, ToPid), [Key, ToPid]).
give_away1({_,l,_} = Key, ToPid) when is_pid(ToPid), node(ToPid) == node() ->
call({give_away, Key, ToPid});
@@ -1290,7 +1317,7 @@ goodbye() ->
%% @end
%%
send(Key, Msg) ->
- ?CATCH(send1(Key, Msg), [Key, Msg]).
+ ?CATCH_GPROC_ERROR(send1(Key, Msg), [Key, Msg]).
send1({T,C,_} = Key, Msg) when C==l; C==g ->
if T == n orelse T == a ->
@@ -1298,7 +1325,7 @@ send1({T,C,_} = Key, Msg) when C==l; C==g ->
[{_, Pid, _}] ->
Pid ! Msg;
_ ->
- ?THROW(badarg)
+ ?THROW_GPROC_ERROR(badarg)
end;
T==p orelse T==c ->
%% BUG - if the key part contains select wildcards, we may end up
@@ -1311,7 +1338,7 @@ send1({T,C,_} = Key, Msg) when C==l; C==g ->
erlang:error(badarg)
end;
send1(_, _) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
%% @spec (Context :: context()) -> key() | '$end_of_table'
@@ -1654,7 +1681,7 @@ call(Req, g) ->
chk_reply(Reply) ->
case Reply of
- badarg -> ?THROW(badarg);
+ badarg -> ?THROW_GPROC_ERROR(badarg);
_ -> Reply
end.
View
24 src/gproc_dist.erl
@@ -99,45 +99,45 @@ reg({_,g,_} = Key, Value) ->
%% anything global
leader_call({reg, Key, Value, self()});
reg(_, _) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
reg_shared({_,g,_} = Key, Value) ->
leader_call({reg, Key, Value, shared});
reg_shared(_, _) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
mreg(T, KVL) ->
if is_list(KVL) -> leader_call({mreg, T, g, KVL, self()});
- true -> ?THROW(badarg)
+ true -> ?THROW_GPROC_ERROR(badarg)
end.
munreg(T, Keys) ->
if is_list(Keys) -> leader_call({munreg, T, g, Keys, self()});
- true -> ?THROW(badarg)
+ true -> ?THROW_GPROC_ERROR(badarg)
end.
unreg({_,g,_} = Key) ->
leader_call({unreg, Key, self()});
unreg(_) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
unreg_shared({T,g,_} = Key) when T==c; T==a ->
leader_call({unreg, Key, shared});
unreg_shared(_) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
set_value({T,g,_} = Key, Value) when T==a; T==c ->
if is_integer(Value) ->
leader_call({set, Key, Value});
true ->
- ?THROW(badarg)
+ ?THROW_GPROC_ERROR(badarg)
end;
set_value({_,g,_} = Key, Value) ->
leader_call({set, Key, Value, self()});
set_value(_, _) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
give_away({_,g,_} = Key, To) ->
leader_call({give_away, Key, To, self()}).
@@ -146,18 +146,18 @@ give_away({_,g,_} = Key, To) ->
update_counter({c,g,_} = Key, Incr) when is_integer(Incr) ->
leader_call({update_counter, Key, Incr, self()});
update_counter(_, _) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
update_shared_counter({c,g,_} = Key, Incr) when is_integer(Incr) ->
leader_call({update_counter, Key, Incr, shared});
update_shared_counter(_, _) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
reset_counter({c,g,_} = Key) ->
leader_call({reset_counter, Key, self()});
reset_counter(_) ->
- ?THROW(badarg).
+ ?THROW_GPROC_ERROR(badarg).
%% @spec sync() -> true
@@ -579,7 +579,7 @@ ets_key(K, Pid) ->
leader_call(Req) ->
case gen_leader:leader_call(?MODULE, Req) of
- badarg -> ?THROW(badarg);
+ badarg -> ?THROW_GPROC_ERROR(badarg);
Reply -> Reply
end.
View
4 src/gproc_int.hrl
@@ -17,11 +17,11 @@
%%
%% gproc_int.hrl: Shared internal definitions
--define(CATCH(Expr, Args),
+-define(CATCH_GPROC_ERROR(Expr, Args),
try Expr
catch
throw:{gproc_error, GprocError} ->
erlang:error(GprocError, Args)
end).
--define(THROW(E), throw({gproc_error, E})).
+-define(THROW_GPROC_ERROR(E), throw({gproc_error, E})).
View
37 src/gproc_lib.erl
@@ -39,6 +39,7 @@
update_counter/3,
valid_opts/2]).
+-include("gproc_int.hrl").
-include("gproc.hrl").
%% We want to store names and aggregated counters with the same
@@ -364,10 +365,42 @@ do_set_counter_value({_,C,N} = Key, Value, Pid) ->
update_aggr_counter(C, N, Value - OldVal),
Res.
-update_counter({c,l,Ctr} = Key, Incr, Pid) ->
+update_counter({c,l,Ctr} = Key, Incr, Pid) when is_integer(Incr) ->
Res = ets:update_counter(?TAB, {Key, Pid}, {3,Incr}),
update_aggr_counter(l, Ctr, Incr),
- Res.
+ Res;
+update_counter({c,l,Ctr} = Key, {Incr, Threshold, SetValue}, Pid)
+ when is_integer(Incr), is_integer(Threshold), is_integer(SetValue) ->
+ [Prev, New] = ets:update_counter(?TAB, {Key, Pid},
+ [{3, 0}, {3, Incr, Threshold, SetValue}]),
+ update_aggr_counter(l, Ctr, New - Prev),
+ New;
+update_counter({c,l,Ctr} = Key, Ops, Pid) when is_list(Ops) ->
+ case ets:update_counter(?TAB, {Key, Pid},
+ [{3, 0} | expand_ops(Ops)]) of
+ [_] ->
+ [];
+ [Prev | Rest] ->
+ [New | _] = lists:reverse(Rest),
+ update_aggr_counter(l, Ctr, New - Prev),
+ Rest
+ end;
+update_counter(_, _, _) ->
+ ?THROW_GPROC_ERROR(badarg).
+
+expand_ops([{Incr,Thr,SetV}|T])
+ when is_integer(Incr), is_integer(Thr), is_integer(SetV) ->
+ [{3, Incr, Thr, SetV}|expand_ops(T)];
+expand_ops([Incr|T]) when is_integer(Incr) ->
+ [{3, Incr}|expand_ops(T)];
+expand_ops([]) ->
+ [];
+expand_ops(_) ->
+ ?THROW_GPROC_ERROR(badarg).
+
+
+
+
update_aggr_counter(C, N, Val) ->
catch ets:update_counter(?TAB, {{a,C,N},a}, {3, Val}).
Please sign in to comment.
Something went wrong with that request. Please try again.