-module(counter). -behaviour(gen_server). -define(SERVER, ?MODULE). -export([start_link/0]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -export([start/0, counter/0, next/0, set/1, stop/0]). -define(MAXCOUNT, 32767). start_link() -> gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). init(_Args) -> {ok, 0}. handle_call(next, _From, N) when N >= ?MAXCOUNT -> {reply, 0, 0}; handle_call(next, _From, N) -> {reply, N + 1, N + 1}; handle_call(get, _From, N) -> {reply, N, N}; handle_call({set, N}, _From, _N) -> {reply, N, N}. handle_cast(_Msg, State) -> {noreply, State}. handle_info(_Info, State) -> {noreply, State}. terminate(_Reason, _State) -> ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% start() -> register(?MODULE, spawn_link(?MODULE, counter, [])). counter() -> process_flag(trap_exit, true), count(0). count(N) when N > ?MAXCOUNT -> count(0); count(N) -> receive {next, FromPID} -> FromPID ! {next, N}, count(N+1); {set, New} -> count(New); {'EXIT', Pid, Reason} -> io:format("~p: ~p~n", [Pid, Reason]), exit(normal); {stop} -> exit(normal) end. set({present, N}) -> ?MODULE ! {set, N+1}. next() -> ?MODULE ! {next, self()}, receive {next, N} -> {present, N} end. stop() -> ?MODULE ! {stop}.