Module: duim-sheets-internals Synopsis: DUIM sheets Author: Scott McKay, Andy Armstrong Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND /// Event queues // Event queues encapsulate both a queue and a notification that serves to // synchronize multiple threads define sealed class () sealed constant slot %deque :: = make(); sealed constant slot %non-empty :: = make(, lock: make()); end class ; define sealed domain make (singleton()); define sealed domain initialize (); define sealed method event-queue-push (queue :: , event :: ) => () with-lock (associated-lock(queue.%non-empty)) when (empty?(queue.%deque)) // If there are any threads waiting for something to go into // the event queue, wake them up now release-all(queue.%non-empty) end; push(queue.%deque, event) end end method event-queue-push; define sealed method event-queue-push-last (queue :: , event :: ) => () with-lock (associated-lock(queue.%non-empty)) when (empty?(queue.%deque)) release-all(queue.%non-empty) end; push-last(queue.%deque, event) end end method event-queue-push-last; define sealed method event-queue-pop (queue :: ) => (event :: ) with-lock (associated-lock(queue.%non-empty)) // Block until there's something to pop while (empty?(queue.%deque)) wait-for(queue.%non-empty); end; pop(queue.%deque) end end method event-queue-pop; define sealed method event-queue-top (queue :: ) => (event :: ) with-lock (associated-lock(queue.%non-empty)) while (empty?(queue.%deque)) wait-for(queue.%non-empty); end; queue.%deque[0] end end method event-queue-top; define sealed method event-queue-wait (queue :: , #key timeout) => (timed-out? :: ) with-lock (associated-lock(queue.%non-empty)) while (empty?(queue.%deque)) wait-for(queue.%non-empty, timeout: timeout); end; // If the queue is empty, we must have timed out empty?(queue.%deque) end end method event-queue-wait; define sealed method event-queue-empty? (queue :: ) => (true? :: ) // Don't bother locking empty?(queue.%deque) end method event-queue-empty?; define sealed method event-queue-clear (queue :: ) => () with-lock (associated-lock(queue.%non-empty)) queue.%deque.size := 0 end end method event-queue-clear;