scala.actors.threadpool.helpers.WaitQueue Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scala-actors Show documentation
Show all versions of scala-actors Show documentation
Deprecated Actors Library for Scala
/*
based on file: QueuedSemaphore.java
Originally written by Doug Lea and released into the public domain.
This may be used for any purposes whatsoever without acknowledgment.
Thanks for the assistance and support of Sun Microsystems Labs,
and everyone contributing, testing, and using this code.
History:
Date Who What
11Jun1998 dl Create public version
5Aug1998 dl replaced int counters with longs
24Aug1999 dl release(n): screen arguments
*/
package scala.actors.threadpool.helpers;
import java.util.Collection;
import scala.actors.threadpool.*;
/**
* Base class for internal queue classes for semaphores, etc.
* Relies on subclasses to actually implement queue mechanics.
* NOTE: this class is NOT present in java.util.concurrent.
**/
public abstract class WaitQueue {
public abstract void insert(WaitNode w); // assumed not to block
public abstract WaitNode extract(); // should return null if empty
public abstract void putBack(WaitNode w);
public abstract boolean hasNodes();
public abstract int getLength();
public abstract Collection getWaitingThreads();
public abstract boolean isWaiting(Thread thread);
public static interface QueuedSync {
// invoked with sync on wait node, (atomically) just before enqueuing
boolean recheck(WaitNode node);
// invoked with sync on wait node, (atomically) just before signalling
void takeOver(WaitNode node);
}
public static class WaitNode {
boolean waiting = true;
WaitNode next = null;
final Thread owner;
public WaitNode() {
this.owner = Thread.currentThread();
}
public Thread getOwner() {
return owner;
}
public synchronized boolean signal(QueuedSync sync) {
boolean signalled = waiting;
if (signalled) {
waiting = false;
notify();
sync.takeOver(this);
}
return signalled;
}
public synchronized boolean doTimedWait(QueuedSync sync, long nanos)
throws InterruptedException
{
if (sync.recheck(this) || !waiting)
return true;
else if (nanos <= 0) {
waiting = false;
return false;
}
else {
long deadline = Utils.nanoTime() + nanos;
try {
for (; ; ) {
TimeUnit.NANOSECONDS.timedWait(this, nanos);
if (!waiting) // definitely signalled
return true;
else {
nanos = deadline - Utils.nanoTime();
if (nanos <= 0) { // timed out
waiting = false;
return false;
}
}
}
}
catch (InterruptedException ex) {
if (waiting) { // no notification
waiting = false; // invalidate for the signaller
throw ex;
}
else { // thread was interrupted after it was notified
Thread.currentThread().interrupt();
return true;
}
}
}
}
public synchronized void doWait(QueuedSync sync)
throws InterruptedException
{
if (!sync.recheck(this)) {
try {
while (waiting) wait();
}
catch (InterruptedException ex) {
if (waiting) { // no notification
waiting = false; // invalidate for the signaller
throw ex;
}
else { // thread was interrupted after it was notified
Thread.currentThread().interrupt();
return;
}
}
}
}
public synchronized void doWaitUninterruptibly(QueuedSync sync) {
if (!sync.recheck(this)) {
boolean wasInterrupted = Thread.interrupted();
try {
while (waiting) {
try {
wait();
}
catch (InterruptedException ex) {
wasInterrupted = true;
// no need to notify; if we were signalled, we
// must be not waiting, and we'll act like signalled
}
}
}
finally {
if (wasInterrupted) Thread.currentThread().interrupt();
}
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy