diff options
Diffstat (limited to 'lib/stdlib/test/dummy_via.erl')
| -rw-r--r-- | lib/stdlib/test/dummy_via.erl | 94 | 
1 files changed, 94 insertions, 0 deletions
diff --git a/lib/stdlib/test/dummy_via.erl b/lib/stdlib/test/dummy_via.erl new file mode 100644 index 0000000000..e405811cbe --- /dev/null +++ b/lib/stdlib/test/dummy_via.erl @@ -0,0 +1,94 @@ +-module(dummy_via). +-export([reset/0, +	 register_name/2, +	 whereis_name/1, +	 unregister_name/1, +	 send/2]). + + +reset() -> +    P = whereis(?MODULE), +    catch unlink(P), +    Ref = erlang:monitor(process, P), +    catch exit(P, kill), +    receive {'DOWN',Ref,_,_,_} -> ok end, +    Me = self(), +    Pid = spawn_link(fun() -> +			     register(?MODULE, self()), +			     Me ! {self(), started}, +			     loop([]) +		     end), +    receive +	{Pid, started} -> +	    Pid +    after 10000 -> +	    exit(timeout) +    end. + +register_name(Name, Pid) when is_pid(Pid) -> +    call({register_name, Name, Pid}). + +unregister_name(Name) -> +    call({unregister_name, Name}). + +whereis_name(Name) -> +    call({whereis_name, Name}). + +send(Name, Msg) -> +    case whereis_name(Name) of +	undefined -> +	    exit({badarg, {Name, Msg}}); +	Pid when is_pid(Pid) -> +	    Pid ! Msg, +	    Pid +    end. + +call(Req) -> +    MRef = erlang:monitor(process, ?MODULE), +    ?MODULE ! {self(), MRef, Req}, +    receive +	{'DOWN', MRef, _, _, _} -> +	    erlang:error(badarg); +	{MRef, badarg} -> +	    erlang:error(badarg); +	{MRef, Reply} -> +	    Reply +    after 5000 -> +	    erlang:error(timeout) +    end. + +loop(Reg) -> +    receive +	{'DOWN', _, _, P, _} when is_pid(P) -> +	    loop([X || {_,Pid,_} = X <- Reg, Pid =/= P]); +	{From, Ref, Request} when is_pid(From), is_reference(Ref) -> +	    {Reply, NewReg} = handle_request(Request, Reg), +	    From ! {Ref, Reply}, +	    loop(NewReg) +    end. + +handle_request({register_name, Name, Pid}, Reg) when is_pid(Pid) -> +    case lists:keyfind(Name, 1, Reg) of +	false -> +	    Ref = erlang:monitor(process, Pid), +	    {yes, [{Name, Pid, Ref}|Reg]}; +	_ -> +	    {no, Reg} +    end; +handle_request({whereis_name, Name}, Reg) -> +    case lists:keyfind(Name, 1, Reg) of +	{_, Pid, _} -> +	    {Pid, Reg}; +	false -> +	    {undefined, Reg} +    end; +handle_request({unregister_name, Name}, Reg) -> +    case lists:keyfind(Name, 1, Reg) of +	{_, _, Ref} -> +	    catch erlang:demonitor(Ref); +	_ -> +	    ok +    end, +    {ok, lists:keydelete(Name, 1, Reg)}; +handle_request(_, Reg) -> +    {badarg, Reg}.  | 
