Exemplo n.º 1
0
 int loop() {
   long _fireTime;
   long t = System.currentTimeMillis();
   BaseTimerTask e;
   int fireCnt = 0;
   for (; ; ) {
     boolean _fires;
     synchronized (timer.lock) {
       Queue q = timer.outQueue;
       for (; ; ) {
         e = q.getNextNotCancelledMin();
         if (e == null) {
           return fireCnt;
         }
         _fires = false;
         _fireTime = e.getTime();
         if (_fireTime > t) {
           t = System.currentTimeMillis();
         }
         if (_fireTime <= t) {
           if (_fireTime < t) { // missed timely execution?
             recordLapse(_fireTime, t);
           }
           q.removeMin();
           BaseTimerTask _next = q.getMin();
           boolean _fireWithinLock = _next != null && _fireTime == _next.getTime();
           if (_fireWithinLock) {
             fireTask(e);
             fireCnt++;
             continue;
           }
           _fires = true;
         }
         break;
       } // inner for loop
     } // synchronized
     if (_fires) {
       fireTask(e);
       fireCnt++;
     } else {
       long _waitTime = _fireTime - t;
       waitUntilTimeout(_waitTime);
     }
   } // outer loop
 }
Exemplo n.º 2
0
 void fireTask(BaseTimerTask e) {
   try {
     boolean f = e.fire(e.getTime());
     if (f) {
       timer.eventsDelivered++;
     } else {
       cancelCount++;
     }
   } catch (Throwable ex) {
     timer.fireExceptionCount++;
     timer.log.warn("timer event caused exception", ex);
   }
 }
Exemplo n.º 3
0
  /**
   * Cleans cancelled timer tasks from the priority queue. We do this just in the thread that calls
   * us, but without holding up event delivery . When a purge occurs we work with two queues. One
   * for added timer tasks and one for delivered timer tasks. Newly added timer tasks will be
   * appended to the the out queue after the purge is finished. Thus, the delivery of new timer
   * tasks is delayed after the purge is finished.
   *
   * <p>One tricky thing is to catch up with tasks that fired during the purge from the out queue.
   * This is achieved by skipping to the time of the task that will fire next and by the ensurance
   * that the timer thread will always process events of the same time within one synchronized
   * block.
   */
  void performPurge() {
    Queue _purgeQ;
    int _queueSizeBefore;
    synchronized (lock) {
      if (inQueue != outQueue || inQueue.size == 0) {
        return;
      }
      addedWithoutPurge = Integer.MIN_VALUE;
      cancelCount += inQueue.cancelCount;
      outQueue.cancelCount = 0;
      _purgeQ = outQueue.copy();
      inQueue = new Queue();
      _queueSizeBefore = outQueue.size;
    }
    _purgeQ.purge();
    synchronized (lock) {
      boolean _somethingFired = outQueue.size != _queueSizeBefore;
      if (_somethingFired) {
        BaseTimerTask _nextTimerTaskInQueue = outQueue.getNextNotCancelledMin();
        if (_nextTimerTaskInQueue == null) {

          cancelCount += outQueue.cancelCount;
          _purgeQ = new Queue();
        } else {
          long _forwardUntilTime = _nextTimerTaskInQueue.getTime();
          BaseTimerTask t;
          BaseTimerTask _previousSkippedTask = null;
          while ((t = _purgeQ.getMin()).getTime() != _forwardUntilTime) {
            if (t.isCancelled()) {
              _purgeQ.cancelCount++;
            }
            _purgeQ.removeMin();
            _previousSkippedTask = t;
          }
        }
      }
      BaseTimerTask t;
      while ((t = inQueue.getNextNotCancelledMin()) != null) {
        inQueue.removeMin();
        _purgeQ.addQueue(t);
      }
      cancelCount += inQueue.cancelCount;
      inQueue = outQueue = _purgeQ;
      addedWithoutPurge = 0;
      if (inQueue.size > 0) {
        startThread();
        lock.notify();
      }
      purgeCount++;
    }
  }