Current section
Files
Jump to
Current section
Files
src/event_ffi.erl
-module(event_ffi).
-behaviour(gen_server).
-export([start_link/0, poll/1, push/1, read/0, init/1, handle_call/3, handle_cast/2,
handle_info/2, terminate/2, code_change/3]).
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
poll(TimeoutMs) when is_integer(TimeoutMs), TimeoutMs >= 0 ->
case whereis(?MODULE) of
undefined ->
logger:error("Event server not started. Did you forget to call event.init_event_se"
"rver()?"),
exit(event_loop_not_running);
_Pid ->
gen_server:call(?MODULE, {poll, TimeoutMs}, TimeoutMs + 50)
end.
read() ->
case whereis(?MODULE) of
undefined ->
logger:error("Event server not started. Did you forget to call event.init_event_se"
"rver()?"),
exit(event_loop_not_running);
_Pid ->
gen_server:call(?MODULE, read, infinity)
end.
push(Event) ->
gen_server:cast(?MODULE, {push, Event}).
init([]) ->
gen_event:add_handler(erl_signal_server, signal_handler, self()),
{ok, {queue:new(), none}}.
handle_call({poll, _Timeout}, _From, {Q, Waiter}) ->
case queue:out(Q) of
{empty, _} ->
{reply, none, {Q, Waiter}};
{{value, Ev}, Q2} ->
{reply, {some, Ev}, {Q2, Waiter}}
end;
handle_call(read, From, {Q, none}) ->
case queue:out(Q) of
{empty, _} ->
{noreply, {Q, From}};
{{value, Ev}, Q2} ->
{reply, {some, Ev}, {Q2, none}}
end;
handle_call(read, From, {Q, Waiter}) ->
gen_server:reply(From, none),
{reply, ok, {Q, Waiter}};
handle_call(_Other, _From, State) ->
{reply, ok, State}.
handle_cast({push, Ev}, {Q, none}) ->
{noreply, {queue:in(Ev, Q), none}};
handle_cast({push, Ev}, {Q, Waiter}) ->
gen_server:reply(Waiter, {some, Ev}),
{noreply, {Q, none}};
handle_cast(_Other, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
handle_info(_Info, State) ->
{noreply, State}.