DIRECTORY MonitoredQueue, SafeStorage; MonitoredQueueImpl: CEDAR MONITOR LOCKS queue USING queue: MQ IMPORTS SafeStorage EXPORTS MonitoredQueue = BEGIN MQ: TYPE = REF QueueBody; QueueBody: PUBLIC TYPE = MONITORED RECORD [ start, end, free: LIST OF REF ANY, closed: BOOLEAN _ FALSE, z: ZONE, -- for allocating LISTs change: CONDITION ]; QueueClosed: PUBLIC ERROR = CODE; EndOfQueue: PUBLIC ERROR = CODE; Create: PUBLIC PROC [z: ZONE _ NIL] RETURNS [queue: MQ] = { IF z = NIL THEN z _ SafeStorage.GetSystemZone[]; queue _ z.NEW[QueueBody]; queue.z _ z }; Add: PUBLIC PROC [item: REF ANY, queue: MQ] = { AddIt[item, queue, FALSE] }; AddToSet: PUBLIC PROC [item: REF ANY, queue: MQ] = { AddIt[item, queue, TRUE] }; AddIt: ENTRY PROC [item: REF ANY, queue: MQ, toSet: BOOL] = { OPEN queue; ENABLE UNWIND => NULL; new: LIST OF REF ANY; IF closed THEN ERROR QueueClosed; IF toSet THEN -- check if item is alreay in queue FOR list: LIST OF REF ANY _ start, list.rest UNTIL list=NIL DO IF list.first = item THEN RETURN; -- already in queue ENDLOOP; IF free # NIL THEN { new _ free; free _ free.rest; new.rest _ NIL; new.first _ item } ELSE new _ z.LIST[item]; IF end=NIL THEN start _ new ELSE end.rest _ new; end _ new; NOTIFY change }; Remove: PUBLIC ENTRY PROC [queue: MQ] RETURNS [item: REF ANY] = { OPEN queue; ENABLE UNWIND => NULL; current: LIST OF REF ANY; UNTIL closed OR start # NIL DO WAIT change; ENDLOOP; IF (current _ start) = NIL THEN ERROR EndOfQueue; item _ current.first; current.first _ NIL; start _ current.rest; current.rest _ free; free _ current; IF start = NIL THEN { end _ NIL; -- have removed last entry IF closed THEN BROADCAST change --for possible Reset-- }}; Close: PUBLIC ENTRY PROC [queue: MQ] = { OPEN queue; ENABLE UNWIND => NULL; closed _ TRUE; BROADCAST change -- may be several waiting Remove's -- }; Reset: PUBLIC ENTRY PROC [queue: MQ] = { OPEN queue; ENABLE UNWIND => NULL; UNTIL closed AND start = NIL DO WAIT change; ENDLOOP; closed _ FALSE }; END. þ-- MonitoredQueueImpl.Mesa -- written by Paxton. December 1981 -- last written by Paxton. August 10, 1982 1:27 pm Last Edited by: Maxwell, January 5, 1983 12:34 pm -- adds item to queue -- causes ERROR QueueClosed if have already called Close[queue] -- adds item to queue unless it is already in it -- causes ERROR QueueClosed if queue is closed -- returns next item -- causes ERROR EndOfQueue if have called Close[queue] and no more items -- this waits until queue is closed and empty, then reopens it ÊI˜JšÏc™Jš$™$Jš2™2J™1JšÏk ˜ J˜J˜ J˜šœž œ˜#Jšžœžœž˜Jšžœ ˜Jšžœ˜—Jšž˜J˜Jšžœžœžœ ˜š œ žœžœž œžœ˜+Jš œžœžœžœžœ˜"Jšœžœžœ˜Jšœžœ˜ Jšœž ˜J˜J˜—Jšœ žœžœžœ˜!Jšœ žœžœžœ˜ J˜šÏnœžœžœžœžœžœ žœ˜;Jšžœžœžœ!˜0Jšœ žœ ˜J˜J˜—šŸœžœžœžœžœ žœžœ˜LJš™Jš?™?J˜—šŸœžœžœžœžœ žœžœ˜PJš0™0Jš.™.J˜—šŸœžœžœžœžœ žœ žœžœ˜IJšžœžœžœ˜Jš œžœžœžœžœ˜Jšžœžœžœ ˜!šžœžœ#˜1šžœžœžœžœžœžœžœž˜>Jšžœžœžœ˜5Jšžœ˜——šžœžœžœ˜Jšœ)žœ˜@—Jšžœ žœ˜Jšžœžœžœ ˜Jšžœ˜J˜ Jšžœ ˜J˜—šŸœžœžœžœ žœžœžœžœžœ˜MJš™JšH™HJšžœžœžœ˜Jš œ žœžœžœžœ˜Jš žœžœ žœžœžœ žœ˜4Jšžœžœžœžœ ˜1Jšœ&žœ˜*J˜:šžœ žœžœ˜Jšœžœ˜%Jšžœžœž œœ˜:J˜——š Ÿœžœžœžœ žœžœ˜4Jšžœžœžœ˜Jšœ žœ˜Jšž œ%œ˜9J˜—š Ÿœžœžœžœ žœžœ˜4Jš>™>Jšžœžœžœ˜Jš žœžœ žœžœžœ žœ˜5Jšœ žœ˜J˜—Jšžœ˜J˜—…—Ì