package edu.colostate.vchill; import java.util.LinkedList; /** * A thread-safe FIFO queue * * @author Jochen Deyke * @author jpont * @version 2009-03-23 */ public final class ControlSyncQueue<E> { private LinkedList<E> objects = new LinkedList<E>(); private boolean stopping = false; /** * Enqueues an object. * Only one copy of each object (as determined by equals) can be enqueued at once. * * @param object the object to enqueue */ public void add(final E object) { synchronized (this.objects) { if (!(this.objects.contains(object))) this.objects.add(object); this.stopping = false; this.objects.notify(); } } /** * Non-destructively gets the oldest enqueued object * * @return the oldest enqueued object */ public E peek() { synchronized (this.objects) { while (this.isEmpty()) { try { this.objects.wait(); } catch (InterruptedException e) { } } return this.objects.getFirst(); } } /** * Destructively gets the oldest enqueued object * * @return the oldest enqueued object */ public E get() { synchronized (this.objects) { while (this.isEmpty()) { try { this.objects.wait(); } catch (InterruptedException e) { } } return this.objects.remove(0); } } /** * Destroys the oldest enqueued object */ public void remove() { synchronized (this.objects) { this.objects.remove(0); } } /** * Removes the specified object from the queue * * @param object the object to remove */ public void remove(final Object object) { synchronized (this.objects) { this.objects.remove(object); } } /** * Tests if the queue is currenty empty * * @return true if the queue is empty, false if it contains one or more items */ public boolean isEmpty() { synchronized (this.objects) { return this.objects.isEmpty(); } } /** * Clears all enqueued requests */ public void clear() { synchronized (this.objects) { this.objects.clear(); } } /** * Clears all enqueud requests and sets the stopping flag to let Socket know to cancel current request */ public void stop() { synchronized (this.objects) { this.stopping = true; this.clear(); } } /** * Tests whether the socket is to stop or not * * @return true if the socket should abort, false otherwise */ public boolean stopping() { synchronized (this.objects) { return this.stopping; } } /** * Indicates that a socket has finished stopping * and is now in a stopped state. */ public void stopped() { synchronized (this.objects) { this.stopping = false; } } }