void RunLoop::TimerBase::timerFired(CFRunLoopTimerRef, void* context) { TimerBase* timer = static_cast<TimerBase*>(context); AutodrainedPool pool; timer->fired(); }
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(); }
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(); } }
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(); }
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(); }
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); } }
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; }
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(); }
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 ------------------------------------------- }
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; } }