summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
authorpjain <pjain@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1996-11-22 04:24:06 +0000
committerpjain <pjain@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1996-11-22 04:24:06 +0000
commit88aa3350698954b097db8533a892fb45f6e59149 (patch)
tree510b8923590775106e107182371edd34c5888463 /java
parentbc93ab7046510f4e464ed0694a75b278ce864d39 (diff)
downloadATCD-88aa3350698954b097db8533a892fb45f6e59149.tar.gz
Added timed waits to Token acquire and renew.
Diffstat (limited to 'java')
-rw-r--r--java/src/Token.java107
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 ();
}
}
}