Registrando un nombre de forma atómica

pp2@nereida:~/Lerlang$ cat -n register.erl               
 1  % page 150, problem 1                            
 2  % Write a function start(AnAtom. Fun) to register AnAtom 
 3  % as spawn(Fun).                                         
 4  -module(register).                                       
 5  -export([start_server/0, rf/1]).                         
 6                                                           
 7  start_server() ->                                        
 8      spawn(fun() -> tutu_server() end)                    
 9  .                                                        
10                                                           
11  tutu_server() ->                                         
12    io:format("tutu_server:~n"),                           
13    receive                                                
14      { register, From, AnAtom, Fun } ->                   
15          Owner = whereis(AnAtom),                         
16          io:format("Owner: ~p~n",[Owner]),                
17          if                                               
18            Owner =/= undefined ->                         
19              From ! {self(), false};                      
20            true ->                                        
21              io:format("tutu_server: registering function <~p>.~n",[AnAtom]),
22              Pid = spawn(fun() -> Fun() end),                                
23              register(AnAtom, Pid),                                          
24              From ! {self(), true}                                           
25          end,                                                                
26          tutu_server();                                                      
27     { From, Any } ->                                                         
28         io:format("tutu_server: received <~p> from ~p~n",[Any, From]),       
29         From ! {self(), false},
30         tutu_server();
31     Any ->
32         io:format("tutu_server: received <~p>~n",[Any]),
33         tutu_server()
34    end
35  .
36
37  rf(Pid) ->
38    Pid! { register, self(), toto, fun() -> timer(10, 1) end},
39    receive
40        {Pid, true}  ->
41            io:format("accepted request~n");
42        {Pid, false} ->
43            io:format("denied request~n");
44        Any ->
45            io:format("error: received<~p>~n",[Any])
46    end
47  .
48
49  timer(Time, I) ->
50      receive
51          cancel -> void
52          after Time ->
53             %io:format("TICK: ~p~n", [erlang:now()]),
54             if
55               I < 1000 ->
56                 %io:format("I = ~p~n", [I]),
57                 timer(Time, I+1);
58              true ->
59                 io:format("end of loop reached I = ~p~n", [I])
60             end
61      end
62  .

Ejecución:

pp2@nereida:~/Lerlang$ erl
Erlang (BEAM) emulator version 5.6.5 [source] [64-bit] [smp:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.6.5  (abort with ^G)
1> c(register).               
{ok,register}                 
2> P = register:start_server().
tutu_server:                   
<0.38.0>
3> register:rf(P).
Owner: undefined
tutu_server: registering function <toto>.
tutu_server:
accepted request
ok
4> register:rf(P).
Owner: <0.40.0>
tutu_server:
denied request
ok
end of loop reached I = 1000
5> register:rf(P).
Owner: undefined
tutu_server: registering function <toto>.
tutu_server:
accepted request
ok
6> register:rf(P).
Owner: <0.43.0>
tutu_server:
denied request
ok
7> register:rf(P).
Owner: <0.43.0>
tutu_server:
denied request
ok
8> register:rf(P).
Owner: <0.43.0>
tutu_server:
denied request
ok
end of loop reached I = 1000
9>

Casiano Rodríguez León
2012-02-29