gproc.erl 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148
  1. %% ``The contents of this file are subject to the Erlang Public License,
  2. %% Version 1.1, (the "License"); you may not use this file except in
  3. %% compliance with the License. You should have received a copy of the
  4. %% Erlang Public License along with this software. If not, it can be
  5. %% retrieved via the world wide web at http://www.erlang.org/.
  6. %%
  7. %% Software distributed under the License is distributed on an "AS IS"
  8. %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  9. %% the License for the specific language governing rights and limitations
  10. %% under the License.
  11. %%
  12. %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
  13. %% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
  14. %% AB. All Rights Reserved.''
  15. %%
  16. %% @author Ulf Wiger <ulf.wiger@erlang-consulting.com>
  17. %%
  18. %% @doc Extended process registry
  19. %% This module implements an extended process registry
  20. %%
  21. %% For a detailed description, see
  22. %% <a href="erlang07-wiger.pdf">erlang07-wiger.pdf</a>.
  23. %%
  24. %% <h2>Tuning Gproc performance</h2>
  25. %%
  26. %% Gproc relies on a central server and an ordered-set ets table.
  27. %% Effort is made to perform as much work as possible in the client without
  28. %% sacrificing consistency. A few things can be tuned by setting the following
  29. %% application environment variables in the top application of `gproc'
  30. %% (usually `gproc'):
  31. %%
  32. %% * `{ets_options, list()}' - Currently, the options `{write_concurrency, F}'
  33. %% and `{read_concurrency, F}' are allowed. The default is
  34. %% `[{write_concurrency, true}, {read_concurrency, true}]'
  35. %% * `{server_options, list()}' - These will be passed as spawn options when
  36. %% starting the `gproc' and `gproc_dist' servers. Default is `[]'. It is
  37. %% likely that `{priority, high | max}' and/or increasing `min_heap_size'
  38. %% will improve performance.
  39. %%
  40. %% @end
  41. %% @type type() = n | p | c | a. n = name; p = property; c = counter;
  42. %% a = aggregate_counter
  43. %% @type scope() = l | g. l = local registration; g = global registration
  44. %%
  45. %% @type reg_id() = {type(), scope(), any()}.
  46. %% @type unique_id() = {n | a, scope(), any()}.
  47. %%
  48. %% @type sel_scope() = scope | all | global | local.
  49. %% @type sel_type() = type() | names | props | counters | aggr_counters.
  50. %% @type context() = {scope(), type()} | type(). {'all','all'} is the default
  51. %%
  52. %% @type headpat() = {keypat(),pidpat(),ValPat}.
  53. %% @type keypat() = {sel_type() | sel_var(),
  54. %% l | g | sel_var(),
  55. %% any()}.
  56. %% @type pidpat() = pid() | sel_var().
  57. %% @type sel_var() = DollarVar | '_'.
  58. %% @type sel_pattern() = [{headpat(), Guards, Prod}].
  59. %% @type key() = {type(), scope(), any()}.
  60. -module(gproc).
  61. -behaviour(gen_server).
  62. -export([start_link/0,
  63. reg/1, reg/2, unreg/1,
  64. reg_shared/1, reg_shared/2, unreg_shared/1,
  65. mreg/3,
  66. munreg/3,
  67. set_value/2,
  68. get_value/1, get_value/2,
  69. where/1,
  70. await/1, await/2,
  71. nb_wait/1,
  72. cancel_wait/2,
  73. cancel_wait_or_monitor/1,
  74. monitor/1,
  75. demonitor/2,
  76. lookup_pid/1,
  77. lookup_pids/1,
  78. lookup_value/1,
  79. lookup_values/1,
  80. update_counter/2,
  81. reset_counter/1,
  82. update_shared_counter/2,
  83. give_away/2,
  84. goodbye/0,
  85. send/2,
  86. info/1, info/2,
  87. i/0,
  88. select/1, select/2, select/3,
  89. select_count/1, select_count/2,
  90. first/1,
  91. next/2,
  92. prev/2,
  93. last/1,
  94. table/0, table/1, table/2]).
  95. %% Environment handling
  96. -export([get_env/3, get_env/4,
  97. get_set_env/3, get_set_env/4,
  98. set_env/5]).
  99. %% Convenience functions
  100. -export([add_local_name/1,
  101. add_global_name/1,
  102. add_local_property/2,
  103. add_global_property/2,
  104. add_local_counter/2,
  105. add_global_counter/2,
  106. add_local_aggr_counter/1,
  107. add_global_aggr_counter/1,
  108. add_shared_local_counter/2,
  109. lookup_local_name/1,
  110. lookup_global_name/1,
  111. lookup_local_properties/1,
  112. lookup_global_properties/1,
  113. lookup_local_counters/1,
  114. lookup_global_counters/1,
  115. lookup_local_aggr_counter/1,
  116. lookup_global_aggr_counter/1]).
  117. %% Callbacks for behaviour support
  118. -export([whereis_name/1,
  119. register_name/2,
  120. unregister_name/1]).
  121. -export([default/1]).
  122. %%% internal exports
  123. -export([init/1,
  124. handle_cast/2,
  125. handle_call/3,
  126. handle_info/2,
  127. code_change/3,
  128. terminate/2]).
  129. %% this shouldn't be necessary
  130. -export([audit_process/1]).
  131. -include("gproc_int.hrl").
  132. -include("gproc.hrl").
  133. -include_lib("eunit/include/eunit.hrl").
  134. -define(SERVER, ?MODULE).
  135. %%-define(l, l(?LINE)). % when activated, calls a traceable empty function
  136. -define(l, ignore).
  137. -define(CHK_DIST,
  138. case whereis(gproc_dist) of
  139. undefined ->
  140. ?THROW_GPROC_ERROR(local_only);
  141. _ ->
  142. ok
  143. end).
  144. -record(state, {}).
  145. %% @spec () -> {ok, pid()}
  146. %%
  147. %% @doc Starts the gproc server.
  148. %%
  149. %% This function is intended to be called from gproc_sup, as part of
  150. %% starting the gproc application.
  151. %% @end
  152. start_link() ->
  153. _ = create_tabs(),
  154. SpawnOpts = gproc_lib:valid_opts(server_options, []),
  155. gen_server:start_link({local, ?SERVER}, ?MODULE, [],
  156. [{spawn_opt, SpawnOpts}]).
  157. %% spec(Name::any()) -> true
  158. %%
  159. %% @doc Registers a local (unique) name. @equiv reg({n,l,Name})
  160. %% @end
  161. %%
  162. add_local_name(Name) -> ?CATCH_GPROC_ERROR(reg1({n,l,Name}, undefined), [Name]).
  163. %% spec(Name::any()) -> true
  164. %%
  165. %% @doc Registers a global (unique) name. @equiv reg({n,g,Name})
  166. %% @end
  167. %%
  168. add_global_name(Name) -> ?CATCH_GPROC_ERROR(reg1({n,g,Name}, undefined), [Name]).
  169. %% spec(Name::any(), Value::any()) -> true
  170. %%
  171. %% @doc Registers a local (non-unique) property. @equiv reg({p,l,Name},Value)
  172. %% @end
  173. %%
  174. add_local_property(Name , Value) ->
  175. ?CATCH_GPROC_ERROR(reg1({p,l,Name}, Value), [Name, Value]).
  176. %% spec(Name::any(), Value::any()) -> true
  177. %%
  178. %% @doc Registers a global (non-unique) property. @equiv reg({p,g,Name},Value)
  179. %% @end
  180. %%
  181. add_global_property(Name, Value) ->
  182. ?CATCH_GPROC_ERROR(reg1({p,g,Name}, Value), [Name, Value]).
  183. %% spec(Name::any(), Initial::integer()) -> true
  184. %%
  185. %% @doc Registers a local (non-unique) counter. @equiv reg({c,l,Name},Value)
  186. %% @end
  187. %%
  188. add_local_counter(Name, Initial) when is_integer(Initial) ->
  189. ?CATCH_GPROC_ERROR(reg1({c,l,Name}, Initial), [Name, Initial]).
  190. %% spec(Name::any(), Initial::integer()) -> true
  191. %%
  192. %% @doc Registers a local shared (unique) counter.
  193. %% @equiv reg_shared({c,l,Name},Value)
  194. %% @end
  195. %%
  196. add_shared_local_counter(Name, Initial) when is_integer(Initial) ->
  197. reg_shared({c,l,Name}, Initial).
  198. %% spec(Name::any(), Initial::integer()) -> true
  199. %%
  200. %% @doc Registers a global (non-unique) counter. @equiv reg({c,g,Name},Value)
  201. %% @end
  202. %%
  203. add_global_counter(Name, Initial) when is_integer(Initial) ->
  204. ?CATCH_GPROC_ERROR(reg1({c,g,Name}, Initial), [Name, Initial]).
  205. %% spec(Name::any()) -> true
  206. %%
  207. %% @doc Registers a local (unique) aggregated counter.
  208. %% @equiv reg({a,l,Name})
  209. %% @end
  210. %%
  211. add_local_aggr_counter(Name) -> ?CATCH_GPROC_ERROR(reg1({a,l,Name}), [Name]).
  212. %% spec(Name::any()) -> true
  213. %%
  214. %% @doc Registers a global (unique) aggregated counter.
  215. %% @equiv reg({a,g,Name})
  216. %% @end
  217. %%
  218. add_global_aggr_counter(Name) -> ?CATCH_GPROC_ERROR(reg1({a,g,Name}), [Name]).
  219. %% @spec (Name::any()) -> pid()
  220. %%
  221. %% @doc Lookup a local unique name. Fails if there is no such name.
  222. %% @equiv where({n,l,Name})
  223. %% @end
  224. %%
  225. lookup_local_name(Name) -> where({n,l,Name}).
  226. %% @spec (Name::any()) -> pid()
  227. %%
  228. %% @doc Lookup a global unique name. Fails if there is no such name.
  229. %% @equiv where({n,g,Name})
  230. %% @end
  231. %%
  232. lookup_global_name(Name) -> where({n,g,Name}).
  233. %% @spec (Name::any()) -> integer()
  234. %%
  235. %% @doc Lookup a local (unique) aggregated counter and returns its value.
  236. %% Fails if there is no such object.
  237. %% @equiv where({a,l,Name})
  238. %% @end
  239. %%
  240. lookup_local_aggr_counter(Name) -> lookup_value({a,l,Name}).
  241. %% @spec (Name::any()) -> integer()
  242. %%
  243. %% @doc Lookup a global (unique) aggregated counter and returns its value.
  244. %% Fails if there is no such object.
  245. %% @equiv where({a,g,Name})
  246. %% @end
  247. %%
  248. lookup_global_aggr_counter(Name) -> lookup_value({a,g,Name}).
  249. %% @spec (Property::any()) -> [{pid(), Value}]
  250. %%
  251. %% @doc Look up all local (non-unique) instances of a given Property.
  252. %% Returns a list of {Pid, Value} tuples for all matching objects.
  253. %% @equiv lookup_values({p, l, Property})
  254. %% @end
  255. %%
  256. lookup_local_properties(P) -> lookup_values({p,l,P}).
  257. %% @spec (Property::any()) -> [{pid(), Value}]
  258. %%
  259. %% @doc Look up all global (non-unique) instances of a given Property.
  260. %% Returns a list of {Pid, Value} tuples for all matching objects.
  261. %% @equiv lookup_values({p, g, Property})
  262. %% @end
  263. %%
  264. lookup_global_properties(P) -> lookup_values({p,g,P}).
  265. %% @spec (Counter::any()) -> [{pid(), Value::integer()}]
  266. %%
  267. %% @doc Look up all local (non-unique) instances of a given Counter.
  268. %% Returns a list of {Pid, Value} tuples for all matching objects.
  269. %% @equiv lookup_values({c, l, Counter})
  270. %% @end
  271. %%
  272. lookup_local_counters(P) -> lookup_values({c,l,P}).
  273. %% @spec (Counter::any()) -> [{pid(), Value::integer()}]
  274. %%
  275. %% @doc Look up all global (non-unique) instances of a given Counter.
  276. %% Returns a list of {Pid, Value} tuples for all matching objects.
  277. %% @equiv lookup_values({c, g, Counter})
  278. %% @end
  279. %%
  280. lookup_global_counters(P) -> lookup_values({c,g,P}).
  281. %% @spec get_env(Scope::scope(), App::atom(), Key::atom()) -> term()
  282. %% @equiv get_env(Scope, App, Key, [app_env])
  283. get_env(Scope, App, Key) ->
  284. get_env(Scope, App, Key, [app_env]).
  285. %% @spec (Scope::scope(), App::atom(), Key::atom(), Strategy) -> term()
  286. %% Strategy = [Alternative]
  287. %% Alternative = app_env
  288. %% | os_env
  289. %% | inherit | {inherit, pid()} | {inherit, unique_id()}
  290. %% | init_arg
  291. %% | {mnesia, ActivityType, Oid, Pos}
  292. %% | {default, term()}
  293. %% | error
  294. %% @doc Read an environment value, potentially cached as a `gproc_env' property.
  295. %%
  296. %% This function first tries to read the value of a cached property,
  297. %% `{p, Scope, {gproc_env, App, Key}}'. If this fails, it will try the provided
  298. %% alternative strategy. `Strategy' is a list of alternatives, tried in order.
  299. %% Each alternative can be one of:
  300. %%
  301. %% * `app_env' - try `application:get_env(App, Key)'
  302. %% * `os_env' - try `os:getenv(ENV)', where `ENV' is `Key' converted into an
  303. %% uppercase string
  304. %% * `{os_env, ENV}' - try `os:getenv(ENV)'
  305. %% * `inherit' - inherit the cached value, if any, held by the parent process.
  306. %% * `{inherit, Pid}' - inherit the cached value, if any, held by `Pid'.
  307. %% * `{inherit, Id}' - inherit the cached value, if any, held by the process
  308. %% registered in `gproc' as `Id'.
  309. %% * `init_arg' - try `init:get_argument(Key)'; expects a single value, if any.
  310. %% * `{mnesia, ActivityType, Oid, Pos}' - try
  311. %% `mnesia:activity(ActivityType, fun() -> mnesia:read(Oid) end)'; retrieve
  312. %% the value in position `Pos' if object found.
  313. %% * `{default, Value}' - set a default value to return once alternatives have
  314. %% been exhausted; if not set, `undefined' will be returned.
  315. %% * `error' - raise an exception, `erlang:error(gproc_env, [App, Key, Scope])'.
  316. %%
  317. %% While any alternative can occur more than once, the only one that might make
  318. %% sense to use multiple times is `{default, Value}'.
  319. %%
  320. %% The return value will be one of:
  321. %%
  322. %% * The value of the first matching alternative, or `error' eception,
  323. %% whichever comes first
  324. %% * The last instance of `{default, Value}', or `undefined', if there is no
  325. %% matching alternative, default or `error' entry in the list.
  326. %%
  327. %% The `error' option can be used to assert that a value has been previously
  328. %% cached. Alternatively, it can be used to assert that a value is either cached
  329. %% or at least defined somewhere,
  330. %% e.g. `get_env(l, mnesia, dir, [app_env, error])'.
  331. %% @end
  332. get_env(Scope, App, Key, Strategy)
  333. when Scope==l, is_atom(App), is_atom(Key);
  334. Scope==g, is_atom(App), is_atom(Key) ->
  335. do_get_env(Scope, App, Key, Strategy, false).
  336. %% @spec get_set_env(Scope::scope(), App::atom(), Key::atom()) -> term()
  337. %% @equiv get_set_env(Scope, App, Key, [app_env])
  338. get_set_env(Scope, App, Key) ->
  339. get_set_env(Scope, App, Key, [app_env]).
  340. %% @spec get_set_env(Scope::scope(), App::atom(), Key::atom(), Strategy) ->
  341. %% Value
  342. %% @doc Fetch and cache an environment value, if not already cached.
  343. %%
  344. %% This function does the same thing as {@link get_env/4}, but also updates the
  345. %% cache. Note that the cache will be updated even if the result of the lookup
  346. %% is `undefined'.
  347. %%
  348. %% @see get_env/4.
  349. %% @end
  350. %%
  351. get_set_env(Scope, App, Key, Strategy)
  352. when Scope==l, is_atom(App), is_atom(Key);
  353. Scope==g, is_atom(App), is_atom(Key) ->
  354. do_get_env(Scope, App, Key, Strategy, true).
  355. do_get_env(Context, App, Key, Alternatives, Set) ->
  356. case lookup_env(Context, App, Key, self()) of
  357. undefined ->
  358. check_alternatives(Alternatives, Context, App, Key, undefined, Set);
  359. {ok, Value} ->
  360. Value
  361. end.
  362. %% @spec set_env(Scope::scope(), App::atom(),
  363. %% Key::atom(), Value::term(), Strategy) -> Value
  364. %% Strategy = [Alternative]
  365. %% Alternative = app_env | os_env | {os_env, VAR}
  366. %% | {mnesia, ActivityType, Oid, Pos}
  367. %%
  368. %% @doc Updates the cached value as well as underlying environment.
  369. %%
  370. %% This function should be exercised with caution, as it affects the larger
  371. %% environment outside gproc. This function modifies the cached value, and then
  372. %% proceeds to update the underlying environment (OS environment variable or
  373. %% application environment variable).
  374. %%
  375. %% When the `mnesia' alternative is used, gproc will try to update any existing
  376. %% object, changing only the `Pos' position. If no such object exists, it will
  377. %% create a new object, setting any other attributes (except `Pos' and the key)
  378. %% to `undefined'.
  379. %% @end
  380. %%
  381. set_env(Scope, App, Key, Value, Strategy)
  382. when Scope==l, is_atom(App), is_atom(Key);
  383. Scope==g, is_atom(App), is_atom(Key) ->
  384. case is_valid_set_strategy(Strategy, Value) of
  385. true ->
  386. update_cached_env(Scope, App, Key, Value),
  387. set_strategy(Strategy, App, Key, Value);
  388. false ->
  389. erlang:error(badarg)
  390. end.
  391. check_alternatives([{default, Val}|Alts], Scope, App, Key, _, Set) ->
  392. check_alternatives(Alts, Scope, App, Key, Val, Set);
  393. check_alternatives([H|T], Scope, App, Key, Def, Set) ->
  394. case try_alternative(H, App, Key, Scope) of
  395. undefined ->
  396. check_alternatives(T, Scope, App, Key, Def, Set);
  397. {ok, Value} ->
  398. if Set ->
  399. cache_env(Scope, App, Key, Value),
  400. Value;
  401. true ->
  402. Value
  403. end
  404. end;
  405. check_alternatives([], Scope, App, Key, Def, Set) ->
  406. if Set ->
  407. cache_env(Scope, App, Key, Def);
  408. true ->
  409. ok
  410. end,
  411. Def.
  412. try_alternative(error, App, Key, Scope) ->
  413. erlang:error(gproc_env, [App, Key, Scope]);
  414. try_alternative(inherit, App, Key, Scope) ->
  415. case get('$ancestors') of
  416. [P|_] ->
  417. lookup_env(Scope, App, Key, P);
  418. _ ->
  419. undefined
  420. end;
  421. try_alternative({inherit, P}, App, Key, Scope) when is_pid(P) ->
  422. lookup_env(Scope, App, Key, P);
  423. try_alternative({inherit, P}, App, Key, Scope) ->
  424. case where(P) of
  425. undefined -> undefined;
  426. Pid when is_pid(Pid) ->
  427. lookup_env(Scope, App, Key, Pid)
  428. end;
  429. try_alternative(app_env, App, Key, _Scope) ->
  430. case application:get_env(App, Key) of
  431. undefined -> undefined;
  432. {ok, undefined} -> undefined;
  433. {ok, Value} -> {ok, Value}
  434. end;
  435. try_alternative(os_env, _App, Key, _) ->
  436. case os:getenv(os_env_key(Key)) of
  437. false -> undefined;
  438. Val -> {ok, Val}
  439. end;
  440. try_alternative({os_env, Key}, _, _, _) ->
  441. case os:getenv(Key) of
  442. false -> undefined;
  443. Val -> {ok, Val}
  444. end;
  445. try_alternative(init_arg, _, Key, _) ->
  446. case init:get_argument(Key) of
  447. {ok, [[Value]]} ->
  448. {ok, Value};
  449. error ->
  450. undefined
  451. end;
  452. try_alternative({mnesia,Type,Key,Pos}, _, _, _) ->
  453. case mnesia:activity(Type, fun() -> mnesia:read(Key) end) of
  454. [] -> undefined;
  455. [Found] ->
  456. {ok, element(Pos, Found)}
  457. end.
  458. os_env_key(Key) ->
  459. string:to_upper(atom_to_list(Key)).
  460. lookup_env(Scope, App, Key, P) ->
  461. case ets:lookup(?TAB, {{p, Scope, {gproc_env, App, Key}}, P}) of
  462. [] ->
  463. undefined;
  464. [{_, _, Value}] ->
  465. {ok, Value}
  466. end.
  467. cache_env(Scope, App, Key, Value) ->
  468. ?CATCH_GPROC_ERROR(
  469. reg1({p, Scope, {gproc_env, App, Key}}, Value),
  470. [Scope,App,Key,Value]).
  471. update_cached_env(Scope, App, Key, Value) ->
  472. case lookup_env(Scope, App, Key, self()) of
  473. undefined ->
  474. cache_env(Scope, App, Key, Value);
  475. {ok, _} ->
  476. set_value({p, Scope, {gproc_env, App, Key}}, Value)
  477. end.
  478. is_valid_set_strategy([os_env|T], Value) ->
  479. is_string(Value) andalso is_valid_set_strategy(T, Value);
  480. is_valid_set_strategy([{os_env, _}|T], Value) ->
  481. is_string(Value) andalso is_valid_set_strategy(T, Value);
  482. is_valid_set_strategy([app_env|T], Value) ->
  483. is_valid_set_strategy(T, Value);
  484. is_valid_set_strategy([{mnesia,_Type,_Oid,_Pos}|T], Value) ->
  485. is_valid_set_strategy(T, Value);
  486. is_valid_set_strategy([], _) ->
  487. true;
  488. is_valid_set_strategy(_, _) ->
  489. false.
  490. set_strategy([H|T], App, Key, Value) ->
  491. case H of
  492. app_env ->
  493. application:set_env(App, Key, Value);
  494. os_env ->
  495. os:putenv(os_env_key(Key), Value);
  496. {os_env, ENV} ->
  497. os:putenv(ENV, Value);
  498. {mnesia,Type,Oid,Pos} ->
  499. mnesia:activity(
  500. Type,
  501. fun() ->
  502. Rec = case mnesia:read(Oid) of
  503. [] ->
  504. {Tab,K} = Oid,
  505. Tag = mnesia:table_info(Tab, record_name),
  506. Attrs = mnesia:table_info(Tab, attributes),
  507. list_to_tuple(
  508. [Tag,K |
  509. [undefined || _ <- tl(Attrs)]]);
  510. [Old] ->
  511. Old
  512. end,
  513. mnesia:write(setelement(Pos, Rec, Value))
  514. end)
  515. end,
  516. set_strategy(T, App, Key, Value);
  517. set_strategy([], _, _, Value) ->
  518. Value.
  519. is_string(S) ->
  520. try begin _ = iolist_to_binary(S),
  521. true
  522. end
  523. catch
  524. error:_ ->
  525. false
  526. end.
  527. %% @spec reg(Key::key()) -> true
  528. %%
  529. %% @doc
  530. %% @equiv reg(Key, default(Key))
  531. %% @end
  532. reg(Key) ->
  533. ?CATCH_GPROC_ERROR(reg1(Key), [Key]).
  534. reg1(Key) ->
  535. reg1(Key, default(Key)).
  536. default({T,_,_}) when T==c -> 0;
  537. default(_) -> undefined.
  538. %% @spec await(Key::key()) -> {pid(),Value}
  539. %% @equiv await(Key,infinity)
  540. %%
  541. await(Key) ->
  542. ?CATCH_GPROC_ERROR(await1(Key, infinity), [Key]).
  543. %% @spec await(Key::key(), Timeout) -> {pid(),Value}
  544. %% Timeout = integer() | infinity
  545. %%
  546. %% @doc Wait for a local name to be registered.
  547. %% The function raises an exception if the timeout expires. Timeout must be
  548. %% either an interger &gt; 0 or 'infinity'.
  549. %% A small optimization: we first perform a lookup, to see if the name
  550. %% is already registered. This way, the cost of the operation will be
  551. %% roughly the same as of where/1 in the case where the name is already
  552. %% registered (the difference: await/2 also returns the value).
  553. %% @end
  554. %%
  555. await(Key, Timeout) ->
  556. ?CATCH_GPROC_ERROR(await1(Key, Timeout), [Key, Timeout]).
  557. await1({n,g,_} = Key, Timeout) ->
  558. ?CHK_DIST,
  559. request_wait(Key, Timeout);
  560. await1({n,l,_} = Key, Timeout) ->
  561. case ets:lookup(?TAB, {Key, n}) of
  562. [{_, Pid, Value}] ->
  563. case is_process_alive(Pid) of
  564. true ->
  565. {Pid, Value};
  566. false ->
  567. %% we can send an asynchronous audit request, since the purpose is
  568. %% only to ensure that the server handles the audit before it serves
  569. %% our 'await' request. Strictly speaking, we could allow the bad Pid
  570. %% to be returned, as there are no guarantees that whatever Pid we return
  571. %% will still be alive when addressed. Still, we don't want to knowingly
  572. %% serve bad data.
  573. nb_audit_process(Pid),
  574. request_wait(Key, Timeout)
  575. end;
  576. _ ->
  577. request_wait(Key, Timeout)
  578. end;
  579. await1(_, _) ->
  580. throw(badarg).
  581. request_wait({n,C,_} = Key, Timeout) when C==l; C==g ->
  582. TRef = case Timeout of
  583. infinity -> no_timer;
  584. T when is_integer(T), T > 0 ->
  585. erlang:start_timer(T, self(), gproc_timeout);
  586. _ ->
  587. ?THROW_GPROC_ERROR(badarg)
  588. end,
  589. WRef = case {call({await,Key,self()}, C), C} of
  590. {{R, {Kg,Pg,Vg}}, g} ->
  591. self() ! {gproc, R, registered, {Kg,Pg,Vg}},
  592. R;
  593. {R,_} ->
  594. R
  595. end,
  596. receive
  597. {gproc, WRef, registered, {_K, Pid, V}} ->
  598. _ = case TRef of
  599. no_timer -> ignore;
  600. _ -> erlang:cancel_timer(TRef)
  601. end,
  602. {Pid, V};
  603. {timeout, TRef, gproc_timeout} ->
  604. cancel_wait(Key, WRef),
  605. ?THROW_GPROC_ERROR(timeout)
  606. end.
  607. %% @spec nb_wait(Key::key()) -> Ref
  608. %%
  609. %% @doc Wait for a local name to be registered.
  610. %% The caller can expect to receive a message,
  611. %% {gproc, Ref, registered, {Key, Pid, Value}}, once the name is registered.
  612. %% @end
  613. %%
  614. nb_wait(Key) ->
  615. ?CATCH_GPROC_ERROR(nb_wait1(Key), [Key]).
  616. nb_wait1({n,g,_} = Key) ->
  617. ?CHK_DIST,
  618. call({await, Key, self()}, g);
  619. nb_wait1({n,l,_} = Key) ->
  620. call({await, Key, self()}, l);
  621. nb_wait1(_) ->
  622. ?THROW_GPROC_ERROR(badarg).
  623. %% @spec cancel_wait(Key::key(), Ref) -> ok
  624. %% Ref = all | reference()
  625. %%
  626. %% @doc Cancels a previous call to nb_wait/1
  627. %%
  628. %% If `Ref = all', all wait requests on `Key' from the calling process
  629. %% are canceled.
  630. %% @end
  631. %%
  632. cancel_wait(Key, Ref) ->
  633. ?CATCH_GPROC_ERROR(cancel_wait1(Key, Ref), [Key, Ref]).
  634. cancel_wait1({_,g,_} = Key, Ref) ->
  635. ?CHK_DIST,
  636. cast({cancel_wait, self(), Key, Ref}, g),
  637. ok;
  638. cancel_wait1({_,l,_} = Key, Ref) ->
  639. cast({cancel_wait, self(), Key, Ref}, l),
  640. ok.
  641. cancel_wait_or_monitor(Key) ->
  642. ?CATCH_GPROC_ERROR(cancel_wait_or_monitor1(Key), [Key]).
  643. cancel_wait_or_monitor1({_,g,_} = Key) ->
  644. ?CHK_DIST,
  645. cast({cancel_wait_or_monitor, self(), Key}, g),
  646. ok;
  647. cancel_wait_or_monitor1({_,l,_} = Key) ->
  648. cast({cancel_wait_or_monitor, self(), Key}, l),
  649. ok.
  650. %% @spec monitor(key()) -> reference()
  651. %%
  652. %% @doc monitor a registered name
  653. %% This function works much like erlang:monitor(process, Pid), but monitors
  654. %% a unique name registered via gproc. A message, `{gproc, unreg, Ref, Key}'
  655. %% will be sent to the requesting process, if the name is unregistered or
  656. %% the registered process dies.
  657. %%
  658. %% If the name is not yet registered, the same message is sent immediately.
  659. %% @end
  660. monitor(Key) ->
  661. ?CATCH_GPROC_ERROR(monitor1(Key), [Key]).
  662. monitor1({T,g,_} = Key) when T==n; T==a ->
  663. ?CHK_DIST,
  664. call({monitor, Key, self()}, g);
  665. monitor1({T,l,_} = Key) when T==n; T==a ->
  666. call({monitor, Key, self()}, l);
  667. monitor1(_) ->
  668. ?THROW_GPROC_ERROR(badarg).
  669. %% @spec demonitor(key(), reference()) -> ok
  670. %%
  671. %% @doc Remove a monitor on a registered name
  672. %% This function is the reverse of monitor/1. It removes a monitor previously
  673. %% set on a unique name. This function always succeeds given legal input.
  674. %% @end
  675. demonitor(Key, Ref) ->
  676. ?CATCH_GPROC_ERROR(demonitor1(Key, Ref), [Key, Ref]).
  677. demonitor1({T,g,_} = Key, Ref) when T==n; T==a ->
  678. ?CHK_DIST,
  679. call({demonitor, Key, Ref, self()}, g);
  680. demonitor1({T,l,_} = Key, Ref) when T==n; T==a ->
  681. call({demonitor, Key, Ref, self()}, l);
  682. demonitor1(_, _) ->
  683. ?THROW_GPROC_ERROR(badarg).
  684. %% @spec reg(Key::key(), Value) -> true
  685. %%
  686. %% @doc Register a name or property for the current process
  687. %%
  688. %%
  689. reg(Key, Value) ->
  690. ?CATCH_GPROC_ERROR(reg1(Key, Value), [Key, Value]).
  691. reg1({_,g,_} = Key, Value) ->
  692. %% anything global
  693. ?CHK_DIST,
  694. gproc_dist:reg(Key, Value);
  695. reg1({p,l,_} = Key, Value) ->
  696. local_reg(Key, Value);
  697. reg1({a,l,_} = Key, undefined) ->
  698. call({reg, Key, undefined});
  699. reg1({c,l,_} = Key, Value) when is_integer(Value) ->
  700. call({reg, Key, Value});
  701. reg1({n,l,_} = Key, Value) ->
  702. call({reg, Key, Value});
  703. reg1(_, _) ->
  704. ?THROW_GPROC_ERROR(badarg).
  705. %% @spec reg_shared(Key::key()) -> true
  706. %%
  707. %% @doc Register a resource, but don't tie it to a particular process.
  708. %%
  709. %% `reg_shared({c,l,C}) -> reg_shared({c,l,C}, 0).'
  710. %% `reg_shared({a,l,A}) -> reg_shared({a,l,A}, undefined).'
  711. %% @end
  712. reg_shared(Key) ->
  713. ?CATCH_GPROC_ERROR(reg_shared1(Key), [Key]).
  714. reg_shared1({c,_,_} = Key) ->
  715. reg_shared(Key, 0);
  716. reg_shared1({a,_,_} = Key) ->
  717. reg_shared(Key, undefined).
  718. %% @spec reg_shared(Key::key(), Value) -> true
  719. %%
  720. %% @doc Register a resource, but don't tie it to a particular process.
  721. %%
  722. %% Shared resources are all unique. They remain until explicitly unregistered
  723. %% (using {@link unreg_shared/1}). The types of shared resources currently
  724. %% supported are `counter' and `aggregated counter'. In listings and query
  725. %% results, shared resources appear as other similar resources, except that
  726. %% `Pid == shared'. To wit, update_counter({c,l,myCounter}, 1, shared) would
  727. %% increment the shared counter `myCounter' with 1, provided it exists.
  728. %%
  729. %% A shared aggregated counter will track updates in exactly the same way as
  730. %% an aggregated counter which is owned by a process.
  731. %% @end
  732. %%
  733. reg_shared(Key, Value) ->
  734. ?CATCH_GPROC_ERROR(reg_shared1(Key, Value), [Key, Value]).
  735. reg_shared1({_,g,_} = Key, Value) ->
  736. %% anything global
  737. ?CHK_DIST,
  738. gproc_dist:reg_shared(Key, Value);
  739. reg_shared1({a,l,_} = Key, undefined) ->
  740. call({reg_shared, Key, undefined});
  741. reg_shared1({c,l,_} = Key, Value) when is_integer(Value) ->
  742. call({reg_shared, Key, Value});
  743. reg_shared1(_, _) ->
  744. ?THROW_GPROC_ERROR(badarg).
  745. %% @spec mreg(type(), scope(), [{Key::any(), Value::any()}]) -> true
  746. %%
  747. %% @doc Register multiple {Key,Value} pairs of a given type and scope.
  748. %%
  749. %% This function is more efficient than calling {@link reg/2} repeatedly.
  750. %% It is also atomic in regard to unique names; either all names are registered
  751. %% or none are.
  752. %% @end
  753. mreg(T, C, KVL) ->
  754. ?CATCH_GPROC_ERROR(mreg1(T, C, KVL), [T, C, KVL]).
  755. mreg1(T, g, KVL) ->
  756. ?CHK_DIST,
  757. gproc_dist:mreg(T, KVL);
  758. mreg1(T, l, KVL) when T==a; T==n ->
  759. if is_list(KVL) ->
  760. call({mreg, T, l, KVL});
  761. true ->
  762. erlang:error(badarg)
  763. end;
  764. mreg1(p, l, KVL) ->
  765. local_mreg(p, KVL);
  766. mreg1(_, _, _) ->
  767. ?THROW_GPROC_ERROR(badarg).
  768. %% @spec munreg(type(), scope(), [Key::any()]) -> true
  769. %%
  770. %% @doc Unregister multiple Key items of a given type and scope.
  771. %%
  772. %% This function is usually more efficient than calling {@link unreg/1}
  773. %% repeatedly.
  774. %% @end
  775. munreg(T, C, L) ->
  776. ?CATCH_GPROC_ERROR(munreg1(T, C, L), [T, C, L]).
  777. munreg1(T, g, L) ->
  778. ?CHK_DIST,
  779. gproc_dist:munreg(T, existing(T,g,L));
  780. munreg1(T, l, L) when T==a; T==n ->
  781. if is_list(L) ->
  782. call({munreg, T, l, existing(T,l,L)});
  783. true ->
  784. erlang:error(badarg)
  785. end;
  786. munreg1(p, l, L) ->
  787. local_munreg(p, existing(p,l,L));
  788. munreg1(_, _, _) ->
  789. ?THROW_GPROC_ERROR(badarg).
  790. existing(T,Scope,L) ->
  791. Keys = if T==p; T==c ->
  792. [{{T,Scope,K}, self()} || K <- L];
  793. T==a; T==n ->
  794. [{{T,Scope,K}, T} || K <- L]
  795. end,
  796. _ = [case ets:member(?TAB, K) of
  797. false -> erlang:error(badarg);
  798. true -> true
  799. end || K <- Keys],
  800. L.
  801. %% @spec (Key:: key()) -> true
  802. %%
  803. %% @doc Unregister a name or property.
  804. %% @end
  805. unreg(Key) ->
  806. ?CATCH_GPROC_ERROR(unreg1(Key), [Key]).
  807. unreg1(Key) ->
  808. case Key of
  809. {_, g, _} ->
  810. ?CHK_DIST,
  811. gproc_dist:unreg(Key);
  812. {T, l, _} when T == n;
  813. T == a -> call({unreg, Key});
  814. {_, l, _} ->
  815. case ets:member(?TAB, {Key,self()}) of
  816. true ->
  817. _ = gproc_lib:remove_reg(Key, self(), unreg),
  818. true;
  819. false ->
  820. ?THROW_GPROC_ERROR(badarg)
  821. end
  822. end.
  823. %% @spec (Key:: key()) -> true
  824. %%
  825. %% @doc Unregister a shared resource.
  826. %% @end
  827. unreg_shared(Key) ->
  828. ?CATCH_GPROC_ERROR(unreg_shared1(Key), [Key]).
  829. unreg_shared1(Key) ->
  830. case Key of
  831. {_, g, _} ->
  832. ?CHK_DIST,
  833. gproc_dist:unreg_shared(Key);
  834. {T, l, _} when T == c;
  835. T == a -> call({unreg_shared, Key});
  836. _ ->
  837. ?THROW_GPROC_ERROR(badarg)
  838. end.
  839. %% @spec (key(), pid()) -> yes | no
  840. %%
  841. %% @doc Behaviour support callback
  842. %% @end
  843. register_name({n,_,_} = Name, Pid) when Pid == self() ->
  844. try reg(Name), yes
  845. catch
  846. error:_ ->
  847. no
  848. end.
  849. %% @equiv unreg/1
  850. unregister_name(Key) ->
  851. unreg(Key).
  852. %% @spec (Continuation ::term()) -> {[Match],Continuation} | '$end_of_table'
  853. %% @doc
  854. %% see http://www.erlang.org/doc/man/ets.html#select-1
  855. %% @end
  856. select({?TAB, _, _, _, _, _, _, _} = Continuation) ->
  857. ets:select(Continuation);
  858. %% @spec (select_pattern()) -> list(sel_object())
  859. %% @doc
  860. %% @equiv select(all, Pat)
  861. %% @end
  862. select(Pat) ->
  863. select(all, Pat).
  864. %% @spec (Context::context(), Pat::sel_pattern()) -> [{Key, Pid, Value}]
  865. %%
  866. %% @doc Perform a select operation on the process registry.
  867. %%
  868. %% The physical representation in the registry may differ from the above,
  869. %% but the select patterns are transformed appropriately.
  870. %% @end
  871. select(Context, Pat) ->
  872. ets:select(?TAB, pattern(Pat, Context)).
  873. %% @spec (Context::context(), Pat::sel_patten(), Limit::integer()) ->
  874. %% {[Match],Continuation} | '$end_of_table'
  875. %% @doc Like {@link select/2} but returns Limit objects at a time.
  876. %%
  877. %% See [http://www.erlang.org/doc/man/ets.html#select-3].
  878. %% @end
  879. select(Context, Pat, Limit) ->
  880. ets:select(?TAB, pattern(Pat, Context), Limit).
  881. %% @spec (select_pattern()) -> list(sel_object())
  882. %% @doc
  883. %% @equiv select_count(all, Pat)
  884. %% @end
  885. select_count(Pat) ->
  886. select_count(all, Pat).
  887. %% @spec (Context::context(), Pat::sel_pattern()) -> [{Key, Pid, Value}]
  888. %%
  889. %% @doc Perform a select_count operation on the process registry.
  890. %%
  891. %% The physical representation in the registry may differ from the above,
  892. %% but the select patterns are transformed appropriately.
  893. %% @end
  894. select_count(Context, Pat) ->
  895. ets:select_count(?TAB, pattern(Pat, Context)).
  896. %%% Local properties can be registered in the local process, since
  897. %%% no other process can interfere.
  898. %%%
  899. local_reg(Key, Value) ->
  900. case gproc_lib:insert_reg(Key, Value, self(), l) of
  901. false -> ?THROW_GPROC_ERROR(badarg);
  902. true -> monitor_me()
  903. end.
  904. local_mreg(_, []) -> true;
  905. local_mreg(T, [_|_] = KVL) ->
  906. case gproc_lib:insert_many(T, l, KVL, self()) of
  907. false -> ?THROW_GPROC_ERROR(badarg);
  908. {true,_} -> monitor_me()
  909. end.
  910. local_munreg(T, L) when T==p; T==c ->
  911. _ = [gproc_lib:remove_reg({T,l,K}, self(), unreg) || K <- L],
  912. true.
  913. %% @spec (Key :: key(), Value) -> true
  914. %% @doc Sets the value of the registeration entry given by Key
  915. %%
  916. %% Key is assumed to exist and belong to the calling process.
  917. %% If it doesn't, this function will exit.
  918. %%
  919. %% Value can be any term, unless the object is a counter, in which case
  920. %% it must be an integer.
  921. %% @end
  922. %%
  923. set_value(Key, Value) ->
  924. ?CATCH_GPROC_ERROR(set_value1(Key, Value), [Key, Value]).
  925. set_value1({_,g,_} = Key, Value) ->
  926. ?CHK_DIST,
  927. gproc_dist:set_value(Key, Value);
  928. set_value1({a,l,_} = Key, Value) when is_integer(Value) ->
  929. call({set, Key, Value});
  930. set_value1({n,l,_} = Key, Value) ->
  931. %% we cannot do this locally, since we have to check that the object
  932. %% exists first - not an atomic update.
  933. call({set, Key, Value});
  934. set_value1({p,l,_} = Key, Value) ->
  935. %% we _can_ to this locally, since there is no race condition - no
  936. %% other process can update our properties.
  937. case gproc_lib:do_set_value(Key, Value, self()) of
  938. true -> true;
  939. false ->
  940. erlang:error(badarg)
  941. end;
  942. set_value1({c,l,_} = Key, Value) when is_integer(Value) ->
  943. gproc_lib:do_set_counter_value(Key, Value, self());
  944. set_value1(_, _) ->
  945. ?THROW_GPROC_ERROR(badarg).
  946. %% @spec (Key) -> Value
  947. %% @doc Reads the value stored with a key registered to the current process.
  948. %%
  949. %% If no such key is registered to the current process, this function exits.
  950. %% @end
  951. get_value(Key) ->
  952. ?CATCH_GPROC_ERROR(get_value1(Key, self()), [Key]).
  953. %% @spec (Key, Pid) -> Value
  954. %% @doc Reads the value stored with a key registered to the process Pid.
  955. %%
  956. %% If `Pid == shared', the value of a shared key (see {@link reg_shared/1})
  957. %% will be read.
  958. %% @end
  959. %%
  960. get_value(Key, Pid) ->
  961. ?CATCH_GPROC_ERROR(get_value1(Key, Pid), [Key, Pid]).
  962. get_value1({T,_,_} = Key, Pid) when is_pid(Pid) ->
  963. if T==n orelse T==a ->
  964. case ets:lookup(?TAB, {Key, T}) of
  965. [{_, P, Value}] when P == Pid -> Value;
  966. _ -> ?THROW_GPROC_ERROR(badarg)
  967. end;
  968. true ->
  969. ets:lookup_element(?TAB, {Key, Pid}, 3)
  970. end;
  971. get_value1({T,_,_} = K, shared) when T==c; T==a ->
  972. Key = case T of
  973. c -> {K, shared};
  974. a -> {K, a}
  975. end,
  976. case ets:lookup(?TAB, Key) of
  977. [{_, shared, Value}] -> Value;
  978. _ -> ?THROW_GPROC_ERROR(badarg)
  979. end;
  980. get_value1(_, _) ->
  981. ?THROW_GPROC_ERROR(badarg).
  982. %% @spec (Key) -> Pid
  983. %% @doc Lookup the Pid stored with a key.
  984. %%
  985. lookup_pid({_T,_,_} = Key) ->
  986. case where(Key) of
  987. undefined -> erlang:error(badarg);
  988. P -> P
  989. end.
  990. %% @spec (Key) -> Value
  991. %% @doc Lookup the value stored with a key.
  992. %%
  993. lookup_value({T,_,_} = Key) ->
  994. if T==n orelse T==a ->
  995. ets:lookup_element(?TAB, {Key,T}, 3);
  996. true ->
  997. erlang:error(badarg)
  998. end.
  999. %% @spec (Key::key()) -> pid()
  1000. %%
  1001. %% @doc Returns the pid registered as Key
  1002. %%
  1003. %% The type of registration entry must be either name or aggregated counter.
  1004. %% Otherwise this function will exit. Use {@link lookup_pids/1} in these
  1005. %% cases.
  1006. %% @end
  1007. %%
  1008. where(Key) ->
  1009. ?CATCH_GPROC_ERROR(where1(Key), [Key]).
  1010. where1({T,_,_}=Key) ->
  1011. if T==n orelse T==a ->
  1012. case ets:lookup(?TAB, {Key,T}) of
  1013. [{_, P, _Value}] ->
  1014. case my_is_process_alive(P) of
  1015. true -> P;
  1016. false ->
  1017. undefined
  1018. end;
  1019. _ -> % may be [] or [{Key,Waiters}]
  1020. undefined
  1021. end;
  1022. true ->
  1023. ?THROW_GPROC_ERROR(badarg)
  1024. end.
  1025. %% @equiv where/1
  1026. whereis_name(Key) ->
  1027. ?CATCH_GPROC_ERROR(where1(Key), [Key]).
  1028. %% @spec (Key::key()) -> [pid()]
  1029. %%
  1030. %% @doc Returns a list of pids with the published key Key
  1031. %%
  1032. %% If the type of registration entry is either name or aggregated counter,
  1033. %% this function will return either an empty list, or a list of one pid.
  1034. %% For non-unique types, the return value can be a list of any length.
  1035. %% @end
  1036. %%
  1037. lookup_pids({T,_,_} = Key) ->
  1038. L = if T==n orelse T==a ->
  1039. ets:select(?TAB, [{{{Key,T}, '$1', '_'},[],['$1']}]);
  1040. true ->
  1041. ets:select(?TAB, [{{{Key,'_'}, '$1', '_'},[],['$1']}])
  1042. end,
  1043. [P || P <- L, my_is_process_alive(P)].
  1044. %% @spec (pid()) -> boolean()
  1045. %%
  1046. my_is_process_alive(P) when node(P) =:= node() ->
  1047. is_process_alive(P);
  1048. my_is_process_alive(_) ->
  1049. %% remote pid - assume true (too costly to find out)
  1050. true.
  1051. %% @spec (Key::key()) -> [{pid(), Value}]
  1052. %%
  1053. %% @doc Retrieve the `{Pid,Value}' pairs corresponding to Key.
  1054. %%
  1055. %% Key refer to any type of registry object. If it refers to a unique
  1056. %% object, the list will be of length 0 or 1. If it refers to a non-unique
  1057. %% object, the return value can be a list of any length.
  1058. %% @end
  1059. %%
  1060. lookup_values({T,_,_} = Key) ->
  1061. L = if T==n orelse T==a ->
  1062. ets:select(?TAB, [{{{Key,T}, '$1', '$2'},[],[{{'$1','$2'}}]}]);
  1063. true ->
  1064. ets:select(?TAB, [{{{Key,'_'}, '$1', '$2'},[],[{{'$1','$2'}}]}])
  1065. end,
  1066. [Pair || {P,_} = Pair <- L, my_is_process_alive(P)].
  1067. %% @spec (Key::key(), Incr) -> integer() | [integer()]
  1068. %% Incr = IncrVal | UpdateOp | [UpdateOp]
  1069. %% UpdateOp = IncrVal | {IncrVal, Threshold, SetValue}
  1070. %% IncrVal = integer()
  1071. %%
  1072. %% @doc Updates the counter registered as Key for the current process.
  1073. %%
  1074. %% This function works almost exactly like ets:update_counter/3
  1075. %% (see [http://www.erlang.org/doc/man/ets.html#update_counter-3]), but
  1076. %% will fail if the type of object referred to by Key is not a counter.
  1077. %%
  1078. %% Aggregated counters with the same name will be updated automatically.
  1079. %% The `UpdateOp' patterns are the same as for `ets:update_counter/3', except
  1080. %% that the position is omitted; in gproc, the value position is always `3'.
  1081. %% @end
  1082. %%
  1083. update_counter(Key, Incr) ->
  1084. ?CATCH_GPROC_ERROR(update_counter1(Key, Incr), [Key, Incr]).
  1085. update_counter1({c,l,_} = Key, Incr) ->
  1086. gproc_lib:update_counter(Key, Incr, self());
  1087. update_counter1({c,g,_} = Key, Incr) ->
  1088. ?CHK_DIST,
  1089. gproc_dist:update_counter(Key, Incr);
  1090. update_counter1(_, _) ->
  1091. ?THROW_GPROC_ERROR(badarg).
  1092. %% @spec (Key) -> {ValueBefore, ValueAfter}
  1093. %% Key = {c, Scope, Name}
  1094. %% Scope = l | g
  1095. %% ValueBefore = integer()
  1096. %% ValueAfter = integer()
  1097. %%
  1098. %% @doc Reads and resets a counter in a "thread-safe" way
  1099. %%
  1100. %% This function reads the current value of a counter and then resets it to its
  1101. %% initial value. The reset operation is done using {@link update_counter/2},
  1102. %% which allows for concurrent calls to {@link update_counter/2} without losing
  1103. %% updates. Aggregated counters are updated accordingly.
  1104. %% @end
  1105. %%
  1106. reset_counter(Key) ->
  1107. ?CATCH_GPROC_ERROR(reset_counter1(Key), [Key]).
  1108. reset_counter1({c,g,_} = Key) ->
  1109. ?CHK_DIST,
  1110. gproc_dist:reset_counter(Key);
  1111. reset_counter1({c,l,_} = Key) ->
  1112. Current = ets:lookup_element(?TAB, {Key, self()}, 3),
  1113. Initial = case ets:lookup(?TAB, {self(), Key}) of
  1114. [{_, r}] -> 0;
  1115. [{_, Opts}] ->
  1116. proplists:get_value(initial, Opts, 0)
  1117. end,
  1118. {Current, update_counter(Key, Initial - Current)}.
  1119. %% @spec (Key::key(), Incr) -> integer() | [integer()]
  1120. %% Incr = IncrVal | UpdateOp | [UpdateOp]
  1121. %% UpdateOp = IncrVal | {IncrVal, Threshold, SetValue}
  1122. %% IncrVal = integer()
  1123. %%
  1124. %% @doc Updates the shared counter registered as Key.
  1125. %%
  1126. %% This function works almost exactly like ets:update_counter/3
  1127. %% (see [http://www.erlang.org/doc/man/ets.html#update_counter-3]), but
  1128. %% will fail if the type of object referred to by Key is not a counter.
  1129. %%
  1130. %% Aggregated counters with the same name will be updated automatically.
  1131. %% The `UpdateOp' patterns are the same as for `ets:update_counter/3', except
  1132. %% that the position is omitted; in gproc, the value position is always `3'.
  1133. %% @end
  1134. %%
  1135. update_shared_counter(Key, Incr) ->
  1136. ?CATCH_GPROC_ERROR(update_shared_counter1(Key, Incr), [Key, Incr]).
  1137. update_shared_counter1({c,g,_} = Key, Incr) ->
  1138. ?CHK_DIST,
  1139. gproc_dist:update_shared_counter(Key, Incr);
  1140. update_shared_counter1({c,l,_} = Key, Incr) ->
  1141. gproc_lib:update_counter(Key, Incr, shared).
  1142. %% @spec (From::key(), To::pid() | key()) -> undefined | pid()
  1143. %%
  1144. %% @doc Atomically transfers the key `From' to the process identified by `To'.
  1145. %%
  1146. %% This function transfers any gproc key (name, property, counter, aggr counter)
  1147. %% from one process to another, and returns the pid of the new owner.
  1148. %%
  1149. %% `To' must be either a pid or a unique name (name or aggregated counter), but
  1150. %% does not necessarily have to resolve to an existing process. If there is
  1151. %% no process registered with the `To' key, `give_away/2' returns `undefined',
  1152. %% and the `From' key is effectively unregistered.
  1153. %%
  1154. %% It is allowed to give away a key to oneself, but of course, this operation
  1155. %% will have no effect.
  1156. %%
  1157. %% Fails with `badarg' if the calling process does not have a `From' key
  1158. %% registered.
  1159. %% @end
  1160. give_away(Key, ToPid) ->
  1161. ?CATCH_GPROC_ERROR(give_away1(Key, ToPid), [Key, ToPid]).
  1162. give_away1({_,l,_} = Key, ToPid) when is_pid(ToPid), node(ToPid) == node() ->
  1163. call({give_away, Key, ToPid});
  1164. give_away1({_,l,_} = Key, {n,l,_} = ToKey) ->
  1165. call({give_away, Key, ToKey});
  1166. give_away1({_,g,_} = Key, To) ->
  1167. ?CHK_DIST,
  1168. gproc_dist:give_away(Key, To).
  1169. %% @spec () -> ok
  1170. %%
  1171. %% @doc Unregister all items of the calling process and inform gproc
  1172. %% to forget about the calling process.
  1173. %%
  1174. %% This function is more efficient than letting gproc perform these
  1175. %% cleanup operations.
  1176. %% @end
  1177. goodbye() ->
  1178. process_is_down(self()).
  1179. %% @spec (Key::key(), Msg::any()) -> Msg
  1180. %%
  1181. %% @doc Sends a message to the process, or processes, corresponding to Key.
  1182. %%
  1183. %% If Key belongs to a unique object (name or aggregated counter), this
  1184. %% function will send a message to the corresponding process, or fail if there
  1185. %% is no such process. If Key is for a non-unique object type (counter or
  1186. %% property), Msg will be send to all processes that have such an object.
  1187. %% @end
  1188. %%
  1189. send(Key, Msg) ->
  1190. ?CATCH_GPROC_ERROR(send1(Key, Msg), [Key, Msg]).
  1191. send1({T,C,_} = Key, Msg) when C==l; C==g ->
  1192. if T == n orelse T == a ->
  1193. case ets:lookup(?TAB, {Key, T}) of
  1194. [{_, Pid, _}] ->
  1195. Pid ! Msg;
  1196. _ ->
  1197. ?THROW_GPROC_ERROR(badarg)
  1198. end;
  1199. T==p orelse T==c ->
  1200. %% BUG - if the key part contains select wildcards, we may end up
  1201. %% sending multiple messages to the same pid
  1202. lists:foreach(fun(Pid) ->
  1203. Pid ! Msg
  1204. end, lookup_pids(Key)),
  1205. Msg;
  1206. true ->
  1207. erlang:error(badarg)
  1208. end;
  1209. send1(_, _) ->
  1210. ?THROW_GPROC_ERROR(badarg).
  1211. %% @spec (Context :: context()) -> key() | '$end_of_table'
  1212. %%
  1213. %% @doc Behaves as ets:first(Tab) for a given type of registration object.
  1214. %%
  1215. %% See [http://www.erlang.org/doc/man/ets.html#first-1].
  1216. %% The registry behaves as an ordered_set table.
  1217. %% @end
  1218. %%
  1219. first(Context) ->
  1220. {S, T} = get_s_t(Context),
  1221. {HeadPat,_} = headpat({S, T}, '_', '_', '_'),
  1222. case ets:select(?TAB, [{HeadPat,[],[{element,1,'$_'}]}], 1) of
  1223. {[First], _} ->
  1224. First;
  1225. _ ->
  1226. '$end_of_table'
  1227. end.
  1228. %% @spec (Context :: context()) -> key() | '$end_of_table'
  1229. %%
  1230. %% @doc Behaves as ets:last(Tab) for a given type of registration object.
  1231. %%
  1232. %% See [http://www.erlang.org/doc/man/ets.html#last-1].
  1233. %% The registry behaves as an ordered_set table.
  1234. %% @end
  1235. %%
  1236. last(Context) ->
  1237. {S, T} = get_s_t(Context),
  1238. S1 = if S == '_'; S == l -> m; % 'm' comes after 'l'
  1239. S == g -> h % 'h' comes between 'g' & 'l'
  1240. end,
  1241. Beyond = {{T,S1,[]},[]},
  1242. step(ets:prev(?TAB, Beyond), S, T).
  1243. %% @spec (Context::context(), Key::key()) -> key() | '$end_of_table'
  1244. %%
  1245. %% @doc Behaves as ets:next(Tab,Key) for a given type of registration object.
  1246. %%
  1247. %% See [http://www.erlang.org/doc/man/ets.html#next-2].
  1248. %% The registry behaves as an ordered_set table.
  1249. %% @end
  1250. %%
  1251. next(Context, K) ->
  1252. {S,T} = get_s_t(Context),
  1253. step(ets:next(?TAB,K), S, T).
  1254. %% @spec (Context::context(), Key::key()) -> key() | '$end_of_table'
  1255. %%
  1256. %% @doc Behaves as ets:prev(Tab,Key) for a given type of registration object.
  1257. %%
  1258. %% See [http://www.erlang.org/doc/man/ets.html#prev-2].
  1259. %% The registry behaves as an ordered_set table.
  1260. %% @end
  1261. %%
  1262. prev(Context, K) ->
  1263. {S, T} = get_s_t(Context),
  1264. step(ets:prev(?TAB, K), S, T).
  1265. step(Key, '_', '_') ->
  1266. case Key of
  1267. {{_,_,_},_} -> Key;
  1268. _ -> '$end_of_table'
  1269. end;
  1270. step(Key, '_', T) ->
  1271. case Key of
  1272. {{T,_,_},_} -> Key;
  1273. _ -> '$end_of_table'
  1274. end;
  1275. step(Key, S, '_') ->
  1276. case Key of
  1277. {{_, S, _}, _} -> Key;
  1278. _ -> '$end_of_table'
  1279. end;
  1280. step(Key, S, T) ->
  1281. case Key of
  1282. {{T, S, _}, _} -> Key;
  1283. _ -> '$end_of_table'
  1284. end.
  1285. %% @spec (Pid::pid()) -> ProcessInfo
  1286. %% ProcessInfo = [{gproc, [{Key,Value}]} | ProcessInfo]
  1287. %%
  1288. %% @doc Similar to `process_info(Pid)' but with additional gproc info.
  1289. %%
  1290. %% Returns the same information as process_info(Pid), but with the
  1291. %% addition of a `gproc' information item, containing the `{Key,Value}'
  1292. %% pairs registered to the process.
  1293. %% @end
  1294. info(Pid) when is_pid(Pid) ->
  1295. Items = [?MODULE | [ I || {I,_} <- process_info(self())]],
  1296. [info(Pid,I) || I <- Items].
  1297. %% @spec (Pid::pid(), Item::atom()) -> {Item, Info}
  1298. %%
  1299. %% @doc Similar to process_info(Pid, Item), but with additional gproc info.
  1300. %%
  1301. %% For `Item = gproc', this function returns a list of `{Key, Value}' pairs
  1302. %% registered to the process Pid. For other values of Item, it returns the
  1303. %% same as [http://www.erlang.org/doc/man/erlang.html#process_info-2].
  1304. %% @end
  1305. info(Pid, gproc) ->
  1306. gproc_info(Pid, '_');
  1307. info(Pid, {gproc, Pat}) ->
  1308. gproc_info(Pid, Pat);
  1309. info(Pid, current_function) ->
  1310. {_, T} = process_info(Pid, backtrace),
  1311. info_cur_f(T, process_info(Pid, current_function));
  1312. info(Pid, I) ->
  1313. process_info(Pid, I).
  1314. %% We don't want to return the internal gproc:info() function as current
  1315. %% function, so we grab the 'backtrace' and extract the call stack from it,
  1316. %% filtering out the functions gproc:info/_ and gproc:'-info/1-lc...' entries.
  1317. %%
  1318. %% This is really an indication that wrapping the process_info() BIF was a
  1319. %% bad idea to begin with... :P
  1320. %%
  1321. info_cur_f(T, Default) ->
  1322. {match, Matches} = re:run(T,<<"\\(([^\\)]+):(.+)/([0-9]+)">>,
  1323. [global,{capture,[1,2,3],list}]),
  1324. case lists:dropwhile(fun(["gproc","info",_]) -> true;
  1325. (["gproc","'-info/1-lc" ++ _, _]) -> true;
  1326. (_) -> false
  1327. end, Matches) of
  1328. [] ->
  1329. Default;
  1330. [[M,F,A]|_] ->
  1331. {current_function,
  1332. {to_atom(M), to_atom(F), list_to_integer(A)}}
  1333. end.
  1334. to_atom(S) ->
  1335. case erl_scan:string(S) of
  1336. {ok, [{atom,_,A}|_],_} ->
  1337. A;
  1338. _ ->
  1339. list_to_atom(S)
  1340. end.
  1341. gproc_info(Pid, Pat) ->
  1342. Keys = ets:select(?TAB, [{ {{Pid,Pat}, '_'}, [], [{element,2,
  1343. {element,1,'$_'}}] }]),
  1344. {?MODULE, lists:zf(
  1345. fun(K) ->
  1346. try V = get_value(K, Pid),
  1347. {true, {K,V}}
  1348. catch
  1349. error:_ ->
  1350. false
  1351. end
  1352. end, Keys)}.
  1353. %% @spec () -> ok
  1354. %%
  1355. %% @doc Similar to the built-in shell command `i()' but inserts information
  1356. %% about names and properties registered in Gproc, where applicable.
  1357. %% @end
  1358. i() ->
  1359. gproc_info:i().
  1360. %%% ==========================================================
  1361. %% @hidden
  1362. handle_cast({monitor_me, Pid}, S) ->
  1363. erlang:monitor(process, Pid),
  1364. {noreply, S};
  1365. handle_cast({audit_process, Pid}, S) ->
  1366. case is_process_alive(Pid) of
  1367. false ->
  1368. process_is_down(Pid);
  1369. true ->
  1370. ignore
  1371. end,
  1372. {noreply, S};
  1373. handle_cast({cancel_wait, Pid, {T,_,_} = Key, Ref}, S) ->
  1374. _ = case ets:lookup(?TAB, {Key,T}) of
  1375. [{_, Waiters}] ->
  1376. gproc_lib:remove_wait(Key, Pid, Ref, Waiters);
  1377. _ ->
  1378. ignore
  1379. end,
  1380. {noreply, S};
  1381. handle_cast({cancel_wait_or_monitor, Pid, {T,_,_} = Key}, S) ->
  1382. _ = case ets:lookup(?TAB, {Key, T}) of
  1383. [{_, Waiters}] ->
  1384. gproc_lib:remove_wait(Key, Pid, all, Waiters);
  1385. [{_, OtherPid, _}] ->
  1386. gproc_lib:remove_monitors(Key, OtherPid, Pid);
  1387. _ ->
  1388. ok
  1389. end,
  1390. {noreply, S}.
  1391. %% @hidden
  1392. handle_call({reg, {_T,l,_} = Key, Val}, {Pid,_}, S) ->
  1393. case try_insert_reg(Key, Val, Pid) of
  1394. true ->
  1395. _ = gproc_lib:ensure_monitor(Pid,l),
  1396. {reply, true, S};
  1397. false ->
  1398. {reply, badarg, S}
  1399. end;
  1400. handle_call({monitor, {T,l,_} = Key, Pid}, _From, S)
  1401. when T==n; T==a ->
  1402. Ref = make_ref(),
  1403. _ = case where(Key) of
  1404. undefined ->
  1405. Pid ! {gproc, unreg, Ref, Key};
  1406. RegPid ->
  1407. case ets:lookup(?TAB, {RegPid, Key}) of
  1408. [{K,r}] ->
  1409. ets:insert(?TAB, {K, [{monitor, [{Pid,Ref}]}]});
  1410. [{K, Opts}] ->
  1411. ets:insert(?TAB, {K, gproc_lib:add_monitor(Opts, Pid, Ref)})
  1412. end
  1413. end,
  1414. {reply, Ref, S};
  1415. handle_call({demonitor, {T,l,_} = Key, Ref, Pid}, _From, S)
  1416. when T==n; T==a ->
  1417. _ = case where(Key) of
  1418. undefined ->
  1419. ok; % be nice
  1420. RegPid ->
  1421. case ets:lookup(?TAB, {RegPid, Key}) of
  1422. [{_K,r}] ->
  1423. ok; % be nice
  1424. [{K, Opts}] ->
  1425. ets:insert(?TAB, {K, gproc_lib:remove_monitor(
  1426. Opts, Pid, Ref)})
  1427. end
  1428. end,
  1429. {reply, ok, S};
  1430. handle_call({reg_shared, {_T,l,_} = Key, Val}, _From, S) ->
  1431. case try_insert_reg(Key, Val, shared) of
  1432. %% case try_insert_shared(Key, Val) of
  1433. true ->
  1434. {reply, true, S};
  1435. false ->
  1436. {reply, badarg, S}
  1437. end;
  1438. handle_call({unreg, {_,l,_} = Key}, {Pid,_}, S) ->
  1439. case ets:lookup(?TAB, {Pid,Key}) of
  1440. [{_, r}] ->
  1441. _ = gproc_lib:remove_reg(Key, Pid, unreg),
  1442. {reply, true, S};
  1443. [{_, Opts}] when is_list(Opts) ->
  1444. _ = gproc_lib:remove_reg(Key, Pid, unreg, Opts),
  1445. {reply, true, S};
  1446. [] ->
  1447. {reply, badarg, S}
  1448. end;
  1449. handle_call({unreg_shared, {_,l,_} = Key}, _, S) ->
  1450. _ = case ets:lookup(?TAB, {shared, Key}) of
  1451. [{_, r}] ->
  1452. _ = gproc_lib:remove_reg(Key, shared, unreg);
  1453. [{_, Opts}] ->
  1454. _ = gproc_lib:remove_reg(Key, shared, unreg, Opts);
  1455. [] ->
  1456. %% don't crash if shared key already unregged.
  1457. ok
  1458. end,
  1459. {reply, true, S};
  1460. handle_call({await, {_,l,_} = Key, Pid}, From, S) ->
  1461. %% Passing the pid explicitly is needed when leader_call is used,
  1462. %% since the Pid given as From in the leader is the local gen_leader
  1463. %% instance on the calling node.
  1464. case gproc_lib:await(Key, Pid, From) of
  1465. noreply ->
  1466. {noreply, S};
  1467. {reply, Reply, _} ->
  1468. {reply, Reply, S}
  1469. end;
  1470. handle_call({mreg, T, l, L}, {Pid,_}, S) ->
  1471. try gproc_lib:insert_many(T, l, L, Pid) of
  1472. {true,_} -> {reply, true, S};
  1473. false -> {reply, badarg, S}
  1474. catch
  1475. error:_ -> {reply, badarg, S}
  1476. end;
  1477. handle_call({munreg, T, l, L}, {Pid,_}, S) ->
  1478. _ = gproc_lib:remove_many(T, l, L, Pid),
  1479. {reply, true, S};
  1480. handle_call({set, {_,l,_} = Key, Value}, {Pid,_}, S) ->
  1481. case gproc_lib:do_set_value(Key, Value, Pid) of
  1482. true ->
  1483. {reply, true, S};
  1484. false ->
  1485. {reply, badarg, S}
  1486. end;
  1487. handle_call({audit_process, Pid}, _, S) ->
  1488. _ = case is_process_alive(Pid) of
  1489. false ->
  1490. process_is_down(Pid);
  1491. true ->
  1492. ignore
  1493. end,
  1494. {reply, ok, S};
  1495. handle_call({give_away, Key, To}, {Pid,_}, S) ->
  1496. Reply = do_give_away(Key, To, Pid),
  1497. {reply, Reply, S};
  1498. handle_call(_, _, S) ->
  1499. {reply, badarg, S}.
  1500. %% @hidden
  1501. handle_info({'DOWN', _MRef, process, Pid, _}, S) ->
  1502. _ = process_is_down(Pid),
  1503. {noreply, S};
  1504. handle_info(_, S) ->
  1505. {noreply, S}.
  1506. %% @hidden
  1507. code_change(_FromVsn, S, _Extra) ->
  1508. %% We have changed local monitor markers from {Pid} to {Pid,l}.
  1509. _ = case ets:select(?TAB, [{{'$1'},[],['$1']}]) of
  1510. [] ->
  1511. ok;
  1512. Pids ->
  1513. ets:insert(?TAB, [{P,l} || P <- Pids]),
  1514. ets:select_delete(?TAB, [{{'_'},[],[true]}])
  1515. end,
  1516. {ok, S}.
  1517. %% @hidden
  1518. terminate(_Reason, _S) ->
  1519. ok.
  1520. call(Req) ->
  1521. call(Req, l).
  1522. call(Req, l) ->
  1523. chk_reply(gen_server:call(?MODULE, Req));
  1524. call(Req, g) ->
  1525. chk_reply(gproc_dist:leader_call(Req)).
  1526. chk_reply(Reply) ->
  1527. case Reply of
  1528. badarg -> ?THROW_GPROC_ERROR(badarg);
  1529. _ -> Reply
  1530. end.
  1531. cast(Msg) ->
  1532. cast(Msg, l).
  1533. cast(Msg, l) ->
  1534. gen_server:cast(?MODULE, Msg);
  1535. cast(Msg, g) ->
  1536. gproc_dist:leader_cast(Msg).
  1537. try_insert_reg({T,l,_} = Key, Val, Pid) ->
  1538. case gproc_lib:insert_reg(Key, Val, Pid, l) of
  1539. false ->
  1540. case ets:lookup(?TAB, {Key,T}) of
  1541. %% In this particular case, the lookup cannot result in
  1542. %% [{_, Waiters}], since the insert_reg/4 function would
  1543. %% have succeeded then.
  1544. [{_, OtherPid, _}] ->
  1545. case is_process_alive(OtherPid) of
  1546. true ->
  1547. false;
  1548. false ->
  1549. process_is_down(OtherPid),
  1550. true = gproc_lib:insert_reg(Key, Val, Pid, l)
  1551. end;
  1552. [] ->
  1553. false
  1554. end;
  1555. true ->
  1556. true
  1557. end.
  1558. %% try_insert_shared({c,l,_} = Key, Val) ->
  1559. %% ets:insert_new(?TAB, [{{Key,shared}, shared, Val}, {{shared, Key}, []}]);
  1560. %% try_insert_shared({a,l,_} = Key, Val) ->
  1561. %% ets:insert_new(?TAB, [{{Key, a}, shared, Val}, {{shared, Key}, []}]).
  1562. -spec audit_process(pid()) -> ok.
  1563. audit_process(Pid) when is_pid(Pid) ->
  1564. ok = gen_server:call(gproc, {audit_process, Pid}, infinity).
  1565. nb_audit_process(Pid) when is_pid(Pid) ->
  1566. ok = gen_server:cast(gproc, {audit_process, Pid}).
  1567. -spec process_is_down(pid()) -> ok.
  1568. process_is_down(Pid) when is_pid(Pid) ->
  1569. %% delete the monitor marker
  1570. %% io:fwrite(user, "process_is_down(~p) - ~p~n", [Pid,ets:tab2list(?TAB)]),
  1571. Marker = {Pid,l},
  1572. case ets:member(?TAB, Marker) of
  1573. false ->
  1574. ok;
  1575. true ->
  1576. Revs = ets:select(?TAB, [{{{Pid,'$1'}, '$2'},
  1577. [{'==',{element,2,'$1'},l}],
  1578. [{{'$1','$2'}}]}]),
  1579. lists:foreach(
  1580. fun({{n,l,_}=K, R}) ->
  1581. Key = {K,n},
  1582. case ets:lookup(?TAB, Key) of
  1583. [{_, Pid, _}] ->
  1584. ets:delete(?TAB, Key),
  1585. opt_notify(R, K);
  1586. [{_, Waiters}] ->
  1587. case [W || {P,_} = W <- Waiters,
  1588. P =/= Pid] of
  1589. [] ->
  1590. ets:delete(?TAB, Key);
  1591. Waiters1 ->
  1592. ets:insert(?TAB, {Key, Waiters1})
  1593. end;
  1594. [] ->
  1595. true
  1596. end;
  1597. ({{c,l,C} = K, _}) ->
  1598. Key = {K, Pid},
  1599. [{_, _, Value}] = ets:lookup(?TAB, Key),
  1600. ets:delete(?TAB, Key),
  1601. gproc_lib:update_aggr_counter(l, C, -Value);
  1602. ({{a,l,_} = K, R}) ->
  1603. ets:delete(?TAB, {K,a}),
  1604. opt_notify(R, K);
  1605. ({{p,_,_} = K, _}) ->
  1606. ets:delete(?TAB, {K, Pid})
  1607. end, Revs),
  1608. ets:select_delete(?TAB, [{{{Pid,{'_',l,'_'}},'_'}, [], [true]}]),
  1609. ets:delete(?TAB, Marker),
  1610. ok
  1611. end.
  1612. opt_notify(r, _) ->
  1613. ok;
  1614. opt_notify(Opts, Key) ->
  1615. gproc_lib:notify(Key, Opts).
  1616. do_give_away({T,l,_} = K, To, Pid) when T==n; T==a ->
  1617. Key = {K, T},
  1618. case ets:lookup(?TAB, Key) of
  1619. [{_, Pid, Value}] ->
  1620. %% Pid owns the reg; allowed to give_away
  1621. case pid_to_give_away_to(To) of
  1622. Pid ->
  1623. %% Give away to ourselves? Why not? We'll allow it,
  1624. %% but nothing needs to be done.
  1625. Pid;
  1626. ToPid when is_pid(ToPid) ->
  1627. ets:insert(?TAB, [{Key, ToPid, Value},
  1628. {{ToPid, K}, []}]),
  1629. _ = gproc_lib:remove_reverse_mapping({migrated,ToPid}, Pid, K),
  1630. _ = gproc_lib:ensure_monitor(ToPid, l),
  1631. ToPid;
  1632. undefined ->
  1633. _ = gproc_lib:remove_reg(K, Pid, unreg),
  1634. undefined
  1635. end;
  1636. _ ->
  1637. badarg
  1638. end;
  1639. do_give_away({T,l,_} = K, To, Pid) when T==c; T==p ->
  1640. Key = {K, Pid},
  1641. case ets:lookup(?TAB, Key) of
  1642. [{_, Pid, Value}] ->
  1643. case pid_to_give_away_to(To) of
  1644. ToPid when is_pid(ToPid) ->
  1645. ToKey = {K, ToPid},
  1646. case ets:member(?TAB, ToKey) of
  1647. true ->
  1648. badarg;
  1649. false ->
  1650. ets:insert(?TAB, [{ToKey, ToPid, Value},
  1651. {{ToPid, K}, []}]),
  1652. ets:delete(?TAB, {Pid, K}),
  1653. ets:delete(?TAB, Key),
  1654. _ = gproc_lib:ensure_monitor(ToPid, l),
  1655. ToPid
  1656. end;
  1657. undefined ->
  1658. _ = gproc_lib:remove_reg(K, Pid, {migrated, undefined}),
  1659. undefined
  1660. end;
  1661. _ ->
  1662. badarg
  1663. end.
  1664. pid_to_give_away_to(P) when is_pid(P), node(P) == node() ->
  1665. P;
  1666. pid_to_give_away_to({T,l,_} = Key) when T==n; T==a ->
  1667. case ets:lookup(?TAB, {Key, T}) of
  1668. [{_, Pid, _}] ->
  1669. Pid;
  1670. _ ->
  1671. undefined
  1672. end.
  1673. create_tabs() ->
  1674. Opts = gproc_lib:valid_opts(ets_options, [{write_concurrency,true},
  1675. {read_concurrency, true}]),
  1676. case ets:info(?TAB, name) of
  1677. undefined ->
  1678. ets:new(?TAB, [ordered_set, public, named_table | Opts]);
  1679. _ ->
  1680. ok
  1681. end.
  1682. %% @hidden
  1683. init([]) ->
  1684. set_monitors(),
  1685. {ok, #state{}}.
  1686. set_monitors() ->
  1687. set_monitors(ets:select(?TAB, [{{{'$1',l}},[],['$1']}], 100)).
  1688. set_monitors('$end_of_table') ->
  1689. ok;
  1690. set_monitors({Pids, Cont}) ->
  1691. _ = [erlang:monitor(process,Pid) || Pid <- Pids],
  1692. set_monitors(ets:select(Cont)).
  1693. monitor_me() ->
  1694. case ets:insert_new(?TAB, {{self(),l}}) of
  1695. false -> true;
  1696. true ->
  1697. cast({monitor_me,self()}),
  1698. true
  1699. end.
  1700. pattern([{'_', Gs, As}], T) ->
  1701. ?l,
  1702. {HeadPat, Vs} = headpat(T, '$1', '$2', '$3'),
  1703. [{HeadPat, rewrite(Gs,Vs), rewrite(As,Vs)}];
  1704. pattern([{{A,B,C},Gs,As}], Scope) ->
  1705. ?l,
  1706. {HeadPat, Vars} = headpat(Scope, A,B,C),
  1707. [{HeadPat, rewrite(Gs,Vars), rewrite(As,Vars)}];
  1708. pattern([{Head, Gs, As}], Scope) ->
  1709. ?l,
  1710. {S, T} = get_s_t(Scope),
  1711. case is_var(Head) of
  1712. {true,_N} ->
  1713. HeadPat = {{{T,S,'_'},'_'},'_','_'},
  1714. Vs = [{Head, obj_prod()}],
  1715. %% the headpat function should somehow verify that Head is
  1716. %% consistent with Scope (or should we add a guard?)
  1717. [{HeadPat, rewrite(Gs, Vs), rewrite(As, Vs)}];
  1718. false ->
  1719. erlang:error(badarg)
  1720. end.
  1721. %% This is the expression to use in guards and the RHS to address the whole
  1722. %% object, in its logical representation.
  1723. obj_prod() ->
  1724. {{ {element,1,{element,1,'$_'}},
  1725. {element,2,'$_'},
  1726. {element,3,'$_'} }}.
  1727. obj_prod_l() ->
  1728. [ {element,1,{element,1,'$_'}},
  1729. {element,2,'$_'},
  1730. {element,3,'$_'} ].
  1731. headpat({S, T}, V1,V2,V3) ->
  1732. headpat(type(T), scope(S), V1,V2,V3);
  1733. headpat(T, V1, V2, V3) when is_atom(T) ->
  1734. headpat(type(T), l, V1, V2, V3);
  1735. headpat(_, _, _, _) -> erlang:error(badarg).
  1736. headpat(T, C, V1,V2,V3) ->
  1737. Rf = fun(Pos) ->
  1738. {element,Pos,{element,1,{element,1,'$_'}}}
  1739. end,
  1740. K2 = if T==n orelse T==a -> T;
  1741. true -> '_'
  1742. end,
  1743. {Kp,Vars} = case V1 of
  1744. {Vt,Vc,Vn} ->
  1745. ?l,
  1746. {T1,Vs1} = subst(T,Vt,fun() -> Rf(1) end,[]),
  1747. {C1,Vs2} = subst(C,Vc,fun() -> Rf(2) end,Vs1),
  1748. {{T1,C1,Vn}, Vs2};
  1749. '_' ->
  1750. ?l,
  1751. {{T,C,'_'}, []};
  1752. _ ->
  1753. ?l,
  1754. case is_var(V1) of
  1755. {true,_} ->
  1756. {{T,C,V1}, [{V1, {element,1,
  1757. {element,1,'$_'}}}]};
  1758. false ->
  1759. erlang:error(badarg)
  1760. end
  1761. end,
  1762. {{{Kp,K2},V2,V3}, Vars}.
  1763. %% l(L) -> L.
  1764. subst(X, '_', _F, Vs) ->
  1765. {X, Vs};
  1766. subst(X, V, F, Vs) ->
  1767. case is_var(V) of
  1768. {true,_} ->
  1769. {X, [{V,F()}|Vs]};
  1770. false ->
  1771. {V, Vs}
  1772. end.
  1773. scope('_') -> '_';
  1774. scope(all) -> '_';
  1775. scope(global) -> g;
  1776. scope(local) -> l;
  1777. scope(S) when S==l; S==g -> S.
  1778. type('_') -> '_';
  1779. type(all) -> '_';
  1780. type(T) when T==n; T==p; T==c; T==a -> T;
  1781. type(names) -> n;
  1782. type(props) -> p;
  1783. type(counters) -> c;
  1784. type(aggr_counters) -> a.
  1785. rev_keypat(Context) ->
  1786. {S,T} = get_s_t(Context),
  1787. {T,S,'_'}.
  1788. get_s_t({S,T}) -> {scope(S), type(T)};
  1789. get_s_t(T) when is_atom(T) ->
  1790. {scope(all), type(T)}.
  1791. is_var('$1') -> {true,1};
  1792. is_var('$2') -> {true,2};
  1793. is_var('$3') -> {true,3};
  1794. is_var('$4') -> {true,4};
  1795. is_var('$5') -> {true,5};
  1796. is_var('$6') -> {true,6};
  1797. is_var('$7') -> {true,7};
  1798. is_var('$8') -> {true,8};
  1799. is_var('$9') -> {true,9};
  1800. is_var(X) when is_atom(X) ->
  1801. case atom_to_list(X) of
  1802. "\$" ++ Tl ->
  1803. try N = list_to_integer(Tl),
  1804. {true,N}
  1805. catch
  1806. error:_ ->
  1807. false
  1808. end;
  1809. _ ->
  1810. false
  1811. end;
  1812. is_var(_) -> false.
  1813. rewrite(Gs, R) ->
  1814. [rewrite1(G, R) || G <- Gs].
  1815. rewrite1('$_', _) ->
  1816. obj_prod();
  1817. rewrite1('$$', _) ->
  1818. obj_prod_l();
  1819. rewrite1(Guard, R) when is_tuple(Guard) ->
  1820. list_to_tuple([rewrite1(G, R) || G <- tuple_to_list(Guard)]);
  1821. rewrite1(Exprs, R) when is_list(Exprs) ->
  1822. [rewrite1(E, R) || E <- Exprs];
  1823. rewrite1(V, R) when is_atom(V) ->
  1824. case is_var(V) of
  1825. {true,_N} ->
  1826. case lists:keysearch(V, 1, R) of
  1827. {value, {_, V1}} ->
  1828. V1;
  1829. false ->
  1830. V
  1831. end;
  1832. false ->
  1833. V
  1834. end;
  1835. rewrite1(Expr, _) ->
  1836. Expr.
  1837. %% @spec () -> any()
  1838. %%
  1839. %% @doc
  1840. %% @equiv table({all, all})
  1841. %% @end
  1842. table() ->
  1843. table({all, all}).
  1844. %% @spec (Context::context()) -> any()
  1845. %%
  1846. %% @doc
  1847. %% @equiv table(Context, [])
  1848. %% @end
  1849. %%
  1850. table(Context) ->
  1851. table(Context, []).
  1852. %% @spec (Context::context(), Opts) -> any()
  1853. %%
  1854. %% @doc QLC table generator for the gproc registry.
  1855. %% Context specifies which subset of the registry should be queried.
  1856. %% See [http://www.erlang.org/doc/man/qlc.html].
  1857. %% @end
  1858. table(Context, Opts) ->
  1859. Ctxt = {_, Type} = get_s_t(Context),
  1860. [Traverse, NObjs] = [proplists:get_value(K,Opts,Def) ||
  1861. {K,Def} <- [{traverse,select}, {n_objects,100}]],
  1862. TF = case Traverse of
  1863. first_next ->
  1864. fun() -> qlc_next(Ctxt, first(Ctxt)) end;
  1865. last_prev -> fun() -> qlc_prev(Ctxt, last(Ctxt)) end;
  1866. select ->
  1867. fun(MS) -> qlc_select(select(Ctxt, MS, NObjs)) end;
  1868. {select,MS} ->
  1869. fun() -> qlc_select(select(Ctxt, MS, NObjs)) end;
  1870. _ ->
  1871. erlang:error(badarg, [Ctxt,Opts])
  1872. end,
  1873. InfoFun = fun(indices) -> [2];
  1874. (is_unique_objects) -> is_unique(Type);
  1875. (keypos) -> 1;
  1876. (is_sorted_key) -> true;
  1877. (num_of_objects) ->
  1878. %% this is just a guesstimate.
  1879. trunc(ets:info(?TAB,size) / 2.5)
  1880. end,
  1881. LookupFun =
  1882. case Traverse of
  1883. {select, _MS} -> undefined;
  1884. _ -> fun(Pos, Ks) -> qlc_lookup(Ctxt, Pos, Ks) end
  1885. end,
  1886. qlc:table(TF, [{info_fun, InfoFun},
  1887. {lookup_fun, LookupFun}] ++ [{K,V} || {K,V} <- Opts,
  1888. K =/= traverse,
  1889. K =/= n_objects]).
  1890. qlc_lookup(_Scope, 1, Keys) ->
  1891. lists:flatmap(
  1892. fun(Key) ->
  1893. ets:select(?TAB, [{ {{Key,'_'},'_','_'}, [],
  1894. [{{ {element,1,{element,1,'$_'}},
  1895. {element,2,'$_'},
  1896. {element,3,'$_'} }}] }])
  1897. end, Keys);
  1898. qlc_lookup(Scope, 2, Pids) ->
  1899. lists:flatmap(fun(Pid) ->
  1900. Found =
  1901. ets:select(?TAB, [{{{Pid, rev_keypat(Scope)}, '_'},
  1902. [], ['$_']}]),
  1903. lists:flatmap(
  1904. fun({{_,{T,_,_}=K}, _}) ->
  1905. K2 = if T==n orelse T==a -> T;
  1906. true -> Pid
  1907. end,
  1908. case ets:lookup(?TAB, {K,K2}) of
  1909. [{{Key,_},_,Value}] ->
  1910. [{Key, Pid, Value}];
  1911. [] ->
  1912. []
  1913. end
  1914. end, Found)
  1915. end, Pids).
  1916. qlc_next(_, '$end_of_table') -> [];
  1917. qlc_next(Scope, K) ->
  1918. case ets:lookup(?TAB, K) of
  1919. [{{Key,_}, Pid, V}] ->
  1920. [{Key,Pid,V}] ++ fun() -> qlc_next(Scope, next(Scope, K)) end;
  1921. [] ->
  1922. qlc_next(Scope, next(Scope, K))
  1923. end.
  1924. qlc_prev(_, '$end_of_table') -> [];
  1925. qlc_prev(Scope, K) ->
  1926. case ets:lookup(?TAB, K) of
  1927. [{{Key,_},Pid,V}] ->
  1928. [{Key,Pid,V}] ++ fun() -> qlc_prev(Scope, prev(Scope, K)) end;
  1929. [] ->
  1930. qlc_prev(Scope, prev(Scope, K))
  1931. end.
  1932. qlc_select('$end_of_table') ->
  1933. [];
  1934. qlc_select({Objects, Cont}) ->
  1935. Objects ++ fun() -> qlc_select(ets:select(Cont)) end.
  1936. is_unique(n) -> true;
  1937. is_unique(a) -> true;
  1938. is_unique(_) -> false.