%% A simple locker, which uses gen_fsm to manage a key-value list, and %% allows writing to a key only in the "locked" state. -module(lock). -export( [% gen_fsm call-backs init/1, handle_sync_event/4, terminate/3, % gen_fsm states unlocked/2, unlocked/3, locked/2, locked/3, % API lock/0, unlock/0, write/2, read/1, start/0, stop/0]). -behaviour(gen_fsm). init([]) -> {ok,unlocked,[]}. terminate(_,_,_) -> ok. %% Event handlers for each state unlocked(lock,S) -> {next_state,locked,S}. unlocked({read,Key},Caller,S) -> gen_fsm:reply(Caller,proplists:get_value(Key,S)), {next_state,unlocked,S}. locked({write,Key,Value},S) -> {next_state,locked,[{Key,Value}|proplists:delete(Key,S)]}; locked(unlock,S) -> {next_state,unlocked,S}. locked({read,Key},Client,S) -> gen_fsm:reply(Client,proplists:get_value(Key,S)), {next_state,locked,S}. %% Event handler for the stop event handle_sync_event(stop,_,_,_) -> {stop,normal,ok,[]}. %% User API lock() -> gen_fsm:send_event(locker,lock). unlock() -> gen_fsm:send_event(locker,unlock). write(Key,Val) -> gen_fsm:send_event(locker,{write,Key,Val}). read(Key) -> gen_fsm:sync_send_event(locker,{read,Key}). start() -> gen_fsm:start({local,locker},?MODULE,[],[]). stop() -> gen_fsm:sync_send_all_state_event(locker,stop).