void Application::Private::checkTimers() { List<Timer*> expiredTimerList; { ContextMutexLocker cml(m_runningTimerListMutex); if (m_runningTimerList.empty()) { return; } Timer *const firstExpiredTimer = m_runningTimerList.front(); { // We control here the case in which the timer that was going to expire // (the head of the queue) was removed before actually expiring. With this // check we won't fire an incorrect timer when it had already time remaining. const iint32 msDelta = firstExpiredTimer->d->m_remaining - m_sleepTime; if (msDelta) { std::vector<Timer*>::iterator it; for (it = m_runningTimerList.begin(); it != m_runningTimerList.end(); ++it) { Timer *const currTimer = *it; currTimer->d->m_remaining -= m_sleepTime; } m_sleepTime = std::min(msDelta, m_defaultSleepTime); return; } } m_nextTimeout = firstExpiredTimer->d->m_remaining; std::vector<Timer*>::iterator it = m_runningTimerList.begin(); while (it != m_runningTimerList.end()) { Timer *const currTimer = *it; if (currTimer->d->m_remaining == firstExpiredTimer->d->m_remaining) { if (currTimer->d->m_timeoutType == Timer::SingleShot) { currTimer->d->m_state = Timer::Stopped; it = m_runningTimerList.erase(it); } else { currTimer->d->m_remaining = currTimer->d->m_interval; ++it; } expiredTimerList.push_back(currTimer); } else { break; } } if (!m_runningTimerList.empty()) { while (it != m_runningTimerList.end()) { Timer *const currTimer = *it; currTimer->d->m_remaining -= m_nextTimeout; ++it; } std::sort(m_runningTimerList.begin(), m_runningTimerList.end(), PrivateImpl::timerSort); Timer *const nextTimer = m_runningTimerList.front(); m_sleepTime = nextTimer->d->m_remaining; } else { m_sleepTime = -1; } } List<Timer*>::iterator it; for (it = expiredTimerList.begin(); it != expiredTimerList.end(); ++it) { Timer *const currTimer = *it; EventDispatcher *eventDispatcher = new EventDispatcher(q); Event *event = new Event(currTimer, Event::Timeout); eventDispatcher->postEvent(event); eventDispatcher->exec(); } }