summaryrefslogtreecommitdiff
path: root/java/JACE/Reactor/TimerQueue.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/JACE/Reactor/TimerQueue.java')
-rw-r--r--java/JACE/Reactor/TimerQueue.java437
1 files changed, 0 insertions, 437 deletions
diff --git a/java/JACE/Reactor/TimerQueue.java b/java/JACE/Reactor/TimerQueue.java
deleted file mode 100644
index 638cffe3391..00000000000
--- a/java/JACE/Reactor/TimerQueue.java
+++ /dev/null
@@ -1,437 +0,0 @@
-/*************************************************
- *
- * = PACKAGE
- * JACE.Reactor
- *
- * = FILENAME
- * TimerQueue.java
- *
- *@author Prashant Jain
- *
- *************************************************/
-package JACE.Reactor;
-
-import java.util.*;
-import JACE.ASX.*;
-
-import JACE.OS.*;
-
-/**
- * Timer Queue implementation which calls back to the handleTimeout
- * method on EventHandler implementations when their timers expire.
- * <P>
- * This is a simple implementation that keeps a linked list of
- * absolute timers. It allows multiple timers to be scheduled
- * and returns a timer id for each timer scheduled. In addition,
- * it allows periodic timers to be scheduled.
- * <P>
- * Note that timeouts given to the TimerQueue are relative time
- * ("2 seconds from now", etc).
- */
-public class TimerQueue implements Runnable
-{
- static class TimerNode
- {
- public TimerNode (EventHandler handler,
- Object arg,
- TimeValue timerValue,
- TimeValue interval,
- TimerNode next,
- int timerId)
- {
- this.handler_ = handler;
- this.arg_ = arg;
- this.timerValue_ = timerValue;
- this.interval_ = interval;
- this.next_ = next;
- this.timerId_ = timerId;
- }
-
- public EventHandler handler_;
- // Handler to invoke <handleTimeout> on when a timeout occurs.
-
- public Object arg_;
- // Argument to pass to <handleTimeout>.
-
- public TimeValue timerValue_;
- // Time until the timer expires.
-
- public TimeValue interval_;
- // If this is a periodic timer this holds the time until the next
- // timeout.
-
- public TimerNode next_;
- // Pointer to next timer.
-
- public int timerId_;
- // Id of this timer (used to cancel timers before they expire).
- }
-
- static class WaitObject extends TimedWait
- {
- public boolean condition ()
- {
- return this.condition_;
- }
-
- public void condition (boolean c)
- {
- this.condition_ = c;
- }
-
- private boolean condition_ = false;
- }
-
- /**
- * Constructor. The caller is responsible for calling handleEvents ()
- * to run the event loop.
- */
- public TimerQueue ()
- {
- this (false);
- }
-
- /**
- * 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. The thread that is created
- * is set to be a daemon thread.
- */
- public TimerQueue (boolean createInternalThread)
- {
- this.eventLoopRunning_ = false;
- if (createInternalThread) {
- Thread queueThread = new Thread (this, "Timer Queue");
- queueThread.setDaemon (true);
- queueThread.start ();
- }
- }
-
- /**
- * The thread run method. Do *NOT* call this method! It gets called
- * automatically.
- */
- public void run ()
- {
- this.handleEvents ();
- }
-
- /**
- * 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_)
- {
- // Set the flag indicating that the event loop is now running
- this.eventLoopRunning_ = true;
-
- for (;;)
- {
- synchronized (this.obj_)
- {
- try {
- // Extract the earliest time from the queue and do a
- // timed wait
-
- this.obj_.timedWait (this.earliestTime ());
-
- // 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);
- }
-
- } catch (TimeoutException e) {
- // Timeout occurred. Call handleTimeout on appropriate
- // Event Handlers
- this.dispatchHandlers ();
-
- } catch (InterruptedException e) {
- ACE.ERROR ("TimerQueue was interrupted");
- return;
- }
- }
- }
- }
- }
-
- /**
- * Check if the queue is empty.
- *@return true if queue is empty, else false.
- */
- boolean isEmpty ()
- {
- return this.head_ == null;
- }
-
- /**
- * Get the node of the earliest node in the TimerQueue.
- *@return the time of the earlier node in the TimerQueue.
- */
- TimeValue earliestTime ()
- {
- synchronized (this.obj_)
- {
- if (!this.isEmpty ())
- return this.head_.timerValue_;
- else
- return null;
- }
- }
-
- /**
- * Schedule an <EventHandler> that will expire after <delta> amount
- * of time. If it expires then <obj> is passed in as the value to
- * the <EventHandler>'s <handleTimeout> callback method. This method
- * returns a timer id that uniquely identifies the timer and can be
- * used to cancel the timer before it expires.
- *@param handler Event Handler that is to be scheduled with the timer
- *@param obj Object that is passed back to the Event Handler when
- * timeout occurs (Asynchronous Completion Token)
- *@param delta amount of time for which to schedule the timer
- *@return id of the timer scheduled
- */
- public int scheduleTimer (EventHandler handler,
- Object obj,
- TimeValue delta)
- {
- return this.scheduleTimer (handler, obj, delta, TimeValue.zero);
- }
-
- /**
- * Schedule an <EventHandler> that will expire after <delta> amount
- * of time. If it expires then <obj> is passed in as the value to
- * the <EventHandler>'s <handleTimeout> callback method. If
- * <interval> is != to <TimeValue.zero> then it is used to
- * reschedule the <EventHandler> automatically. This method
- * returns a timer id that uniquely identifies the timer and can be
- * used to cancel the timer before it expires.
- *@param handler Event Handler that is to be scheduled with the timer
- *@param arg Object that is passed back to the Event Handler when
- * timeout occurs (Asynchronous Completion Token)
- *@param timeout amount of time for which to schedule the timer
- *@param interval amount of time to use to reschedule the timer
- *@return id of the timer scheduled
- */
- public int scheduleTimer (EventHandler handler,
- Object arg,
- TimeValue timeout,
- TimeValue interval)
- {
-
- // Increment the sequence number (it will wrap around).
- this.timerId_++;
-
- ACE.DEBUG("scheduleTimer (" + this.timerId_ + "): " +
- timeout + ", " + interval);
-
-
- TimeValue futureTime = TimeValue.plus (timeout, TimeValue.getTimeOfDay ());
- TimerNode node = new TimerNode (handler,
- arg,
- futureTime,
- interval,
- null,
- this.timerId_);
- synchronized (this.obj_)
- {
- // 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.
- this.reschedule (node);
-
- // Notify the waiting thread so that it can reschedule
- // using the earliest timeout
- this.obj_.notify ();
- }
- else // Place in the appropriate position in the queue.
- {
- this.reschedule (node);
- }
- }
- return this.timerId_;
- }
-
-
- /**
- * Cancel the single timer associated with <timerId>.
- *@param timerId id of the timer that needs to be cancelled.
- *@return Object that was passed in when timer was scheduled
- * (Asynchronous Completion Token).
- */
- public Object cancelTimer (int timerId)
- {
- TimerNode prev = null;
- TimerNode curr = null;
-
- synchronized (this.obj_)
- {
- // 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)
- {
- if (prev == null)
- this.head_ = curr.next_;
- else
- prev.next_ = curr.next_;
-
- return curr.arg_;
- }
- }
- return null;
- }
-
- /**
- * Cancel all timers associated with <Event Handler>.
- *@param handler Event Handler whose associated timers need to be cancelled.
- */
- public void cancelTimer (EventHandler handler)
- {
- TimerNode prev = null;
- TimerNode curr = this.head_;
-
- synchronized (this.obj_)
- {
- while (curr != null)
- {
- if (curr.handler_ == handler)
- {
- if (prev == null)
- {
- this.head_ = curr.next_;
- curr = this.head_;
- }
- else
- {
- prev.next_ = curr.next_;
- curr = prev.next_;
- }
- }
- else
- {
- prev = curr;
- curr = curr.next_;
- }
- }
- }
- }
-
- // Call handleTimeout() on all handlers whose timers have expired.
- private void dispatchHandlers ()
- {
- TimeValue currentTime = TimeValue.getTimeOfDay ();
-
- for (;;)
- {
- if (this.isEmpty () || this.earliestTime ().greaterThan (currentTime))
- break; // There aren't any more timers eligible to expire.
-
- TimerNode expired = this.head_;
- EventHandler handler = expired.handler_;
- Object arg = expired.arg_;
- int result;
-
- this.head_ = this.head_.next_;
-
- // Check whether this is an interval timer.
- if (expired.interval_.greaterThan (TimeValue.zero))
- {
- // Make sure that we skip past values that have already
- // "expired".
- do
- expired.timerValue_.plusEquals (expired.interval_);
- while (expired.timerValue_.lessThanEqual (currentTime));
-
- // Since this is an interval timer, we need to reschedule
- // it.
- this.reschedule (expired);
- }
-
- ACE.DEBUG("Calling handleTimeout for ID " + expired.timerId_);
-
- // Perform the callback.
- result = handler.handleTimeout (currentTime, arg);
-
- if (result == -1)
- this.cancelTimer (handler);
- }
- }
-
- // Reschedule a TimerNode by inserting it at the appropriate
- // position in the queue.
- private void reschedule (TimerNode expired)
- {
- if (this.isEmpty () ||
- expired.timerValue_.lessThan (this.earliestTime ()))
- {
- expired.next_ = this.head_;
- this.head_ = expired;
- // Set the condition to true so that the waiting thread can be
- // notified and it can reschedule.
- this.obj_.condition (true);
- this.reset_ = true;
- }
- else
- {
- TimerNode prev = this.head_;
- TimerNode after = this.head_.next_;
-
- // Locate the proper position in the queue.
-
- while (after != null
- && expired.timerValue_.greaterThan (after.timerValue_))
- {
- prev = after;
- after = after.next_;
- }
-
- expired.next_ = after;
- prev.next_ = expired;
- }
- }
-
- public boolean eventLoopRunning ()
- {
- return eventLoopRunning_;
- }
-
- private WaitObject obj_ = new WaitObject ();
- // Synchronization object (as well as object to use to do wait on)
-
- private TimerNode head_;
- // Pointer to linked list of TimerHandles.
-
- private int timerId_;
- // Keeps track of the timer id that uniquely identifies each timer.
- // This id can be used to cancel a timer via the <cancel (int)>
- // method.
-
- private boolean reset_;
- // Flag indicating whether to start the wait again
-
- private boolean eventLoopRunning_;
- // Flag indicating whether the event loop is running or not
-}
-