summaryrefslogtreecommitdiff
path: root/java/src
diff options
context:
space:
mode:
authorpjain <pjain@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1996-11-26 21:15:13 +0000
committerpjain <pjain@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1996-11-26 21:15:13 +0000
commit216ad0211bf0563c270b258ebd7e1972b0b53cd4 (patch)
treee2717aa9b5e6534d3f846af734254ad8c7b46568 /java/src
parent467e1675f855ef22d18d46ae28b318d3fe5795e4 (diff)
downloadATCD-216ad0211bf0563c270b258ebd7e1972b0b53cd4.tar.gz
Modified TimerQueue so that we can specify at construction time whether to
create an internal thread or not.
Diffstat (limited to 'java/src')
-rw-r--r--java/src/TimerQueue.java160
1 files changed, 100 insertions, 60 deletions
diff --git a/java/src/TimerQueue.java b/java/src/TimerQueue.java
index 1560332f5b3..eeab38f9206 100644
--- a/java/src/TimerQueue.java
+++ b/java/src/TimerQueue.java
@@ -85,53 +85,77 @@ class WaitObject extends TimedWait
public class TimerQueue implements Runnable
{
/**
- * Default Constructor
+ * Constructor.
+ *@param createInternalThread flag specifying whether to create an
+ * internal thread that runs the event loop. If it is true, a thread
+ * is spawned and it runs the event loop, handling all timeout
+ * events. If it is false, the caller is then responsible for calling
+ * handleEvents () to run the event loop.
*/
- public TimerQueue ()
+ public TimerQueue (boolean createInternalThread)
{
- new Thread (this).start ();
+ this.eventLoopRunning_ = false;
+ if (createInternalThread)
+ new Thread (this).start ();
}
-
+
/**
- * This is the work horse of TimerQueue. It forms the event loop and
- * takes care of all scheduling.
+ * The thread run method. Do *NOT* call this method! It gets called
+ * automatically.
*/
public void run ()
{
- TimeValue timeout = null;
- TimeValue earliest = null;
+ this.handleEvents ();
+ }
- for (;;)
+ /**
+ * Handle timeout events. This forms the event loop and takes care
+ * of all scheduling. This method should only be called if the Timer
+ * Queue was constructed with the value of createInternalThread as
+ * false.
+ */
+ public void handleEvents ()
+ {
+ if (!this.eventLoopRunning_)
{
- synchronized (this.obj_)
+ // Set the flag indicating that the event loop is now running
+ this.eventLoopRunning_ = true;
+
+ TimeValue timeout = null;
+ TimeValue earliest = null;
+
+ for (;;)
{
- earliest = this.earliestTime ();
- if (earliest != null)
- timeout = TimeValue.minus (earliest, TimeValue.getTimeOfDay ());
- else
- timeout = new TimeValue ();
- try
+ synchronized (this.obj_)
{
- // Extract the earliest time from the queue and do a timed wait
- this.obj_.timedWait (timeout);
+ earliest = this.earliestTime ();
+ if (earliest != null)
+ timeout = TimeValue.minus (earliest, TimeValue.getTimeOfDay ());
+ else
+ timeout = new TimeValue ();
+ try
+ {
+ // Extract the earliest time from the queue and do a timed wait
+ this.obj_.timedWait (timeout);
- // We have been notified. Check to see if we need to
- // restart the wait with a different timeout
- if (this.reset_)
+ // We have been notified. Check to see if we need to
+ // restart the wait with a different timeout
+ if (this.reset_)
+ {
+ this.reset_ = false;
+ this.obj_.condition (false);
+ timeout = TimeValue.minus (this.earliestTime (), TimeValue.getTimeOfDay ());
+ }
+ }
+ catch (TimeoutException e)
+ {
+ // Timeout occurred. Call handleTimeout on appropriate
+ // Event Handlers
+ this.dispatchHandlers ();
+ }
+ catch (InterruptedException e)
{
- this.reset_ = false;
- this.obj_.condition (false);
- timeout = TimeValue.minus (this.earliestTime (), TimeValue.getTimeOfDay ());
}
- }
- catch (TimeoutException e)
- {
- // Timeout occurred. Call handleTimeout on appropriate
- // Event Handlers
- this.dispatchHandlers ();
- }
- catch (InterruptedException e)
- {
}
}
}
@@ -211,7 +235,15 @@ public class TimerQueue implements Runnable
this.timerId_);
synchronized (this.obj_)
{
- if (this.isEmpty () || futureTime.lessThan (this.earliestTime ()))
+ // Check if event loop is running. If it is not, then we can
+ // just place it at the appropriate place in the queue and
+ // don't need to do any notification. If event loop is
+ // running, then check if the node is the first node in the
+ // queue (either because the queue is empty or because the
+ // time for the node is earlier than the currently scheduled
+ // timer node).
+ if (this.eventLoopRunning_ &&
+ (this.isEmpty () || futureTime.lessThan (this.earliestTime ())))
{
// Insert the node into (the beginning of) the queue to be
// scheduled.
@@ -221,7 +253,7 @@ public class TimerQueue implements Runnable
// using the earliest timeout
this.obj_.notify ();
}
- else // Place in the middle of the list somewhere.
+ else // Place in the appropriate position in the queue.
{
this.reschedule (node);
}
@@ -241,21 +273,23 @@ public class TimerQueue implements Runnable
TimerNode prev = null;
TimerNode curr = null;
- // Try to locate the TimerNode that matches the timerId.
-
- for (curr = this.head_;
- curr != null && curr.timerId_ != timerId;
- curr = curr.next_)
- prev = curr;
-
- if (curr != null)
+ synchronized (this.obj_)
{
- if (prev == null)
- this.head_ = curr.next_;
- else
- prev.next_ = curr.next_;
+ // Try to locate the TimerNode that matches the timerId.
+ for (curr = this.head_;
+ curr != null && curr.timerId_ != timerId;
+ curr = curr.next_)
+ prev = curr;
- return curr.arg_;
+ if (curr != null)
+ {
+ if (prev == null)
+ this.head_ = curr.next_;
+ else
+ prev.next_ = curr.next_;
+
+ return curr.arg_;
+ }
}
return null;
}
@@ -269,26 +303,29 @@ public class TimerQueue implements Runnable
TimerNode prev = null;
TimerNode curr = this.head_;
- while (curr != null)
+ synchronized (this.obj_)
{
- if (curr.handler_ == handler)
+ while (curr != null)
{
- if (prev == null)
+ if (curr.handler_ == handler)
{
- this.head_ = curr.next_;
- curr = this.head_;
+ if (prev == null)
+ {
+ this.head_ = curr.next_;
+ curr = this.head_;
+ }
+ else
+ {
+ prev.next_ = curr.next_;
+ curr = prev.next_;
+ }
}
else
{
- prev.next_ = curr.next_;
- curr = prev.next_;
+ prev = curr;
+ curr = curr.next_;
}
}
- else
- {
- prev = curr;
- curr = curr.next_;
- }
}
}
@@ -377,5 +414,8 @@ public class TimerQueue implements Runnable
private boolean reset_;
// Flag indicating whether to start the wait again
+
+ private boolean eventLoopRunning_;
+ // Flag indicating whether the event loop is running or not
}