Skip to content

Instantly share code, notes, and snippets.

@abhishekc-sharma
Created April 16, 2017 05:21
Show Gist options
  • Save abhishekc-sharma/045a77fc7e6b5bc3a6b3e576c70169b3 to your computer and use it in GitHub Desktop.
Save abhishekc-sharma/045a77fc7e6b5bc3a6b3e576c70169b3 to your computer and use it in GitHub Desktop.
-module(frequency).
-export([start/0, stop/0, allocate/0, deallocate/1, client/1]).
-export([init_supervisor/0, init_server/0]).
%% Server interface
% Start the supervisor and the frequency server
start() ->
register(frequency_supervisor, spawn(frequency, init_supervisor, [])).
% Stop the supervisor and the frequency server
stop() ->
frequency_supervisor ! {request, self(), stop},
receive
{reply, Reply} -> Reply
end.
%% Server implementation
% Initialize and start supervisor
init_supervisor() ->
process_flag(trap_exit, true),
register(frequency_server, spawn_link(frequency, init_server, [])),
loop_supervisor().
% Main supervisor loop
loop_supervisor() ->
receive
{request, Pid, stop} ->
exit(whereis(frequency_server), kill),
Pid ! {reply, stopped};
% When server dies, restart it
{'EXIT', whereis(frequency_server), killed} ->
register(frequency_server, spawn_link(frequency, init_server, [])),
loop_supervisor()
end.
% Initialize state and start frequency server
init_server() ->
process_flag(trap_exit, true),
Frequencies = {get_frequencies(), []},
loop_server(Frequencies).
% Main server loop
loop_server(Frequencies) ->
receive
{request, Pid, allocate} ->
{NewFrequencies, Reply} = allocate(Frequencies, Pid),
Pid ! {reply, Reply},
loop_server(NewFrequencies);
{request, Pid , {deallocate, Freq}} ->
NewFrequencies = deallocate(Frequencies, Freq),
Pid ! {reply, ok},
loop_server(NewFrequencies);
{'EXIT', Pid, _Reason} ->
NewFrequencies = exited(Frequencies, Pid),
loop_server(NewFrequencies)
end.
allocate({[], Allocated}, _Pid) ->
{{[], Allocated}, {error, no_frequency}};
allocate({[Freq|Free], Allocated}, Pid) ->
link(Pid),
{{Free, [{Freq, Pid}|Allocated]}, {ok, Freq}}.
deallocate({Free, Allocated}, Freq) ->
{value,{Freq,Pid}} = lists:keysearch(Freq,1,Allocated),
unlink(Pid),
NewAllocated=lists:keydelete(Freq, 1, Allocated),
{[Freq|Free], NewAllocated}.
exited({Free, Allocated}, Pid) ->
case lists:keysearch(Pid,2,Allocated) of
{value,{Freq,Pid}} ->
NewAllocated = lists:keydelete(Freq,1,Allocated),
{[Freq|Free],NewAllocated};
false ->
{Free,Allocated}
end.
get_frequencies() -> [10,11,12,13,14,15].
%% Client interface
allocate() ->
frequency_server ! {request, self(), allocate},
receive
{reply, Reply} -> Reply
end.
deallocate(Freq) ->
frequency_server ! {request, self(), {deallocate, Freq}},
receive
{reply, Reply} -> Reply
end.
client(Sleep) ->
{ok, Freq} = allocate(),
timer:sleep(Sleep),
deallocate(Freq),
client(Sleep).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment