diff options
Diffstat (limited to 'java/JACE/Concurrency')
-rw-r--r-- | java/JACE/Concurrency/AbstractLock.java | 269 | ||||
-rw-r--r-- | java/JACE/Concurrency/Condition.java | 124 | ||||
-rw-r--r-- | java/JACE/Concurrency/LockAdapter.java | 262 | ||||
-rw-r--r-- | java/JACE/Concurrency/LockException.java | 28 | ||||
-rw-r--r-- | java/JACE/Concurrency/Mutex.java | 239 | ||||
-rw-r--r-- | java/JACE/Concurrency/RWMutex.java | 268 | ||||
-rw-r--r-- | java/JACE/Concurrency/RenewObject.java | 36 | ||||
-rw-r--r-- | java/JACE/Concurrency/Semaphore.java | 263 | ||||
-rw-r--r-- | java/JACE/Concurrency/ThreadManager.java | 113 | ||||
-rw-r--r-- | java/JACE/Concurrency/Token.java | 301 | ||||
-rw-r--r-- | java/JACE/Concurrency/WaitObject.java | 39 | ||||
-rw-r--r-- | java/JACE/Concurrency/package.html | 15 |
12 files changed, 0 insertions, 1957 deletions
diff --git a/java/JACE/Concurrency/AbstractLock.java b/java/JACE/Concurrency/AbstractLock.java deleted file mode 100644 index c8afaf789ae..00000000000 --- a/java/JACE/Concurrency/AbstractLock.java +++ /dev/null @@ -1,269 +0,0 @@ -/************************************************* - * - * = PACKAGE - * JACE.Concurrency - * - * = FILENAME - * Lock.java - * - *@author Everett Anderson - * - *************************************************/ -package JACE.Concurrency; - -import JACE.ASX.*; - -/** - * Interface for any Java ACE synchronization mechanism. - * <P> - * Defines the interface for Token, Mutex, RWMutex, Semaphore, - * and the RemoteLock proxies in the Token service, as well as - * the possible constant return values. - * <P> - * Methods which take TimeValue timeouts can throw - * JACE.ASX.TimeoutExceptions. The locks should continue to - * function properly after a thread times out or is interrupted. - * <em>Also note that the timeouts are absolute time-of-day - * values, not relative times.</em> - * <P> - * An AbstractLock.FAILURE can be returned for an undefined type of - * failure. - * <P> - * You can assume that - * AbstractLock.FAILURE < AbstractLock.SUCCESS < AbstractLock.SLEEPHOOK - * <P> - * Any method can throw a LockException, providing a way to return - * unusual error cases in future types of locks (such as the Token - * service). - * <P> - * It is safe to call release () in a finally block, since it will - * return FAILURE if the accessing thread is not the owner. - * - */ -public interface AbstractLock -{ - /** - * Generic failure indication, used as a return value. - */ - public static final int FAILURE = -1; - - /** - * Success indication, used as a return value. - */ - int SUCCESS = 0; - - /** - * Success indication, but notes that the thread had to sleep - * to complete it (and it called the sleep hook). Used as a - * return value. - */ - int SLEEPHOOK = 1; - - - /** - * Acquire ownership of the lock, blocking indefinitely if necessary. - * <P> - *@return AbstractLock.FAILURE or AbstractLock.SUCCESS - *@exception LockException special exception defined by a later - * implementation - *@exception InterruptedException indicates another thread has - * interrupted this one during wait - */ - public int acquire () throws LockException, InterruptedException; - - /** - * Acquire ownership of the lock by the given absolute time time-out. - * A value of null for the timeout parameter results in a blocking - * acquire. - * A value of TimeValue.zero throws a TimeoutException if the - * acquire would block. - * <P> - *@param timeout absolute time by which the lock must be acquired - *@return appropriate Lock return value (AbstractLock.FAILURE, - * AbstractLock.SUCCESS or AbstractLock.SLEEPHOOK) - *@exception LockException special exception defined by a later - * implementation - *@exception JACE.ASX.TimeoutException thrown when the lock is not - * obtained by the desired time - *@exception InterruptedException indicates another thread has - * interrupted this one during wait - *@see AbstractLock#tryAcquire - */ - public int acquire (TimeValue timeout) - throws LockException, TimeoutException, InterruptedException; - - /** - * Acquire a read lock, blocking indefinitely if necessary. This can - * be used to implement Reader-Writer locks in which multiple readers - * may have simultaneous access. - * <P> - *@return AbstractLock.FAILURE or AbstractLock.SUCCESS - *@exception LockException special exception defined by a later - * implementation - *@exception InterruptedException indicates another thread has - * interrupted this one during wait - */ - public int acquireRead () throws LockException, InterruptedException; - - /** - * Acquire a read lock by the given absolute time time-out. This can - * be used to implement Reader-Writer locks in which multiple readers - * may have simultaneous access. - * <P> - *@param timeout absolute time by which the lock must be acquired - *@return appropriate lock return value (AbstractLock.FAILURE, - * AbstractLock.SUCCESS or AbstractLock.SLEEPHOOK) - *@exception LockException special exception defined by a later - * implementation - *@exception JACE.ASX.TimeoutException thrown when the lock is not - * obtained by the desired time - *@exception InterruptedException indicates another thread has - * interrupted this one during wait - *@see AbstractLock#tryAcquireRead - */ - public int acquireRead (TimeValue timeout) - throws LockException, TimeoutException, InterruptedException; - - /** - * Acquire a write lock, blocking indefinitely if necessary. This can - * be used to implement Reader-Writer locks in which a writer has - * exclusive access. - * <P> - *@return AbstractLock.FAILURE or AbstractLock.SUCCESS - *@exception LockException special exception defined by a later - * implementation - *@exception InterruptedException indicates another thread has - * interrupted this one during wait - */ - public int acquireWrite () throws LockException, InterruptedException; - - /** - * Acquire a write lock by the given absolute time time-out. This can - * be used to implement Reader-Writer locks in which a writer has - * exclusive access. - * <P> - *@param timeout absolute time by which the lock must be acquired - *@return appropriate AbstractLock return value (AbstractLock.FAILURE, - * AbstractLock.SUCCESS or AbstractLock.SLEEPHOOK) - *@exception LockException special exception defined by a later - * implementation - *@exception JACE.ASX.TimeoutException thrown when the lock is not - * obtained by the desired time - *@exception InterruptedException indicates another thread has - * interrupted this one during wait - *@see AbstractLock#tryAcquireWrite - */ - public int acquireWrite (TimeValue timeout) - throws LockException, TimeoutException, InterruptedException; - - /** - * Give up the lock to some number of waiting threads (if any), then - * reacquire, blocking indefinitely if necessary. - * <P> - * An optimized method that efficiently reacquires the token if no - * other threads are waiting. This is useful for situations where - * you don't want to degrade the quality of service if there are - * other threads waiting to get the token. - * <P> - *@param requeuePosition position in the waiters queue to insert - * this thread. If this value is -1 and there are other - * threads waiting to obtain the token, this thread is queued - * at the end. If this value is greater than -1, then it - * indicates how many entries to skip over before inserting - * our thread into the queue. (For example, if it is 0, - * this thread is put at the front of the queue.) If this - * value is greater than the number of waiters, this thread is - * simply put at the end of the current waiters queue. - *@return AbstractLock.FAILURE or AbstractLock.SUCCESS - *@exception LockException special exception defined by a later - * implementation - *@exception InterruptedException indicates another thread has - * interrupted this one during wait - */ - public int renew (int requeuePosition) throws LockException, - InterruptedException; - - /** - * Give up the lock to some waiting threads (if any), then reacquire - * by the given absolute time time-out. - * <P> - * An optimized method that efficiently reacquires the token if no - * other threads are waiting. This is useful for situations where - * you don't want to degrade the quality of service if there are - * other threads waiting to get the token. - * <P> - * A value of null for the timeout should indicate a blocking renew. - * <P> - *@param requeuePosition position in the waiters queue to insert - * this thread. If this value is -1 and there are other - * threads waiting to obtain the token, this thread is queued - * at the end. If this value is greater than -1, then it - * indicates how many entries to skip over before inserting - * our thread into the queue. (For example, if it is 0, - * this thread is put at the front of the queue.) If this - * value is greater than the number of waiters, this thread is - * simply put at the end of the current waiters queue. - * - *@param timeout absolute time by which the lock must be reacquired - * - *@return appropriate AbstractLock return value - * (AbstractLock.FAILURE or AbstractLock.SUCCESS) - *@exception LockException special exception defined by a later - * implementation - *@exception JACE.ASX.TimeoutException thrown when the lock is not - * obtained by the desired time - *@exception InterruptedException indicates another thread has - * interrupted this one during wait - */ - public int renew (int requeuePosition, TimeValue timeout) - throws LockException, TimeoutException, InterruptedException; - - /** - * Try to acquire the lock without blocking. - * <P> - *@return appropriate AbstractLock return value - * (AbstractLock.FAILURE or AbstractLock.SUCCESS) - *@exception LockException special exception defined by a later - * implementation - */ - public int tryAcquire () throws LockException; - - /** - * Try to acquire a read lock without blocking. - * <P> - *@see #acquireRead - *@return appropriate AbstractLock return value - * (AbstractLock.FAILURE or AbstractLock.SUCCESS) - *@exception LockException special exception defined by a later - * implementation - */ - public int tryAcquireRead () throws LockException; - - /** - * Try to acquire a write lock without blocking. - *<P> - *@see #acquireWrite - *@return appropriate AbstractLock return value - * (AbstractLock.FAILURE or AbstractLock.SUCCESS) - *@exception LockException special exception defined by a later - * implementation - */ - public int tryAcquireWrite () throws LockException; - - /** - * Method that is called before a thread goes to sleep in an - * acquire. This should be overridden by a subclass to define - * the appropriate behavior. - */ - public void sleepHook (); - - /** - * Release ownership of this lock. - * <P> - *@return appropriate AbstractLock return value - * (AbstractLock.FAILURE or AbstractLock.SUCCESS) - *@exception LockException special exception defined by a later - * implementation - */ - public int release () throws LockException; -} diff --git a/java/JACE/Concurrency/Condition.java b/java/JACE/Concurrency/Condition.java deleted file mode 100644 index 1889f6e1edf..00000000000 --- a/java/JACE/Concurrency/Condition.java +++ /dev/null @@ -1,124 +0,0 @@ -/************************************************* - * - * = PACKAGE - * JACE.Concurrency - * - * = FILENAME - * Condition.java - * - *@author Irfan Pyarali - * - *************************************************/ -package JACE.Concurrency; - -import JACE.ASX.TimeoutException; -import JACE.ASX.TimeValue; - -/** - * Abstraction for <em>traditional</em> - * condition variable - * <P> - * This condition variable allows the use of one - * mutex between multiple conditions. - * This implementation is based on the C++ version of ACE. - */ -public class Condition -{ - /** - * Default constructor - *@param Mutex for synchronization - */ - public Condition (Mutex mutex) - { - mutex_ = mutex; - } - - /** - * Wait for condition to become signaled. - *@exception InterruptedException exception during wait - */ - public void Wait () - throws InterruptedException - { - waiters_++; - - try - { - mutex_.release(); - synchronized (waitObject_) { - waitObject_.wait (); - } - mutex_.acquire (); - } - finally - { - waiters_--; - } - } - - /** - * TimedWait for condition to become signaled. Note that the - * given TimeValue is an absolute time, not a relative time. - * - *@param tv Absolute time to wait until before timing out - *@exception TimeoutException wait timed out exception - *@exception InterruptedException exception during wait - */ - public void Wait (TimeValue tv) - throws TimeoutException, InterruptedException - { - waiters_++; - - try - { - mutex_.release(); - - synchronized (waitObject_) { - long start = System.currentTimeMillis(); - long waitTime = tv.getMilliTime() - start; - if (waitTime < 1) - throw new TimeoutException (); - waitObject_.wait (waitTime); - } - - mutex_.acquire (tv); - } - finally - { - waiters_--; - } - } - - /** - * Signal condition. Wake one waiter (if any). - */ - public void signal () - { - synchronized (waitObject_) { - waitObject_.notify (); - } - } - - /** - * Signal condition. Wake up all waiters (if any). - */ - public void broadcast () - { - synchronized (waitObject_) { - waitObject_.notifyAll (); - } - } - - /** - * Accessor to lock - *@return Mutex - */ - public Mutex mutex () - { - return mutex_; - } - - private int waiters_; - private Object waitObject_ = new Object (); - private Mutex mutex_; -} diff --git a/java/JACE/Concurrency/LockAdapter.java b/java/JACE/Concurrency/LockAdapter.java deleted file mode 100644 index db2e9de05c7..00000000000 --- a/java/JACE/Concurrency/LockAdapter.java +++ /dev/null @@ -1,262 +0,0 @@ -/************************************************* - * - * = PACKAGE - * JACE.Concurrency - * - * = FILENAME - * Lock.java - * - *@author Everett Anderson - * - *************************************************/ -package JACE.Concurrency; - -import JACE.ASX.*; - -/** - * Abstract adapter class which provides useful default implementations - * for several methods in the AbstractLock interface, as well as - * protected helper functions for making sure only the owner - * can perform certain operations. - * - *@see JACE.Concurrency.AbstractLock - */ -public abstract class LockAdapter implements AbstractLock -{ - /** - * Default implementation that calls acquire (TimeValue) with a null - * timeout. - * - *@see AbstractLock#acquire - */ - public int acquire () throws InterruptedException - { - try { - return acquire (null); - } catch (TimeoutException e) { - // This should never happen - return AbstractLock.FAILURE; - } - } - - /** - * Acquire ownership of the lock by the given absolute time time-out. - * A value of null for the timeout parameter results in a blocking - * acquire. - * A value of TimeValue.zero throws a TimeoutException if the - * acquire would block. - * <P> - *@param timeout absolute time by which the lock must be acquired - *@return appropriate Lock return value (AbstractLock.FAILURE, - * AbstractLock.SUCCESS or AbstractLock.SLEEPHOOK) - *@exception JACE.ASX.TimeoutException thrown when the lock is not - * obtained by the desired time - *@exception InterruptedException indicates another thread has - * interrupted this one during wait - *@see AbstractLock#tryAcquire - */ - public abstract int acquire (TimeValue timeout) - throws TimeoutException, InterruptedException; - - /** - * Default implementation that calls acquireRead (TimeValue) with a - * null timeout. - * - *@see AbstractLock#acquireRead - */ - public int acquireRead () throws InterruptedException - { - try { - return acquireRead (null); - } catch (TimeoutException e) { - // This should never happen - } - - return AbstractLock.FAILURE; - } - - /** - * Default implementation that calls acquire (TimeValue). - * - *@see AbstractLock#acquireRead(TimeValue) - */ - public int acquireRead (TimeValue timeout) - throws TimeoutException, InterruptedException - { - return acquire (timeout); - } - - /** - * Default implementation that calls acquire with a null - * timeout. - * - *@see AbstractLock#acquireWrite - */ - public int acquireWrite () throws InterruptedException - { - try { - return acquire (null); - } catch (TimeoutException e) { - // This should never happen - } - - return AbstractLock.FAILURE; - } - - /** - * Default implementation that calls acquire (TimeValue). - * - *@see AbstractLock#acquireWrite(TimeValue) - */ - public int acquireWrite (TimeValue timeout) - throws TimeoutException, InterruptedException - { - return acquire (timeout); - } - - /** - * Default implementation that calls renew (int, TimeValue) with - * a null timeout. - * - *@see AbstractLock#renew(int) - */ - public int renew (int requeuePosition) throws InterruptedException - { - try - { - return renew (requeuePosition, null); - } catch (TimeoutException e) { - // Note that this should never happen since we requested a - // blocking acquire. - return AbstractLock.FAILURE; - } - } - - /** - * Give up the lock to some waiting threads (if any), then reacquire - * by the given absolute time time-out. - * <P> - * An optimized method that efficiently reacquires the token if no - * other threads are waiting. This is useful for situations where - * you don't want to degrade the quality of service if there are - * other threads waiting to get the token. - * <P> - * A value of null for the timeout should indicate a blocking renew. - * <P> - *@param requeuePosition position in the waiters queue to insert - * this thread. If this value is -1 and there are other - * threads waiting to obtain the token, this thread is queued - * at the end. If this value is greater than -1, then it - * indicates how many entries to skip over before inserting - * our thread into the queue. (For example, if it is 0, - * this thread is put at the front of the queue.) If this - * value is greater than the number of waiters, this thread is - * simply put at the end of the current waiters queue. - * - *@param timeout absolute time by which the lock must be reacquired - * - *@return appropriate AbstractLock return value - * (AbstractLock.FAILURE or AbstractLock.SUCCESS) - *@exception JACE.ASX.TimeoutException thrown when the lock is not - * obtained by the desired time - *@exception InterruptedException indicates another thread has - * interrupted this one during wait - */ - public abstract int renew (int requeuePosition, - TimeValue timeout) - throws TimeoutException, - InterruptedException; - - /** - * Default implementation that calls tryAcquire (). - * - *@see AbstractLock#tryAcquireRead - */ - public int tryAcquireRead () - { - return tryAcquire (); - } - - /** - * Default implementation that calls tryAcquire (). - * - *@see AbstractLock#tryAcquireWrite - */ - public int tryAcquireWrite () - { - return tryAcquire (); - } - /** - * Try to acquire the lock without blocking. - * <P> - *@return appropriate AbstractLock return value - * (AbstractLock.FAILURE or AbstractLock.SUCCESS) - */ - public abstract int tryAcquire (); - - /** - * Default implementation as a no-op. - * - *@see AbstractLock#sleepHook - */ - public void sleepHook () - { - } - - /** - * Release ownership of this lock. - * <P> - *@return appropriate AbstractLock return value - * (AbstractLock.FAILURE or AbstractLock.SUCCESS) - */ - public abstract int release (); - - /** - * Obtains an Object which uniquely identifies the current accessor - * (usually a thread). This is used to make sure only an owner can - * perform certain operations like release. Subclasses can redefine - * the behavior as necessary, such as in the Token service where it is - * defined to be the client ID sent by the proxy. - * <P> - * When using Java 1.2 or later, it might be more efficient to use - * ThreadLocal and an Integer for the ID. The current default - * implementation returns the Thread.currentThread () reference. - * - *@return Object representing a unique ID for this accessor - */ - protected Object accessorID () - { - return Thread.currentThread(); - } - - /** - * Check to see if the current accessor is the (or a) owner of this - * lock. - */ - protected boolean isOwner() - { - return accessorID().equals(this.owner_); - } - - /** - * Set the current accessor to be the (or a) owner of this lock. - */ - protected void setOwner() - { - this.owner_ = accessorID(); - } - - /** - * Make sure that this accessor is no longer the (or a) owner of this - * lock. - */ - protected void clearOwner() - { - this.owner_ = null; - } - - /** - * Reference to the accessorID of the owner. - */ - private Object owner_; -} diff --git a/java/JACE/Concurrency/LockException.java b/java/JACE/Concurrency/LockException.java deleted file mode 100644 index dff4c09c626..00000000000 --- a/java/JACE/Concurrency/LockException.java +++ /dev/null @@ -1,28 +0,0 @@ -package JACE.Concurrency; - -/** - * Base class for possible exceptions thrown from Lock - * mechanisms. This can be used by later Lock - * implementations to signal special types of exceptions, such - * as a remote failure, etc. - * <P> - */ -public class LockException extends java.lang.Exception -{ - /** - * Default constructor - */ - public LockException () { } - - /** - * Constructor with a string message that will be returned - * via the getMessage() method on Exception. - * <P> - *@see java.lang.Exception#getMessage - */ - public LockException (String message) - { - super(message); - } -} - diff --git a/java/JACE/Concurrency/Mutex.java b/java/JACE/Concurrency/Mutex.java deleted file mode 100644 index 856fdbd79eb..00000000000 --- a/java/JACE/Concurrency/Mutex.java +++ /dev/null @@ -1,239 +0,0 @@ -/************************************************* - * - * = PACKAGE - * JACE.Concurrency - * - * = FILENAME - * Mutex.java - * - *@author Prashant Jain - *@author Everett Anderson - * - *************************************************/ -package JACE.Concurrency; - -import java.util.*; -import JACE.ASX.*; - -/** - * Value added abstraction for mutex variable creation. - * - * A mutex whose operations do not block forever and can time out. - * <P> - * <EM>This class does not support recursive semantics.</EM> - */ -public class Mutex extends LockAdapter -{ - /** - * Acquire ownership of the lock, blocking indefinitely if necessary. - * <P> - *@return AbstractLock.FAILURE or AbstractLock.SUCCESS - *@exception InterruptedException indicates another thread has - * interrupted this one during wait - */ - public synchronized int acquire () throws InterruptedException - { - if (this.monitor_.condition ()) { - this.monitor_.condition (false); - setOwner (); - return AbstractLock.SUCCESS; - } - - this.numberOfWaiters_++; - try { - sleepHook (); - this.monitor_.timedWait (); - } finally { - this.numberOfWaiters_--; - } - this.monitor_.condition (false); - setOwner(); - - return AbstractLock.SLEEPHOOK; - } - - public int renew (int requeuePosition, - TimeValue timeout) - throws InterruptedException, - TimeoutException - { - RenewObject rwo; - - synchronized (this) { - - if (!this.isOwner ()) - return AbstractLock.FAILURE; - - if (numberOfWaiters_ == 0 || requeuePosition == 0) - return AbstractLock.SUCCESS; - - if (requeuePosition < 0 || requeuePosition > numberOfWaiters_) - requeuePosition = numberOfWaiters_; - - rwo = new RenewObject (requeuePosition); - - this.release (); - this.renewers_.addElement (rwo); - } - - // We can't have the method synchronized, or synchronize on (this) - // in here because then the Thread that was woken up won't be able - // to continue its acquire. - // - // Normally when an exception occurs in timedWait, this thread just - // needs to remove itself from the renewers queue. - // - // However, the following situation exists: - // Thread A is the current owner, and is doing processing in release() - // This thread generates a timeout exception in timedWait - // Thread A signals this thread to wake up and take ownership, and - // removes it from the queue. - // This thread never takes ownership -- the exception keeps going up. - // - // This could lead to other renewers waiting in limbo forever. - // - // Solution: If this thread has an exception and it looks like it - // has been proclaimed the owner, then it calls release and lets - // the exception continue. - - boolean exceptionOccured = true; - try { - synchronized (rwo) { - rwo.timedWait (timeout); - - exceptionOccured = false; - } - } finally { - if (exceptionOccured) { - synchronized (this) { - if (!renewers_.removeElement (rwo)) { - setOwner (); - release (); - } - } - } - } - - synchronized (this) { - setOwner (); - } - - // By this point, we should know that we have the lock. The condition - // flag is never set to true in the release() call from the Thread - // that gave us control. - - return AbstractLock.SUCCESS; - } - - public synchronized int tryAcquire () { - if (this.monitor_.condition ()) { - this.monitor_.condition (false); - setOwner(); - return AbstractLock.SUCCESS; - } else - return AbstractLock.FAILURE; - } - - public synchronized int acquire (TimeValue tv) - throws TimeoutException, InterruptedException - { - if (this.monitor_.condition ()) { - this.monitor_.condition (false); - setOwner (); - return AbstractLock.SUCCESS; - } - - this.numberOfWaiters_++; - try { - sleepHook (); - this.monitor_.timedWait (tv); - } finally { - this.numberOfWaiters_--; - } - this.monitor_.condition (false); - setOwner(); - - return AbstractLock.SLEEPHOOK; - } - - /** - * Checks any objects in the renewers queue, giving one of them - * the lock if it is appropriate. Assumes the synchronization - * lock is already held. - * - *@return true if a renewer was signaled, else false - */ - protected boolean signalNextRenewer () - { - // First find the renewer with the minimum yieldTo count, processing - // all of them along the way. - if (this.renewers_.size() > 0) { - - RenewObject renewer = (RenewObject)renewers_. - elementAt (renewers_.size () - 1); - - renewer.decrementYieldTo (); - - for (int i = this.renewers_.size() - 2; i >=0; i--) { - - RenewObject rwo = (RenewObject)renewers_.elementAt (i); - - rwo.decrementYieldTo (); - - renewer = renewer.min (rwo); - } - - // If the renewer with the minimum yieldTo count has yielded to - // enough threads, or if there are no waiting threads, it should - // be signaled (thus, it wakes up and obtains the lock again). - - if (renewer.condition () || numberOfWaiters_ == 0) { - // Note that we leave monitor_.condition in the false state so - // we are assured that only the renewer (and not another - // Thread that does an acquire) will gain control. This - // is important since the renew method can't be synchronized - // in its current implementation. - renewers_.removeElement(renewer); - - synchronized (renewer) { - renewer.signal (); - } - - return true; - } - } - - return false; - } - - public synchronized int release () - { - if (!isOwner()) - return AbstractLock.FAILURE; - - if (!signalNextRenewer ()) { - // Do a normal release if there are no threads waiting to renew - // or no such threads are ready to renew. - this.monitor_.condition (true); - this.monitor_.signal (); - } - - return AbstractLock.SUCCESS; - } - - /** - * Monitor used to signal whether or not this Mutex is available. - */ - protected WaitObject monitor_ = new WaitObject (true, this); - // The monitor (adapter) to wait on - - /** - * Queue of waiting renewers. - */ - protected Vector renewers_ = new Vector (); - - /** - * Number of waiting threads. - */ - protected int numberOfWaiters_ = 0; -} diff --git a/java/JACE/Concurrency/RWMutex.java b/java/JACE/Concurrency/RWMutex.java deleted file mode 100644 index abb30ce3bc8..00000000000 --- a/java/JACE/Concurrency/RWMutex.java +++ /dev/null @@ -1,268 +0,0 @@ -package JACE.Concurrency; - -import java.util.*; -import JACE.ASX.*; - -/** - * A read/write lock allows multiple - * readers or a single writer to access the guarded element. - * <P> - * <EM>This class does not support recursive semantics.</EM> - */ -public class RWMutex extends LockAdapter -{ - public synchronized int tryAcquire () - { - if (referenceCount_ == 0) { - referenceCount_ = -1; - setOwner (); - return AbstractLock.SUCCESS; - } else - return AbstractLock.FAILURE; - } - - public synchronized int tryAcquireRead () - { - if (referenceCount_ > -1 && waiters_.size () == 0) { - referenceCount_++; - setOwner (); - return AbstractLock.SUCCESS; - } else - return AbstractLock.FAILURE; - } - - public int acquire(TimeValue timeout) - throws TimeoutException, InterruptedException - { - return acquireWrite(timeout); - } - - public void waitUntilIsOwner (RWWaitObject waitObj, TimeValue timeout) - throws TimeoutException, InterruptedException - { - boolean exceptionOccured = true; - try { - sleepHook (); - synchronized (waitObj) { - waitObj.timedWait (timeout); - } - exceptionOccured = false; - } finally { - - synchronized (this) { - - if (exceptionOccured) { - if (!waiters_.removeElement (waitObj)) { - setOwner (); - release (); - } - } else - setOwner(); - } - } - } - - public int acquireRead(TimeValue timeout) - throws TimeoutException, InterruptedException - { - RWWaitObject waitObj = null; - - synchronized (this) { - - if (referenceCount_ > -1 && waiters_.size () == 0) { - referenceCount_++; - setOwner (); - return AbstractLock.SUCCESS; - } - - waitObj = new RWWaitObject (true); - - waiters_.addElement (waitObj); - } - - waitUntilIsOwner (waitObj, timeout); - - return AbstractLock.SLEEPHOOK; - } - - public int acquireWrite(TimeValue timeout) - throws TimeoutException, InterruptedException - { - RWWaitObject waitObj = null; - - synchronized (this) { - - if (referenceCount_ == 0) { - referenceCount_ = -1; - setOwner (); - return AbstractLock.SUCCESS; - } - - waitObj = new RWWaitObject (false); - - waiters_.addElement (waitObj); - } - - waitUntilIsOwner (waitObj, timeout); - - // When the writer gets here, it has been cleared to go by - // whatever thread specifically gave control to this writer in - // release. The referenceCount_ and numberOfWaitingWriters_ - // variables are also adjusted by the releasing thread since - // it already has a synchronization lock. Not doing that, - // and then having another synchronized (this) block in here - // could lead to a situation in which another thread sneaks - // in inbetween when this thread leaves timedWait and goes to - // adjust them. - - return AbstractLock.SLEEPHOOK; - } - - - public synchronized int release () - { - if (!isOwner ()) - return AbstractLock.FAILURE; - - clearOwner (); - - // Releasing a reader. - if (referenceCount_ > 0) { - referenceCount_--; - - if (referenceCount_ != 0) - return AbstractLock.SUCCESS; - - } else { - // releasing a writer - referenceCount_ = 0; - } - - if (waiters_.size () == 0) - return AbstractLock.SUCCESS; - - if (releaseFirstReaders () == 0) { - RWWaitObject waitObj = (RWWaitObject)waiters_.firstElement (); - waiters_.removeElementAt (0); - - referenceCount_ = -1; - - waitObj.condition (true); - synchronized (waitObj) { - waitObj.signal (); - } - } - - return AbstractLock.SUCCESS; - } - - // Releases all waiting readers up to the first waiting writer - // or the end of the queue. Returns the number of readers - // released. - protected int releaseFirstReaders () - { - int releasedReaders = 0; - - do { - - RWWaitObject waitObj = (RWWaitObject)waiters_.firstElement (); - if (!waitObj.isReader ()) - break; - - waiters_.removeElementAt (0); - - referenceCount_++; - releasedReaders++; - - waitObj.condition (true); - synchronized (waitObj) { - waitObj.signal (); - } - - } while (waiters_.size () > 0); - - return releasedReaders; - } - - public int renew (int requeuePosition, - JACE.ASX.TimeValue timeout) - throws InterruptedException, - TimeoutException - { - RWWaitObject waitObj = null; - - synchronized (this) { - - if (!isOwner ()) - return AbstractLock.FAILURE; - - if (requeuePosition == 0 || waiters_.size () == 0) - return AbstractLock.SUCCESS; - - waitObj = new RWWaitObject (referenceCount_ > 0); - - if (requeuePosition < 0 || requeuePosition > waiters_.size ()) { - requeuePosition = waiters_.size (); - } - - waiters_.insertElementAt (waitObj, requeuePosition); - - release (); - } - - waitUntilIsOwner (waitObj, timeout); - - // When the writer gets here, it has been cleared to go by - // whatever thread specifically gave control to this writer in - // release. The referenceCount_ and numberOfWaitingWriters_ - // variables are also adjusted by the releasing thread since - // it already has a synchronization lock. Not doing that, - // and then having another synchronized (this) block in here - // could lead to a situation in which another thread sneaks - // in inbetween when this thread leaves timedWait and goes to - // adjust them. - - return AbstractLock.SUCCESS; - } - - static class RWWaitObject extends WaitObject - { - public RWWaitObject (boolean isReader) - { - isReader_ = isReader; - } - - public boolean isReader () - { - return isReader_; - } - - private boolean isReader_ = false; - } - - protected boolean isOwner () - { - return owners_.containsKey (accessorID()); - } - - protected void setOwner () - { - owners_.put (accessorID(), this); - } - - protected void clearOwner () - { - owners_.remove (accessorID()); - } - - private Vector waiters_ = new Vector (); - - private int referenceCount_ = 0; - // Value is -1 if writer has the lock, else this keeps track of the - // number of readers holding the lock. - - private Hashtable owners_ = new Hashtable (); - - private int nestingLevel_ = 0; -} - diff --git a/java/JACE/Concurrency/RenewObject.java b/java/JACE/Concurrency/RenewObject.java deleted file mode 100644 index b690958968a..00000000000 --- a/java/JACE/Concurrency/RenewObject.java +++ /dev/null @@ -1,36 +0,0 @@ -package JACE.Concurrency; - -import JACE.ASX.TimedWait; - -class RenewObject extends TimedWait -{ - public RenewObject (int maxYieldTo) - { - yieldTo_ = maxYieldTo; - } - - public boolean condition () - { - return yieldTo_ <= 0; - } - - public void decrementYieldTo() - { - this.yieldTo_--; - } - - public int yieldTo () - { - return this.yieldTo_; - } - - public RenewObject min (RenewObject other) - { - if (other.yieldTo_ < this.yieldTo_) - return other; - else - return this; - } - - private int yieldTo_; -} diff --git a/java/JACE/Concurrency/Semaphore.java b/java/JACE/Concurrency/Semaphore.java deleted file mode 100644 index 5e558035aee..00000000000 --- a/java/JACE/Concurrency/Semaphore.java +++ /dev/null @@ -1,263 +0,0 @@ -/************************************************* - * - * = PACKAGE - * JACE.Concurrency - * - * = FILENAME - * Semaphore.java - * - *@author Prashant Jain - * - *************************************************/ -package JACE.Concurrency; - -import java.util.*; -import JACE.ASX.*; - -/** - * Implementation of Dijkstra's counting semaphore in java. - * <P> - * <EM>This class does not support recursive semantics.</EM> - */ -public class Semaphore extends LockAdapter -{ - static class TimedWaitSAdapter extends JACE.ASX.TimedWait - { - TimedWaitSAdapter (Object obj) - { - super (obj); - } - - // Check to see if there are any semaphores available. - public boolean condition () - { - return this.count_ > 0; - } - - // Increment the count by one - public void increment () - { - this.count_++; - } - - // Decrement the count by one - public void decrement () - { - this.count_--; - } - - // Set the count - public void count (int c) - { - this.count_ = c; - } - - public int count () - { - return this.count_; - } - - private int count_ = 0; - } - - /** - * Create a Semaphore. - *@param count semaphore count - */ - public Semaphore (int c) - { - this.monitor_.count (c); - this.owners_ = new Hashtable (c); - } - - /** - * Create a binary Semaphore. - */ - public Semaphore () - { - this.monitor_.count (1); - this.owners_ = new Hashtable (1); - } - - public synchronized int tryAcquire () - { - if (this.monitor_.condition ()) { - this.monitor_.decrement (); - setOwner (); - return AbstractLock.SUCCESS; - } else - return AbstractLock.FAILURE; - } - - /** - * Acquire the Semaphore. Throws a TimeoutException if the semaphore - * isn't acquired before the given absolute time. - *@param tv time (TimeValue) to wait until before throwing a - * TimeoutException (unless the semaphore is acquired before that) - *@exception TimeoutException wait timed out exception - *@exception InterruptedException exception during wait - */ - public synchronized int acquire (TimeValue tv) - throws TimeoutException, InterruptedException - { - if (this.monitor_.condition ()) { - this.monitor_.decrement (); - setOwner (); - return AbstractLock.SUCCESS; - } - - numberOfWaiters_++; - - try { - sleepHook (); - this.monitor_.timedWait (tv); - } finally { - numberOfWaiters_--; - } - - this.monitor_.decrement (); - setOwner (); - - return AbstractLock.SLEEPHOOK; - } - - public synchronized int release () - { - if (!isOwner ()) - return AbstractLock.FAILURE; - - if (!signalNextRenewer ()) { - this.monitor_.increment (); - this.monitor_.signal (); - clearOwner (); - } - - return AbstractLock.SUCCESS; - } - - /** - * Checks any objects in the renewers queue, giving one of them - * the lock if it is appropriate. Assumes the synchronization - * lock is already held. - * - *@return true if a renewer was signaled, else false - */ - protected boolean signalNextRenewer () - { - // First find the renewer with the minimum yieldTo count, processing - // all of them along the way. - if (this.renewers_.size() > 0) { - - RenewObject renewer = (RenewObject)renewers_. - elementAt (renewers_.size () - 1); - - renewer.decrementYieldTo (); - - for (int i = this.renewers_.size() - 2; i >=0; i--) { - - RenewObject rwo = (RenewObject)renewers_.elementAt (i); - - rwo.decrementYieldTo (); - - renewer = renewer.min (rwo); - } - - // If the renewer with the minimum yieldTo count has yielded to - // enough threads, or if there are no waiting threads, it should - // be signaled (thus, it wakes up and obtains the lock again). - - if (renewer.condition () || numberOfWaiters_ == 0) { - // Note that we leave monitor_.inUse in the true state so - // we are assured that only the renewer (and not another - // Thread that does an acquire) will gain control. This - // is important since the renew method can't be synchronized - // in its current implementation. - renewers_.removeElement(renewer); - - synchronized (renewer) { - renewer.signal (); - } - - return true; - } - } - - return false; - } - - public int renew (int requeuePosition, - JACE.ASX.TimeValue timeout) - throws InterruptedException, - TimeoutException - { - RenewObject rwo; - - synchronized (this) { - - if (!this.isOwner ()) - return AbstractLock.FAILURE; - - if (numberOfWaiters_ == 0 || - requeuePosition == 0 || - this.monitor_.condition ()) - return AbstractLock.SUCCESS; - - if (requeuePosition < 0 || requeuePosition > numberOfWaiters_) - requeuePosition = numberOfWaiters_; - - rwo = new RenewObject (requeuePosition); - - this.release (); - this.renewers_.addElement (rwo); - } - - boolean exceptionOccured = true; - try { - synchronized (rwo) { - rwo.timedWait (timeout); - - exceptionOccured = false; - } - } finally { - synchronized (this) { - - if (exceptionOccured) { - if (!renewers_.removeElement (rwo)) { - setOwner (); - release (); - } - } else { - setOwner(); - } - } - } - - // By this point, we should know that we have the lock. The inUse - // flag is never set to false in the release() call from the Thread - // that gave us control. That thread also set the owner value. - - return AbstractLock.SUCCESS; - } - - protected boolean isOwner () - { - return owners_.containsKey (accessorID()); - } - - protected void setOwner () - { - owners_.put (accessorID(), this); - } - - protected void clearOwner () - { - owners_.remove (accessorID()); - } - - private TimedWaitSAdapter monitor_ = new TimedWaitSAdapter (this); - // The monitor (adapter) to wait on - - private Hashtable owners_; - private Vector renewers_ = new Vector (); - private int numberOfWaiters_ = 0; -} diff --git a/java/JACE/Concurrency/ThreadManager.java b/java/JACE/Concurrency/ThreadManager.java deleted file mode 100644 index d23e2410676..00000000000 --- a/java/JACE/Concurrency/ThreadManager.java +++ /dev/null @@ -1,113 +0,0 @@ -/************************************************* - * - * = PACKAGE - * JACE.Concurrency - * - * = FILENAME - * ThreadManager.java - * - *@author Prashant Jain - * - *************************************************/ -package JACE.Concurrency; - -import java.util.*; -import JACE.OS.*; - -/** - * Wrapper for a ThreadGroup which provides additional methods for - * creating a certain number of Runnable instances. - */ -public class ThreadManager -{ - /** - * Default constructor - */ - public ThreadManager () - { - this (ACE.DEFAULT_THREAD_GROUP_NAME); - } - - /** - * Create a Thread Manager. - *@param groupName name of the thread group that the Thread Manager - * will manage - */ - public ThreadManager (String groupName) - { - this.thrGrp_ = new ThreadGroup (groupName); - if (this.thrGrp_ == null) - ACE.ERROR ("Thread group create failed"); - } - - /** - * Create a new thread. - *@param thr the caller whose run method will be invoked when the - * thread has been spawned - *@param daemon flag indicating whether the thread should be - * spawned off as a daemon thread - */ - public void spawn (Runnable thr, - boolean daemon) - { - Thread t = new Thread (this.thrGrp_, thr); - if (daemon) // Set the thread to be a daemon thread - t.setDaemon (true); - t.start (); - } - - /** - * Create a new thread and also give it a name. - *@param thr the caller whose run method will be invoked when the - * thread has been spawned - *@param threadName the name of the new thread - *@param daemon flag indicating whether the thread should be - * spawned off as a daemon thread - */ - public void spawn (Runnable thr, - String threadName, - boolean daemon) - { - Thread t = new Thread (this.thrGrp_, thr, threadName); - if (daemon) // Set the thread to be a daemon thread - t.setDaemon (true); - t.start (); - } - - - /** - * Create <n> new threads. - *@param n the number of threads to spawn - *@param thr the caller whose run method will be invoked by each of - * the <n> threads - *@param daemon flag indicating whether the threads should be - * spawned off as daemon threads - */ - public void spawnN (int n, - Runnable thr, - boolean daemon) - { - // Spawn off all the threads. - for (int i = 0; i < n; i++) - { - this.spawn (thr, daemon); - } - } - - /** - * Get the thread group containing all the threads. Note that the - * thread group can be used to get information regarding number of - * active threads as well as to suspend/resume all the threads in - * the group. - *@return the thread group that contains all the threads managed by - * the Thread Manager - */ - public ThreadGroup thrGrp () - { - return this.thrGrp_; - } - - private ThreadGroup thrGrp_; - // Thread Group that contains all the spawned threads - -} diff --git a/java/JACE/Concurrency/Token.java b/java/JACE/Concurrency/Token.java deleted file mode 100644 index c9080b47fbe..00000000000 --- a/java/JACE/Concurrency/Token.java +++ /dev/null @@ -1,301 +0,0 @@ -/************************************************* - * - * = PACKAGE - * JACE.Concurrency - * - * = FILENAME - * Token.java - * - *@author Prashant Jain - * - *************************************************/ -package JACE.Concurrency; - -import java.util.*; -import JACE.ASX.*; - -import JACE.OS.*; - -/** - * Class that acquires, renews, and releases a synchronization - * token that is serviced in strict FIFO ordering. - * <P> - * This is a general-purpose synchronization mechanism that offers - * several benefits. For example, it implements "recursive mutex" - * semantics, where a thread that owns the token can reacquire it - * without deadlocking. In addition, threads that are blocked - * awaiting the token are serviced in strict FIFO order as other - * threads release the token. The solution makes use of the - * Specific Notification pattern presented by Tom Cargill in - * "Specific Notification for Java Thread Synchronization," PLoP96. - * - * <P> - * This class DOES support recursive semantics. - */ -public class Token extends LockAdapter -{ - /** - * Acquire ownership of the lock, blocking indefinitely if necessary. - * <P> - *@return AbstractLock.FAILURE or AbstractLock.SUCCESS - *@exception InterruptedException indicates another thread has - * interrupted this one during wait - */ - public int acquire () throws InterruptedException - { - try - { - return this.acquire (null); - } - catch (TimeoutException e) - { - // This really shouldn't happen since we are supposed to - // block. - return AbstractLock.FAILURE; - } - } - - /** - * Acquire the token by the given absolute time time-out. The - * method uses synchronized blocks internally to avoid race conditions. - *@param timeout time to wait until before throwing a - * TimeoutException (unless the token is acquired before that). - * Performs a blocking acquire if the given timeout is null. - *@return AbstractLock.SUCCESS if acquires without calling <sleepHook> - * AbstractLock.SLEEPHOOK if <sleepHook> is called. - * AbstractLock.FAILURE if failure occurs - *@exception TimeoutException if time-out occurs - *@exception InterruptedException exception during wait - */ - public int acquire (TimeValue timeout) throws TimeoutException, - InterruptedException - { - int result = AbstractLock.SUCCESS; - WaitObject snl = new WaitObject (); - boolean mustWait; - synchronized (snl) - { - synchronized (this) - { - mustWait = !this.snq_.isEmpty (); - - if (mustWait && isOwner ()) - { - // I am the one who has the token. So just increment - // the nesting level - this.nestingLevel_++; - return AbstractLock.SUCCESS; - } - // Add local lock to the queue - this.snq_.addElement (snl); - } - if (mustWait) - { - result = AbstractLock.SLEEPHOOK; - sleepHook(); - - boolean exceptionOccured = true; - try { - snl.timedWait(timeout); - exceptionOccured = false; - } finally { - if (exceptionOccured) { - synchronized (this) { - if (!snq_.removeElement (snl)) { - setOwner (); - release (); - } - } - } - } - } - - // Set the owner of the token - synchronized (this) { - setOwner(); - } - } - - return result; - } - - /** - * Try to acquire the token. Implements a non-blocking acquire. - * - *@return AbstractLock.SUCCESS if acquires - * AbstractLock.FAILURE if failure occurs - */ - public synchronized int tryAcquire () - { - int result = AbstractLock.SUCCESS; - - if (this.snq_.isEmpty ()) - { - // No one has the token, so acquire it - this.snq_.addElement (new WaitObject ()); - - setOwner(); - } - else if (isOwner()) - { - this.nestingLevel_++; - } - // Someone else has the token. - else - { - // Would have to block to acquire the token, so return - // failure. - result = AbstractLock.FAILURE; - } - return result; - } - - /** - * An optimized method that efficiently reacquires the token if no - * other threads are waiting. This is useful for situations where - * you don't want to degrade the quality of service if there are - * other threads waiting to get the token. If the given TimeValue - * is null, it's the same as calling renew(int requeuePosition). - *@param requeuePosition Position in the queue where to insert the - * lock. If requeuePosition == -1 and there are other threads - * waiting to obtain the token we are queued at the end of the list - * of waiters. If requeuePosition > -1 then it indicates how many - * entries to skip over before inserting our thread into the list of - * waiters (e.g.,requeuePosition == 0 means "insert at front of the - * queue"). - *@param timeout Throw a TimeoutException if the token isn't renewed - * before this absolute time timeout. - *@return AbstractLock.SUCCESS if renewed the lock - * AbstractLock.FAILURE if failure occurs - *@exception TimeoutException exception if timeout occurs - *@exception InterruptedException exception during wait - */ - public int renew (int requeuePosition, TimeValue timeout) - throws TimeoutException, InterruptedException - { - WaitObject snl = null; - int saveNestingLevel = 0; - - synchronized (this) - { - if (!isOwner ()) - return AbstractLock.FAILURE; - - // Check if there is a thread waiting to acquire the token. If - // not or if requeuePosition == 0, then we don't do anything - // and we simply keep the token. - if (this.snq_.size () > 1 && requeuePosition != 0) - { - // Save the nesting level - saveNestingLevel = this.nestingLevel_; - this.nestingLevel_ = 0; - - // Reinsert ourselves at requeuePosition in the queue - snl = (WaitObject) this.snq_.firstElement (); - this.snq_.removeElementAt (0); - - if (requeuePosition < 0) - this.snq_.addElement (snl); // Insert at end - else - this.snq_.insertElementAt (snl, Math.min(requeuePosition, - this.snq_.size())); - - synchronized (this.snq_.firstElement ()) - { - // Notify the first waiting thread in the queue - WaitObject obj = (WaitObject) this.snq_.firstElement (); - // Set its condition to be true so that it falls out - // of the for loop - obj.condition (true); - // Now signal the thread - obj.signal (); - } - } - } - - // Check if we reinserted the lock in the queue and therefore need - // to do a wait - if (snl != null) - { - synchronized (snl) - { - // Set the condition to be false so that we can begin the - // wait - snl.condition (false); - // Wait until the given absolute time (or until notified - // if the timeout is null) - - boolean exceptionOccured = true; - try { - - snl.timedWait (timeout); - - exceptionOccured = false; - - } finally { - if (exceptionOccured) { - synchronized (this) { - if (!snq_.removeElement (snl)) { - setOwner (); - release (); - } - } - } - } - } - - synchronized (this) { - // Restore the nesting level and current owner of the lock - this.nestingLevel_ = saveNestingLevel; - - // Set the owner of the token - setOwner(); - } - } - - return AbstractLock.SUCCESS; - } - - /** - * Release the token. It is safe for non-owners to call - * this. - *@return AbstractLock.SUCCESS on success - * AbstractLock.FAILURE on failure (for instance, a non-owner - * calling release) - */ - public synchronized int release () - { - if (!isOwner()) - return AbstractLock.FAILURE; - - // Check if nestingLevel > 0 and if so, decrement it - if (this.nestingLevel_ > 0) - this.nestingLevel_--; - else - { - clearOwner (); - this.snq_.removeElementAt (0); - if (!this.snq_.isEmpty ()) - { - synchronized (this.snq_.firstElement ()) - { - // Notify the first waiting thread in the queue - WaitObject obj = (WaitObject) this.snq_.firstElement (); - // Set its condition to be true so that it falls out - // of the for loop - obj.condition (true); - // Now signal the thread - obj.signal (); - } - } - } - - return AbstractLock.SUCCESS; - } - - private Vector snq_ = new Vector (); - // Vector of lock objects - - private int nestingLevel_ = 0; - // Current Nesting Level -} diff --git a/java/JACE/Concurrency/WaitObject.java b/java/JACE/Concurrency/WaitObject.java deleted file mode 100644 index b7c8cbc7191..00000000000 --- a/java/JACE/Concurrency/WaitObject.java +++ /dev/null @@ -1,39 +0,0 @@ -package JACE.Concurrency; - -import JACE.ASX.TimedWait; - -class WaitObject extends TimedWait -{ - public WaitObject () - { - super (); - } - - public WaitObject (Object obj) - { - super (obj); - } - - public WaitObject (boolean initialState) - { - condition_ = initialState; - } - - public WaitObject (boolean initialState, Object obj) - { - super (obj); - condition_ = initialState; - } - - public boolean condition () - { - return this.condition_; - } - - public void condition (boolean c) - { - this.condition_ = c; - } - - private boolean condition_ = false; -} diff --git a/java/JACE/Concurrency/package.html b/java/JACE/Concurrency/package.html deleted file mode 100644 index ceadb36f662..00000000000 --- a/java/JACE/Concurrency/package.html +++ /dev/null @@ -1,15 +0,0 @@ -<!-- $Id$ --> -<HTML> -<BODY> -Collection of concurrency mechanisms and a Thread manager. -<P> -JACE concurrency mechanisms now inherit from a common base class, -AbstractLock. This allows users to write code without regard to -whether a lock is local or remote. - -@see JACE.netsvcs.Token.RemoteLock -@see <a href="http://www.cs.wustl.edu/~schmidt/ACE-papers.html#concurrency">Documents on ACE concurrency components</a> -</BODY> -</HTML> - - |