diff options
author | pjain <pjain@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1996-11-22 04:24:06 +0000 |
---|---|---|
committer | pjain <pjain@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1996-11-22 04:24:06 +0000 |
commit | 88aa3350698954b097db8533a892fb45f6e59149 (patch) | |
tree | 510b8923590775106e107182371edd34c5888463 /java | |
parent | bc93ab7046510f4e464ed0694a75b278ce864d39 (diff) | |
download | ATCD-88aa3350698954b097db8533a892fb45f6e59149.tar.gz |
Added timed waits to Token acquire and renew.
Diffstat (limited to 'java')
-rw-r--r-- | java/src/Token.java | 107 |
1 files changed, 98 insertions, 9 deletions
diff --git a/java/src/Token.java b/java/src/Token.java index 83205b106c6..166874882e5 100644 --- a/java/src/Token.java +++ b/java/src/Token.java @@ -12,6 +12,22 @@ package ACE.Concurrency; import java.util.*; +import ACE.ASX.*; + +class WaitObject extends TimedWait +{ + public boolean condition () + { + return this.condition_; + } + + public void condition (boolean c) + { + this.condition_ = c; + } + + private boolean condition_ = false; +} /** * <hr> @@ -44,8 +60,33 @@ public class Token */ public int acquire () throws InterruptedException { + try + { + return this.acquire (new TimeValue ()); + } + catch (TimeoutException e) + { + // This really shouldn't happen since we are supposed to + // block. + return -1; + } + } + + /** + * Acquire the token. Wait for timeout amount of time. The method + * uses synchronized blocks internally to avoid race conditions. + *@param timeout Amount of time to wait for in trying to acquire the + * token. + *@return 0 if acquires without calling <sleepHook> + * 1 if <sleepHook> is called. + * -1 if failure occurs + *@exception TimeoutException exception if timeout occurs + *@exception InterruptedException exception during wait + */ + public int acquire (TimeValue timeout) throws InterruptedException, TimeoutException + { int result = 0; - Object snl = new Object (); + WaitObject snl = new WaitObject (); boolean mustWait; synchronized (snl) { @@ -68,7 +109,7 @@ public class Token result = 1; // Call sleep hook sleepHook (); - snl.wait (); + snl.timedWait (timeout); // Do a blocking wait } // Set the owner of the token this.owner_ = Thread.currentThread ().toString (); @@ -88,13 +129,14 @@ public class Token if (!this.snq_.isEmpty ()) { // No one has the token, so acquire it - this.snq_.addElement (new Object ()); + this.snq_.addElement (new WaitObject ()); } + // Check if I am the one holding the token. else if (Thread.currentThread ().toString ().compareTo (this.owner_) == 0) { - // Someone has the token. Check if it is me. this.nestingLevel_++; } + // Someone else has the token. else { // Will have to block to acquire the token, so call @@ -127,10 +169,42 @@ public class Token * entries to skip over before inserting our thread into the list of * waiters (e.g.,requeuePosition == 0 means "insert at front of the * queue"). + *@exception InterruptedException exception during wait */ public void renew (int requeuePosition) throws InterruptedException { - Object snl = null; + try + { + this.renew (requeuePosition, new TimeValue ()); + } + catch (TimeoutException e) + { + // This really shouldn't happen since we are supposed to + // block. + } + } + + /** + * 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. + *@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 Amount of time to wait for in trying to acquire the + * token. + *@exception TimeoutException exception if timeout occurs + *@exception InterruptedException exception during wait + */ + public void renew (int requeuePosition, TimeValue timeout) + throws InterruptedException, TimeoutException + { + WaitObject snl = null; int saveNestingLevel = 0; synchronized (this) @@ -145,7 +219,7 @@ public class Token this.nestingLevel_ = 0; // Reinsert ourselves at requeuePosition in the queue - snl = this.snq_.firstElement (); + snl = (WaitObject) this.snq_.firstElement (); this.snq_.removeElementAt (0); if (requeuePosition < 0) @@ -156,7 +230,12 @@ public class Token synchronized (this.snq_.firstElement ()) { // Notify the first waiting thread in the queue - this.snq_.firstElement ().notify (); + 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 (); } } } @@ -167,7 +246,11 @@ public class Token { synchronized (snl) { - snl.wait (); + // Set the condition to be false so that we can begin the + // wait + snl.condition (false); + // Do a blocking wait + snl.timedWait (timeout); } // Restore the nesting level and current owner of the lock this.nestingLevel_ = saveNestingLevel; @@ -190,7 +273,13 @@ public class Token { synchronized (this.snq_.firstElement ()) { - this.snq_.firstElement ().notify (); + // 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 (); } } } |