ensure_started
Ulf Wiger
etxuwig@REDACTED
Thu Feb 27 16:29:00 CET 2003
I posted the following suggestion a few weeks ago, now
slightly modified:
ensure_started() ->
Id = {{?MODULE,ensure_started}, self()},
global:trans(
Id, fun() ->
case whereis(?MODULE) of
undefined ->
Pid = proc_lib:spawn(?MODULE,init,[]),
register(?MODULE, Pid),
{ok, Pid};
Pid when pid(Pid) ->
{ok, Pid}
end
end, [node()]).
Since you know that the ensure_started() call is always
local you can use global:trans(Id, Fun, [node()]) which will
cut it down to two gen_server calls to the nearest global
name server.
(http://www.erlang.org/ml-archive/erlang-questions/200302/msg00391.html)
/Uffe
On Thu, 27 Feb 2003, Vlad Dumitrescu (EAW) wrote:
>Hi,
>
>I wonder about a thing. The following fun is an often used
>way to ensure that one uses "the one and only" server
>called ?MODULE.
>
>ensure_started() ->
> case whereis(?MODULE) of
> undefined ->
> Pid = proc_lib:spawn(?MODULE, init, []),
> register(?MODULE, Pid),
> {ok, Pid};
> Pid ->
> {ok, Pid}
> end.
>
>Now I just had to implement this functionality and I noticed that the above isn't really correct. In fact, I even got a case during tests when the error showed up.
>
>start() ->
> case whereis(?SERVER) of
> undefined ->
> Pid = spawn(fun init/0),
> %% some other process might have already registered it
> %% since we last checked
> case catch register(?SERVER, Pid) of
> true ->
> %% we're the real thing
> Pid;
> _ ->
> %% other process got there first, use that one
> Pid ! stop,
> %% try again!
> start()
> end;
> Pid ->
> Pid
> end.
>
>I thought to share this, as it might cause confusion. Maybe it's not so often the scheduler will interrrupt start() just in the wrong place, but as I said, it happened to me (in relation with the debugger running).
>
>best regards,
>Vlad
>
--
Ulf Wiger, Senior Specialist,
/ / / Architecture & Design of Carrier-Class Software
/ / / Strategic Product & System Management
/ / / Ericsson AB, Connectivity and Control Nodes
More information about the erlang-questions
mailing list