diff options
Diffstat (limited to 'src/corelib/kernel/qeventdispatcher_unix.cpp')
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_unix.cpp | 328 |
1 files changed, 3 insertions, 325 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index 27efac6985..26a9e9f0ca 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -72,8 +72,6 @@ QT_BEGIN_NAMESPACE -Q_CORE_EXPORT bool qt_disable_lowpriority_timers=false; - /***************************************************************************** UNIX signal handling *****************************************************************************/ @@ -309,326 +307,6 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags, return (nevents + q->activateSocketNotifiers()); } -/* - * Internal functions for manipulating timer data structures. The - * timerBitVec array is used for keeping track of timer identifiers. - */ - -QTimerInfoList::QTimerInfoList() -{ -#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC) && !defined(Q_OS_NACL) - if (!QElapsedTimer::isMonotonic()) { - // not using monotonic timers, initialize the timeChanged() machinery - previousTime = qt_gettime(); - - tms unused; - previousTicks = times(&unused); - - ticksPerSecond = sysconf(_SC_CLK_TCK); - msPerTick = 1000/ticksPerSecond; - } else { - // detected monotonic timers - previousTime.tv_sec = previousTime.tv_usec = 0; - previousTicks = 0; - ticksPerSecond = 0; - msPerTick = 0; - } -#endif - - firstTimerInfo = 0; -} - -timeval QTimerInfoList::updateCurrentTime() -{ - return (currentTime = qt_gettime()); -} - -#if ((_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC) && !defined(Q_OS_INTEGRITY)) || defined(QT_BOOTSTRAPPED) - -template <> -timeval qAbs(const timeval &t) -{ - timeval tmp = t; - if (tmp.tv_sec < 0) { - tmp.tv_sec = -tmp.tv_sec - 1; - tmp.tv_usec -= 1000000; - } - if (tmp.tv_sec == 0 && tmp.tv_usec < 0) { - tmp.tv_usec = -tmp.tv_usec; - } - return normalizedTimeval(tmp); -} - -/* - Returns true if the real time clock has changed by more than 10% - relative to the processor time since the last time this function was - called. This presumably means that the system time has been changed. - - If /a delta is nonzero, delta is set to our best guess at how much the system clock was changed. -*/ -bool QTimerInfoList::timeChanged(timeval *delta) -{ -#ifdef Q_OS_NACL - Q_UNUSED(delta) - return false; // Calling "times" crashes. -#endif - struct tms unused; - clock_t currentTicks = times(&unused); - - clock_t elapsedTicks = currentTicks - previousTicks; - timeval elapsedTime = currentTime - previousTime; - - timeval elapsedTimeTicks; - elapsedTimeTicks.tv_sec = elapsedTicks / ticksPerSecond; - elapsedTimeTicks.tv_usec = (((elapsedTicks * 1000) / ticksPerSecond) % 1000) * 1000; - - timeval dummy; - if (!delta) - delta = &dummy; - *delta = elapsedTime - elapsedTimeTicks; - - previousTicks = currentTicks; - previousTime = currentTime; - - // If tick drift is more than 10% off compared to realtime, we assume that the clock has - // been set. Of course, we have to allow for the tick granularity as well. - timeval tickGranularity; - tickGranularity.tv_sec = 0; - tickGranularity.tv_usec = msPerTick * 1000; - return elapsedTimeTicks < ((qAbs(*delta) - tickGranularity) * 10); -} - -void QTimerInfoList::repairTimersIfNeeded() -{ - if (QElapsedTimer::isMonotonic()) - return; - timeval delta; - if (timeChanged(&delta)) - timerRepair(delta); -} - -#else // !(_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(QT_BOOTSTRAPPED) - -void QTimerInfoList::repairTimersIfNeeded() -{ -} - -#endif - -/* - insert timer info into list -*/ -void QTimerInfoList::timerInsert(QTimerInfo *ti) -{ - int index = size(); - while (index--) { - register const QTimerInfo * const t = at(index); - if (!(ti->timeout < t->timeout)) - break; - } - insert(index+1, ti); -} - -/* - repair broken timer -*/ -void QTimerInfoList::timerRepair(const timeval &diff) -{ - // repair all timers - for (int i = 0; i < size(); ++i) { - register QTimerInfo *t = at(i); - t->timeout = t->timeout + diff; - } -} - -static timeval roundToMillisecond(timeval val) -{ - // always round up - // worst case scenario is that the first trigger of a 1-ms timer is 0.999 ms late - - int us = val.tv_usec % 1000; - val.tv_usec += 1000 - us; - return normalizedTimeval(val); -} - -/* - Returns the time to wait for the next timer, or null if no timers - are waiting. -*/ -bool QTimerInfoList::timerWait(timeval &tm) -{ - timeval currentTime = updateCurrentTime(); - repairTimersIfNeeded(); - - // Find first waiting timer not already active - QTimerInfo *t = 0; - for (QTimerInfoList::const_iterator it = constBegin(); it != constEnd(); ++it) { - if (!(*it)->activateRef) { - t = *it; - break; - } - } - - if (!t) - return false; - - if (currentTime < t->timeout) { - // time to wait - tm = roundToMillisecond(t->timeout - currentTime); - } else { - // no time to wait - tm.tv_sec = 0; - tm.tv_usec = 0; - } - - return true; -} - -void QTimerInfoList::registerTimer(int timerId, int interval, QObject *object) -{ - QTimerInfo *t = new QTimerInfo; - t->id = timerId; - t->interval.tv_sec = interval / 1000; - t->interval.tv_usec = (interval % 1000) * 1000; - t->timeout = updateCurrentTime() + t->interval; - t->obj = object; - t->activateRef = 0; - - timerInsert(t); -} - -bool QTimerInfoList::unregisterTimer(int timerId) -{ - // set timer inactive - for (int i = 0; i < count(); ++i) { - register QTimerInfo *t = at(i); - if (t->id == timerId) { - // found it - removeAt(i); - if (t == firstTimerInfo) - firstTimerInfo = 0; - if (t->activateRef) - *(t->activateRef) = 0; - - // release the timer id - if (!QObjectPrivate::get(t->obj)->inThreadChangeEvent) - QAbstractEventDispatcherPrivate::releaseTimerId(timerId); - - delete t; - return true; - } - } - // id not found - return false; -} - -bool QTimerInfoList::unregisterTimers(QObject *object) -{ - if (isEmpty()) - return false; - for (int i = 0; i < count(); ++i) { - register QTimerInfo *t = at(i); - if (t->obj == object) { - // object found - removeAt(i); - if (t == firstTimerInfo) - firstTimerInfo = 0; - if (t->activateRef) - *(t->activateRef) = 0; - - // release the timer id - if (!QObjectPrivate::get(t->obj)->inThreadChangeEvent) - QAbstractEventDispatcherPrivate::releaseTimerId(t->id); - - delete t; - // move back one so that we don't skip the new current item - --i; - } - } - return true; -} - -QList<QPair<int, int> > QTimerInfoList::registeredTimers(QObject *object) const -{ - QList<QPair<int, int> > list; - for (int i = 0; i < count(); ++i) { - register const QTimerInfo * const t = at(i); - if (t->obj == object) - list << QPair<int, int>(t->id, t->interval.tv_sec * 1000 + t->interval.tv_usec / 1000); - } - return list; -} - -/* - Activate pending timers, returning how many where activated. -*/ -int QTimerInfoList::activateTimers() -{ - if (qt_disable_lowpriority_timers || isEmpty()) - return 0; // nothing to do - - int n_act = 0, maxCount = 0; - firstTimerInfo = 0; - - timeval currentTime = updateCurrentTime(); - repairTimersIfNeeded(); - - - // Find out how many timer have expired - for (QTimerInfoList::const_iterator it = constBegin(); it != constEnd(); ++it) { - if (currentTime < (*it)->timeout) - break; - maxCount++; - } - - //fire the timers. - while (maxCount--) { - if (isEmpty()) - break; - - QTimerInfo *currentTimerInfo = first(); - if (currentTime < currentTimerInfo->timeout) - break; // no timer has expired - - if (!firstTimerInfo) { - firstTimerInfo = currentTimerInfo; - } else if (firstTimerInfo == currentTimerInfo) { - // avoid sending the same timer multiple times - break; - } else if (currentTimerInfo->interval < firstTimerInfo->interval - || currentTimerInfo->interval == firstTimerInfo->interval) { - firstTimerInfo = currentTimerInfo; - } - - // remove from list - removeFirst(); - - // determine next timeout time - currentTimerInfo->timeout += currentTimerInfo->interval; - if (currentTimerInfo->timeout < currentTime) - currentTimerInfo->timeout = currentTime + currentTimerInfo->interval; - - // reinsert timer - timerInsert(currentTimerInfo); - if (currentTimerInfo->interval.tv_usec > 0 || currentTimerInfo->interval.tv_sec > 0) - n_act++; - - if (!currentTimerInfo->activateRef) { - // send event, but don't allow it to recurse - currentTimerInfo->activateRef = ¤tTimerInfo; - - QTimerEvent e(currentTimerInfo->id); - QCoreApplication::sendEvent(currentTimerInfo->obj, &e); - - if (currentTimerInfo) - currentTimerInfo->activateRef = 0; - } - } - - firstTimerInfo = 0; - return n_act; -} - QEventDispatcherUNIX::QEventDispatcherUNIX(QObject *parent) : QAbstractEventDispatcher(*new QEventDispatcherUNIXPrivate, parent) { } @@ -652,7 +330,7 @@ int QEventDispatcherUNIX::select(int nfds, fd_set *readfds, fd_set *writefds, fd /*! \internal */ -void QEventDispatcherUNIX::registerTimer(int timerId, int interval, QObject *obj) +void QEventDispatcherUNIX::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *obj) { #ifndef QT_NO_DEBUG if (timerId < 1 || interval < 0 || !obj) { @@ -665,7 +343,7 @@ void QEventDispatcherUNIX::registerTimer(int timerId, int interval, QObject *obj #endif Q_D(QEventDispatcherUNIX); - d->timerList.registerTimer(timerId, interval, obj); + d->timerList.registerTimer(timerId, interval, timerType, obj); } /*! |