void RunLoop::TimerBase::timerFired(CFRunLoopTimerRef, void* context)
{
    TimerBase* timer = static_cast<TimerBase*>(context);

    AutodrainedPool pool;
    timer->fired();
}
예제 #2
0
void ThreadTimers::sharedTimerFiredInternal()
{
    // Do a re-entrancy check.
    if (m_firingTimers)
        return;
    m_firingTimers = true;
    m_pendingSharedTimerFireTime = 0;

    double fireTime = monotonicallyIncreasingTime();
    double timeToQuit = fireTime + maxDurationOfFiringTimers;

    while (!m_timerHeap.isEmpty() && m_timerHeap.first()->m_nextFireTime <= fireTime) {
        TimerBase* timer = m_timerHeap.first();
        timer->m_nextFireTime = 0;
        timer->m_unalignedNextFireTime = 0;
        timer->heapDeleteMin();

        double interval = timer->repeatInterval();
        timer->setNextFireTime(interval ? fireTime + interval : 0);

        // Once the timer has been fired, it may be deleted, so do nothing else with it after this point.
        timer->fired();

        // Catch the case where the timer asked timers to fire in a nested event loop, or we are over time limit.
        if (!m_firingTimers || timeToQuit < monotonicallyIncreasingTime())
            break;
    }

    m_firingTimers = false;

    updateSharedTimer();
}
예제 #3
0
파일: Timer.cpp 프로젝트: Crawping/davinci
void TimerBase::collectFiringTimers(double fireTime, Vector<TimerBase*>& firingTimers)
{
    while (!timerHeap->isEmpty() && timerHeap->first()->m_nextFireTime <= fireTime) {
        TimerBase* timer = timerHeap->first();
        firingTimers.append(timer);
        timersReadyToFire->add(timer);
        timer->m_nextFireTime = 0;
        timer->heapDeleteMin();
    }
}
예제 #4
0
void RunLoop::TimerBase::timerFired(RunLoop* runLoop, uint64_t ID)
{
    TimerMap::iterator it = runLoop->m_activeTimers.find(ID);
    ASSERT(it != runLoop->m_activeTimers.end());
    TimerBase* timer = it->second;

    // FIMXE: Support repeating timers.

    ::KillTimer(runLoop->m_runLoopMessageWindow, ID);
    timer->fired();
}
예제 #5
0
void RunLoop::TimerBase::timerFired(RunLoop* runLoop, uint64_t ID)
{
    TimerMap::iterator it = runLoop->m_activeTimers.find(ID);
    ASSERT(it != runLoop->m_activeTimers.end());
    TimerBase* timer = it->second;

    if (!timer->m_isRepeating) {
        runLoop->m_activeTimers.remove(it);
        ::KillTimer(runLoop->m_runLoopMessageWindow, ID);
    }

    timer->fired();
}
예제 #6
0
void TimerBase::callback(void* arg)
{
/*	
	TimerBase* t = (TimerBase*) arg;

	t->stop();

	bool ret = t->timeout();
	if (!ret || t->m_singleShot) {
		return;
	}

	// periodic timer. restart
	t->start(t->m_interval, false);
*/

	TimerBase* t = (TimerBase*) arg;

	SingletonTimer* master = t->m_master;
	TimerHandle* handle = t->m_handle;

	master->ref(handle);
	
	bool ret = t->timeout();
	// stop if:
	// a. this is a singleshot timer
	// b. callback returned false
	// 
	// but if it stopped and restarted the timer
	// (which will cause the handle to change), we need
	// to continue
	if (!ret || t->m_singleShot) {

		if (!t->m_handle || (t->m_handle == handle)) {
			master->deref(handle);
			t->stop();
			return;
		}
	}

	// periodic timer. reschedule	
	master->deref(handle);

	// Need to check if the handle is valid here because
	// someone could have called stop in the callback but still
	// returned true from the callback
	if (t->m_handle) {
		master->fire(t->m_handle, SingletonTimer::currentTime() + t->m_interval);
	}
}
예제 #7
0
TimerBase* TimerList::PopFront() {
	TimerBase* p = _head;
	if (_head) {
		_head = _head->GetNext();
		if (!_head)
			_tail = nullptr;
		else
			_head->SetPrev(nullptr);

		p->SetNext(nullptr);
		p->SetPrev(nullptr);
		p->SetList(nullptr);
	}
	return p;
}
예제 #8
0
void RunLoop::TimerBase::timerFired(RunLoop* runLoop, uint64_t ID)
{
    TimerMap::iterator it = runLoop->m_activeTimers.find(ID);
    if (it == runLoop->m_activeTimers.end()) {
        // The timer must have been stopped after the WM_TIMER message was posted to the message queue.
        return;
    }

    TimerBase* timer = it->value;

    if (!timer->m_isRepeating) {
        runLoop->m_activeTimers.remove(it);
        ::KillTimer(runLoop->m_runLoopMessageWindow, ID);
    }

    timer->fired();
}
예제 #9
0
    TimeoutGuard::TimeoutGuard(timer::ticks_t beginTicks, timer::ticks_t ticks,
        TimerBase& timer, Thread* pThread) :
        m_timer(timer), m_pThread(pThread)
    {
      // ----- Critical section begin -----------------------------------------
      os::core::scheduler::InterruptsCriticalSection cs;

      timer::ticks_t nowTicks = timer.getCurrentTicks();
      if ((nowTicks - beginTicks) >= ticks)
        {
          m_didTimeout = true;
        }
      else
        {
          // Normally the entry should not be there, but for just in case
          timer.remove(pThread);

          timer.insert(ticks, pThread);

          m_didTimeout = false;
        }
      // ----- Critical section end -------------------------------------------
    }
예제 #10
0
파일: Timer.cpp 프로젝트: Crawping/davinci
void TimerBase::fireTimers(double fireTime, const Vector<TimerBase*>& firingTimers)
{
    int size = firingTimers.size();
    for (int i = 0; i != size; ++i) {
        TimerBase* timer = firingTimers[i];

        // If not in the set, this timer has been deleted or re-scheduled in another timer's fired function.
        // So either we don't want to fire it at all or we will fire it next time the shared timer goes off.
        // It might even have been deleted; that's OK because we won't do anything else with the pointer.
        if (!timersReadyToFire->contains(timer))
            continue;

        // Setting the next fire time has a side effect of removing the timer from the firing timers set.
        double interval = timer->repeatInterval();
        timer->setNextFireTime(interval ? fireTime + interval : 0);

        // Once the timer has been fired, it may be deleted, so do nothing else with it after this point.
        timer->fired();

        // Catch the case where the timer asked timers to fire in a nested event loop.
        if (!timersReadyToFire)
            break;
    }
}