Beispiel #1
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();
}
Beispiel #2
0
void setDeferringTimers(bool shouldDefer)
{
    if (shouldDefer == deferringTimers)
        return;
    deferringTimers = shouldDefer;
    updateSharedTimer();
}
Beispiel #3
0
void TimerBase::setNextFireTime(double newTime)
{
    // Keep heap valid while changing the next-fire time.

    if (timersReadyToFire)
        timersReadyToFire->remove(this);

    double oldTime = m_nextFireTime;
    if (oldTime != newTime) {
        m_nextFireTime = newTime;

        bool wasFirstTimerInHeap = m_heapIndex == 0;

        if (oldTime == 0)
            heapInsert();
        else if (newTime == 0)
            heapDelete();
        else if (newTime < oldTime)
            heapDecreaseKey();
        else
            heapIncreaseKey();

        bool isFirstTimerInHeap = m_heapIndex == 0;

        if (wasFirstTimerInHeap || isFirstTimerInHeap)
            updateSharedTimer();
    }

    checkConsistency();
}
Beispiel #4
0
void ThreadTimers::fireTimersInNestedEventLoop()
{
    // Reset the reentrancy guard so the timers can fire again.
    m_firingTimers = false;

    if (m_sharedTimer) {
        m_sharedTimer->invalidate();
        m_pendingSharedTimerFireTime = 0;
    }

    updateSharedTimer();
}
// A worker thread may initialize SharedTimer after some timers are created.
// Also, SharedTimer can be replaced with 0 before all timers are destroyed.
void ThreadTimers::setSharedTimer(SharedTimer* sharedTimer)
{
    if (m_sharedTimer) {
        m_sharedTimer->setFiredFunction(0);
        m_sharedTimer->stop();
        m_pendingSharedTimerFireTime = 0;
    }

    m_sharedTimer = sharedTimer;

    if (sharedTimer) {
        m_sharedTimer->setFiredFunction(ThreadTimers::sharedTimerFired);
        updateSharedTimer();
    }
}
Beispiel #6
0
// A worker thread may initialize SharedTimer after some timers are created.
// Also, SharedTimer can be replaced with nullptr before all timers are destroyed.
void ThreadTimers::setSharedTimer(SharedTimer* sharedTimer)
{
    if (m_sharedTimer) {
        m_sharedTimer->setFiredFunction(nullptr);
        m_sharedTimer->stop();
        m_pendingSharedTimerFireTime = 0;
    }
    
    m_sharedTimer = sharedTimer;
    
    if (sharedTimer) {
        m_sharedTimer->setFiredFunction([] { threadGlobalData().threadTimers().sharedTimerFiredInternal(); });
        updateSharedTimer();
    }
}
Beispiel #7
0
void TimerBase::sharedTimerFired()
{
    // Do a re-entrancy check.
    if (timersReadyToFire)
        return;

    double fireTime = currentTime();
    Vector<TimerBase*> firingTimers;
    HashSet<const TimerBase*> firingTimersSet;

    timersReadyToFire = &firingTimersSet;

    collectFiringTimers(fireTime, firingTimers);
    fireTimers(fireTime, firingTimers);

    timersReadyToFire = 0;

    updateSharedTimer();
}
Beispiel #8
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);

        TRACE_EVENT2("blink", "ThreadTimers::sharedTimerFiredInternal",
            "src_file", timer.location().fileName(),
            "src_func", timer.location().functionName());

        // 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()
            || (isMainThread() && Platform::current()->currentThread()->scheduler()->shouldYieldForHighPriorityWork()))
            break;
    }

    m_firingTimers = false;

    updateSharedTimer();
}
void ThreadTimers::fireTimersInNestedEventLoop()
{
    // Reset the reentrancy guard so the timers can fire again.
    m_firingTimers = false;
    updateSharedTimer();
}
Beispiel #10
0
void TimerBase::fireTimersInNestedEventLoop()
{
    timersReadyToFire = 0;
    updateSharedTimer();
}