%% Author: hillqand %% Created: 5 dec 2007 %% Description: TODO: Add description to priority_queue -module(priority_queue). -define(EMPTY, []). %% %% Exported Functions %% -export([start_link/0, push/3, pull/1]). -export([init/1, write_debug/3, system_continue/3, system_terminate/4]). %% %% API Functions %% start_link() -> proc_lib:start_link(?MODULE, init, [self()]). push(Pid, Priority, Message) when is_integer(Priority) -> Pid ! {push, Priority, Message}, ok. pull(Pid) -> Ref = make_ref(), Pid ! {pull, self(), Ref}, receive {Ref, Message} -> Message end. init(Parent) -> Deb = sys:debug_options([]), proc_lib:init_ack(Parent, {ok, self()}), loop(Parent, Deb, ?EMPTY). %% proc_lib:hibernate(?MODULE, loop, [Parent, Deb, ?EMPTY]). write_debug(Dev, Event, Name) -> io:format(Dev, "~p event = ~p~n", [Name, Event]). system_continue(Parent, Deb, Queue) -> loop(Parent, Deb, Queue). system_terminate(Reason, Parent, Deb, Queue) -> exit(Reason). %% %% Local Functions %% loop(Parent, Deb, ?EMPTY) -> receive {push, NewPriority, NewMessage} = Msg -> NewDeb = handle_debug(Deb, {in, Msg}), NewQueue = [{NewPriority, NewMessage}], loop(Parent, NewDeb, NewQueue); {system, From, Request} -> sys:handle_system_msg(Request, From, Parent, ?MODULE, Deb, ?EMPTY) end; loop(Parent, Deb, [{Priority, _} | _] = Queue) -> receive {push, NewPriority, NewMessage} = Msg when NewPriority > Priority -> NewDeb = handle_debug(Deb, {in, Msg}), NewQueue = [{NewPriority, NewMessage} | Queue], loop(Parent, NewDeb, NewQueue); {pull, From, Ref} = Msg -> Deb2 = handle_debug(Deb, {in, Msg, From}), [{_, Message} | NewQueue] = Queue, Reply = {Ref, Message}, From ! Reply, Deb3 = handle_debug(Deb, {out, Reply, From}), loop(Parent, Deb3, NewQueue); %% case NewQueue of %% [] -> %% proc_lib:hibernate(?MODULE, loop, [Parent, Deb3, ?EMPTY]); %% [{NewPriority, _}| _] -> %% loop(Parent, Deb3, NewQueue) %% end; {system, From, Request} -> sys:handle_system_msg(Request, From, Parent, ?MODULE, Deb, Queue) end. handle_debug(Deb, Event) -> sys:handle_debug(Deb, {?MODULE, write_debug}, ok, Event).