-module(bufferinclass). -export([start/0, init/0, loop/1, add/2, fetch/1]). start() -> spawn(?MODULE, init, []). % The state of the server is % {state, ListOfElements, QueueOfPids} % where ListOfElements is a list of the elements added and not yet fetched % with the head is the oldest element added % and QueueOfPids is a list of process ids waiting for a value (on fetch) % with the head being the oldest request % invariant: if ListOfElements is not empty then QueueOfPids is empty % and if QueueOfPids is not empty, then ListOfElements is empty init() -> loop({state, [], []}). loop({state, ListOfElements, QueueOfPids}) -> receive {Pid, add, Val} -> Pid ! {self(), added}, case QueueOfPids of [] -> loop({state, ListOfElements ++ [Val], QueueOfPids}); [NextPid|RestPids] -> NextPid ! {self(), value_is, Val}, loop({state, ListOfElements, RestPids}) end; {Pid, fetch} -> case ListOfElements of [] -> loop({state, ListOfElements, QueueOfPids ++ [Pid]}); [E|Rest] -> Pid ! {self(), value_is, E}, loop({state, Rest, QueueOfPids}) end end. %% Functions for the convenience of clients add(BuffId, Val) -> BuffId ! {self(), add, Val}, receive {BuffId, added} -> ok end. fetch(BuffId) -> BuffId ! {self(), fetch}, receive {BuffId, value_is, V} -> V end.