%%% File : mbox.erl %%% Author : Tony Rogvall %%% Description : Message box manipulation %%% Created : 4 Dec 2005 by Tony Rogvall -module(mbox). -compile(export_all). %% Loop over message box %% May return ONE message during the scan (message:remove()). When the %% message is removed then scanning is restarted (beam restriction :-) %% fold(Fun, Acc) -> case message:first() of empty -> Acc; {message,M} -> Acc1 = Fun(M, Acc), fold_next(Fun, Acc1) end. fold_next(Fun, Acc) -> case message:next() of empty -> Acc; {message,M} -> Acc1 = Fun(M, Acc), fold_next(Fun, Acc1) end. %% Receive with a fun %% %% Fun must return false when Message is not selected %% and return anything else otherwise %% freceive(Fun) -> freceive(Fun, infinity, timeout). freceive(Fun, Timeout) -> freceive(Fun, Timeout, timeout). freceive(Fun, Timeout, TimeoutValue) -> Timer = start_timer(Timeout), case message:first() of empty -> freceive_next(Fun, Timer, TimeoutValue); {message,M} -> case Fun(M) of false -> freceive_next(Fun, Timer, TimeoutValue); Value -> stop_timer(Timer), message:remove(), Value end end. freceive_next(Fun, Timer, TimeoutValue) -> case message:next(read_timer(Timer)) of timeout -> stop_timer(Timer), TimeoutValue; {message,M} -> case Fun(M) of false -> freceive_next(Fun, Timer, TimeoutValue); Value -> stop_timer(Timer), message:remove(), Value end end. %% use a trick, send message to undefined. Since there can not be a %% process named undefined no one will ever receice that message. start_timer(infinity) -> undefined; start_timer(Timeout) when integer(Timeout), Timeout>=0 -> erlang:start_timer(Timeout, undefined, timeout). stop_timer(undefined) -> 0; stop_timer(Ref) -> erlang:cancel_timer(Ref). read_timer(undefined) -> infinity; read_timer(Ref) -> case erlang:read_timer(Ref) of false -> 0; T -> T end.