DIRECTORY MonitoredQueue; MonitoredQueueImpl: CEDAR MONITOR LOCKS queue USING queue: MQ EXPORTS MonitoredQueue = BEGIN MQ: TYPE = REF QueueBody; QueueBody: PUBLIC TYPE = MONITORED RECORD [ start, end, free: LIST OF REF ANY _ NIL, closed: BOOL _ FALSE, change: CONDITION ]; QueueClosed: PUBLIC ERROR = CODE; EndOfQueue: PUBLIC ERROR = CODE; Create: PUBLIC PROC RETURNS [queue: MQ] = { RETURN[NEW[QueueBody _ []]]; }; 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 _ 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. LMonitoredQueueImpl.mesa Copyright Σ 1985, 1986 by Xerox Corporation. All rights reserved. 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 Doug Wyatt, March 3, 1985 5:00:34 pm PST 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 Κ1˜codešœ™KšœB™BKšœ!™!Kšœ/™/K™1K™(—K˜šΟk ˜ K˜—K˜Kš Πblœœœœœ˜=Kšœ˜Kšœ˜K˜Kšœœœ ˜š œ œœ œœ˜+Kš œœœœœœ˜(Kšœœœ˜Kšœ ˜K˜K˜—Kšœ œœœ˜!Kšœ œœœ˜ K˜š Οnœœœœ œ˜+Kšœœ˜K˜K˜—šŸœœœœœ œœ˜LKšœ™Kšœ<™Kšœœœ ˜5Kšœ˜——Kšœœœ,œ˜UKšœœ˜Kšœœœ ˜Kšœ˜K˜ Kšœ˜Kšœ˜K˜—šŸœœœœ œœœœœ˜MKšœ™KšœE™EKšœœœ˜Kš œ œœœœ˜Kš œœ œœœ œ˜4Kšœœœœ ˜1Kšœ&œ˜*K˜:šœ œœ˜Kšœœ ˜%Kšœœ œ œ˜:K˜——š Ÿœœœœ œœ˜4Kšœœœ˜Kšœ œ˜Kš œ %œ˜9K˜—š Ÿœœœœ œœ˜4Kšœ;™;Kšœœœ˜Kš œœ œœœ œ˜5Kšœ œ˜K˜—Kšœ˜—…—@ ½