frequenciaE.erl

text/x-erlang frequenciaE.erl — 2.1 KB

Continguts del fitxer

-module(frequenciaE).
-export([iniciar/0, stop/0, assignar/0, desassignar/1]).
-export([init/0]).

%% Aquestes sn les funcions d'arrencada s'utilitzen per crear i inicialitzar el servidor.

iniciar() ->
  register(frequencia, spawn(frequencia, init, [])).

init() ->
  process_flag(trap_exit, true),
  Frequencies = {get_frequencies(), []},
  bucle(Frequencies).

% Codificat
get_frequencies() -> [10,11,12,13,14,15].

%%  Les funcions del client

stop()           -> call(stop).
assignar()       -> call(assignar).
desassignar(Freq) -> call({desassignar, Freq}).

%% Amaguem tot el pas de missatges i el protocol de missatge en una interfcie funcional.

call(Missatge) ->
  frequencia ! {request, self(), Missatge},
  receive
    {reply, Reply} -> Reply
  end.

%% El bucle principal

bucle(Frequencies) ->
  receive
    {request, Pid, assignar} ->
      {NovesFrequencies, Reply} = assignar(Frequencies, Pid), 
	  reply(Pid, Reply), 
	  bucle(NovesFrequencies);
    {request, Pid , {desassignar, Freq}} ->
      NovesFrequencies = desassignar(Frequencies, Freq), 
	  reply(Pid, ok), 
	  bucle(NovesFrequencies);
	{'EXIT', Pid, _Reason} ->
      io:format('Llista freq assinades ~p~n',[Frequencies]),
	  NovesFrequencies = exited(Frequencies, Pid),
      bucle(NovesFrequencies);
    {request, Pid, stop} ->
      reply(Pid, ok)
  end.

reply(Pid, Reply) ->
  Pid ! {reply, Reply}.

%% Funcions d'ajuda interna que s'utilitzen per assignar i alliberar freqncies.

assignar({[], Assignat}, _Pid) -> 
	{{[], Assignat}, {error, no_frequencia}};
	
assignar({[Freq|Lliure], Assignat}, Pid) -> 
	link(Pid),
	{{Lliure, [{Freq, Pid}|Assignat]}, {ok, Freq}}.

desassignar({Lliure, Assignat}, Freq) ->
	{value,{Freq,Pid}} = lists:keysearch(Freq,1,Assignat),
	unlink(Pid),
	NouAssignat=lists:keydelete(Freq, 1, Assignat),
	{[Freq|Lliure],  NouAssignat}.
	
exited({Lliure, Assignat}, Pid) ->
  case lists:keysearch(Pid,2,Assignat) of
    {value,{Freq,Pid}} ->
       NouAssignat = lists:keydelete(Freq,1,Assignat),
      {[Freq|Lliure],NouAssignat};
    false ->
      {Lliure,Assignat}
  end.