diff options
Diffstat (limited to 'src/corelib/kernel/qeventdispatcher_unix.cpp')
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_unix.cpp | 140 |
1 files changed, 36 insertions, 104 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index 9deb78f..2943c6d 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -59,10 +59,6 @@ # include <sys/times.h> #endif -#ifdef Q_OS_MAC -#include <mach/mach_time.h> -#endif - QT_BEGIN_NAMESPACE Q_CORE_EXPORT bool qt_disable_lowpriority_timers=false; @@ -263,18 +259,10 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags, QTimerInfoList::QTimerInfoList() { -#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC) - useMonotonicTimers = false; - -# if (_POSIX_MONOTONIC_CLOCK == 0) - // detect if the system support monotonic timers - long x = sysconf(_SC_MONOTONIC_CLOCK); - useMonotonicTimers = x != -1; -# endif - - getTime(currentTime); + currentTime = qt_gettime(); - if (!useMonotonicTimers) { +#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC) + if (!qt_gettime_is_monotonic()) { // not using monotonic timers, initialize the timeChanged() machinery previousTime = currentTime; @@ -290,12 +278,6 @@ QTimerInfoList::QTimerInfoList() ticksPerSecond = 0; msPerTick = 0; } -#else -# if defined(Q_OS_MAC) - useMonotonicTimers = true; -# endif - // using monotonic timers unconditionally - getTime(currentTime); #endif firstTimerInfo = currentTimerInfo = 0; @@ -303,11 +285,24 @@ QTimerInfoList::QTimerInfoList() timeval QTimerInfoList::updateCurrentTime() { - getTime(currentTime); - return currentTime; + return (currentTime = qt_gettime()); } -#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) || defined(QT_BOOTSTRAPPED) +#if ((_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC)) || 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% @@ -321,69 +316,32 @@ bool QTimerInfoList::timeChanged(timeval *delta) tms unused; clock_t currentTicks = times(&unused); - int elapsedTicks = currentTicks - previousTicks; + clock_t elapsedTicks = currentTicks - previousTicks; timeval elapsedTime = currentTime - previousTime; - int elapsedMsecTicks = (elapsedTicks * 1000) / ticksPerSecond; - int deltaMsecs = (elapsedTime.tv_sec * 1000 + elapsedTime.tv_usec / 1000) - - elapsedMsecTicks; - if (delta) { - delta->tv_sec = deltaMsecs / 1000; - delta->tv_usec = (deltaMsecs % 1000) * 1000; - } + 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. - - return (qAbs(deltaMsecs) - msPerTick) * 10 > elapsedMsecTicks; -} - -void QTimerInfoList::getTime(timeval &t) -{ -#if defined(Q_OS_MAC) - { - static mach_timebase_info_data_t info = {0,0}; - if (info.denom == 0) - mach_timebase_info(&info); - - uint64_t cpu_time = mach_absolute_time(); - uint64_t nsecs = cpu_time * (info.numer / info.denom); - t.tv_sec = nsecs * 1e-9; - t.tv_usec = nsecs * 1e-3 - (t.tv_sec * 1e6); - return; - } -#elif !defined(QT_NO_CLOCK_MONOTONIC) && !defined(QT_BOOTSTRAPPED) - if (useMonotonicTimers) { - timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - t.tv_sec = ts.tv_sec; - t.tv_usec = ts.tv_nsec / 1000; - return; - } -#endif - - gettimeofday(&t, 0); - // NTP-related fix - while (t.tv_usec >= 1000000l) { - t.tv_usec -= 1000000l; - ++t.tv_sec; - } - while (t.tv_usec < 0l) { - if (t.tv_sec > 0l) { - t.tv_usec += 1000000l; - --t.tv_sec; - } else { - t.tv_usec = 0l; - break; - } - } + timeval tickGranularity; + tickGranularity.tv_sec = 0; + tickGranularity.tv_usec = msPerTick * 1000; + return elapsedTimeTicks < ((qAbs(*delta) - tickGranularity) * 10); } void QTimerInfoList::repairTimersIfNeeded() { - if (useMonotonicTimers) + if (qt_gettime_is_monotonic()) return; timeval delta; if (timeChanged(&delta)) @@ -392,14 +350,6 @@ void QTimerInfoList::repairTimersIfNeeded() #else // !(_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(QT_BOOTSTRAPPED) -void QTimerInfoList::getTime(timeval &t) -{ - timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - t.tv_sec = ts.tv_sec; - t.tv_usec = ts.tv_nsec / 1000; -} - void QTimerInfoList::repairTimersIfNeeded() { } @@ -428,7 +378,7 @@ 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; + t->timeout = t->timeout + diff; } } @@ -625,25 +575,7 @@ QEventDispatcherUNIX::~QEventDispatcherUNIX() int QEventDispatcherUNIX::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, timeval *timeout) { - Q_D(QEventDispatcherUNIX); - if (timeout) { - // handle the case where select returns with a timeout, too - // soon. - timeval tvStart = d->timerList.currentTime; - timeval tvCurrent = tvStart; - timeval originalTimeout = *timeout; - - int nsel; - do { - timeval tvRest = originalTimeout + tvStart - tvCurrent; - nsel = ::select(nfds, readfds, writefds, exceptfds, &tvRest); - d->timerList.getTime(tvCurrent); - } while (nsel == 0 && (tvCurrent - tvStart) < originalTimeout); - - return nsel; - } - - return ::select(nfds, readfds, writefds, exceptfds, timeout); + return ::qt_safe_select(nfds, readfds, writefds, exceptfds, timeout); } /*! |