diff options
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_cf.mm | 26 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_glib.cpp | 13 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_unix.cpp | 11 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_wasm.cpp | 18 | ||||
-rw-r--r-- | src/corelib/kernel/qtimerinfo_unix.cpp | 15 | ||||
-rw-r--r-- | src/corelib/kernel/qtimerinfo_unix_p.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 13 |
7 files changed, 56 insertions, 42 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_cf.mm b/src/corelib/kernel/qeventdispatcher_cf.mm index b93a38c8a1..16c5464f10 100644 --- a/src/corelib/kernel/qeventdispatcher_cf.mm +++ b/src/corelib/kernel/qeventdispatcher_cf.mm @@ -555,23 +555,25 @@ int QEventDispatcherCoreFoundation::remainingTime(int timerId) return m_timerInfoList.timerRemainingTime(timerId); } -static double timespecToSeconds(const timespec &spec) -{ - static double nanosecondsPerSecond = 1.0 * 1000 * 1000 * 1000; - return spec.tv_sec + (spec.tv_nsec / nanosecondsPerSecond); -} - void QEventDispatcherCoreFoundation::updateTimers() { if (m_timerInfoList.size() > 0) { // We have Qt timers registered, so create or reschedule CF timer to match - timespec tv = { -1, -1 }; - CFAbsoluteTime timeToFire = m_timerInfoList.timerWait(tv) ? + using namespace std::chrono_literals; + using DoubleSeconds = std::chrono::duration<double, std::ratio<1>>; + + CFAbsoluteTime timeToFire; + auto opt = m_timerInfoList.timerWait(); + DoubleSeconds secs{}; + if (opt) { // We have a timer ready to fire right now, or some time in the future - CFAbsoluteTimeGetCurrent() + timespecToSeconds(tv) + secs = DoubleSeconds{*opt}; + timeToFire = CFAbsoluteTimeGetCurrent() + secs.count(); + } else { // We have timers, but they are all currently blocked by callbacks - : kCFTimeIntervalDistantFuture; + timeToFire = kCFTimeIntervalDistantFuture; + } if (!m_runLoopTimer) { m_runLoopTimer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, @@ -587,9 +589,9 @@ void QEventDispatcherCoreFoundation::updateTimers() qCDebug(lcEventDispatcherTimers) << "Re-scheduled CFRunLoopTimer" << m_runLoopTimer; } - m_overdueTimerScheduled = !timespecToSeconds(tv); + m_overdueTimerScheduled = secs > 0s; - qCDebug(lcEventDispatcherTimers) << "Next timeout in" << tv << "seconds"; + qCDebug(lcEventDispatcherTimers) << "Next timeout in" << secs; } else { // No Qt timers are registered, so make sure we're not running any CF timers diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp index 1e2777b08b..19a52d27bc 100644 --- a/src/corelib/kernel/qeventdispatcher_glib.cpp +++ b/src/corelib/kernel/qeventdispatcher_glib.cpp @@ -4,6 +4,7 @@ #include "qeventdispatcher_glib_p.h" #include "qeventdispatcher_unix_p.h" +#include <private/qnumeric_p.h> #include <private/qthread_p.h> #include "qcoreapplication.h" @@ -14,6 +15,8 @@ #include <glib.h> +using namespace std::chrono_literals; + QT_BEGIN_NAMESPACE struct GPollFDWithQSocketNotifier @@ -95,11 +98,13 @@ struct GTimerSource static gboolean timerSourcePrepareHelper(GTimerSource *src, gint *timeout) { - timespec tv = { 0l, 0l }; - if (!(src->processEventsFlags & QEventLoop::X11ExcludeTimers) && src->timerList.timerWait(tv)) - *timeout = (tv.tv_sec * 1000) + ((tv.tv_nsec + 999999) / 1000 / 1000); - else + if (src->processEventsFlags & QEventLoop::X11ExcludeTimers) { *timeout = -1; + return true; + } + + auto msecs = src->timerList.timerWait().value_or(-1ms); + *timeout = qt_saturate<gint>(msecs.count()); return (*timeout == 0); } diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index 12603d77f0..007b396db4 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -27,6 +27,8 @@ # include <pipeDrv.h> #endif +using namespace std::chrono_literals; + QT_BEGIN_NAMESPACE static const char *socketType(QSocketNotifier::Type type) @@ -427,8 +429,15 @@ bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags) timespec *tm = nullptr; timespec wait_tm = { 0, 0 }; - if (!canWait || (include_timers && d->timerList.timerWait(wait_tm))) + if (!canWait) { tm = &wait_tm; + } else if (include_timers) { + std::optional<std::chrono::milliseconds> msecs = d->timerList.timerWait(); + if (msecs) { + wait_tm = durationToTimespec(*msecs); + tm = &wait_tm; + } + } d->pollfds.clear(); d->pollfds.reserve(1 + (include_notifiers ? d->socketNotifiers.size() : 0)); diff --git a/src/corelib/kernel/qeventdispatcher_wasm.cpp b/src/corelib/kernel/qeventdispatcher_wasm.cpp index 6674d13c4b..00f3f97ee8 100644 --- a/src/corelib/kernel/qeventdispatcher_wasm.cpp +++ b/src/corelib/kernel/qeventdispatcher_wasm.cpp @@ -583,19 +583,15 @@ void QEventDispatcherWasm::updateNativeTimer() // access to m_timerInfo), and then call native API to set the new // wakeup time on the main thread. - using namespace std::chrono; - auto timespecToMsec = [](timespec ts) -> milliseconds { - return duration_cast<milliseconds>(seconds{ts.tv_sec} + nanoseconds{ts.tv_nsec}); - }; - timespec toWait; - bool hasTimer = m_timerInfo->timerWait(toWait); - const milliseconds toWaitDuration = timespecToMsec(toWait); - const time_point newTargetTimePoint = m_timerInfo->currentTime + toWaitDuration; - auto newTargetTime = duration_cast<milliseconds>(newTargetTimePoint.time_since_epoch()); - auto maintainNativeTimer = [this, hasTimer, toWaitDuration, newTargetTime]() { + const std::optional<std::chrono::milliseconds> wait = m_timerInfo->timerWait(); + const auto toWaitDuration = wait.value_or(0ms); + const auto newTargetTimePoint = m_timerInfo->currentTime + toWaitDuration; + auto epochNsecs = newTargetTimePoint.time_since_epoch(); + auto newTargetTime = std::chrono::duration_cast<std::chrono::milliseconds>(epochNsecs); + auto maintainNativeTimer = [this, wait, toWaitDuration, newTargetTime]() { Q_ASSERT(emscripten_is_main_runtime_thread()); - if (!hasTimer) { + if (!wait) { if (m_timerId > 0) { emscripten_clear_timeout(m_timerId); m_timerId = 0; diff --git a/src/corelib/kernel/qtimerinfo_unix.cpp b/src/corelib/kernel/qtimerinfo_unix.cpp index c697bf03e5..484ca89945 100644 --- a/src/corelib/kernel/qtimerinfo_unix.cpp +++ b/src/corelib/kernel/qtimerinfo_unix.cpp @@ -230,7 +230,11 @@ static void calculateNextTimeout(QTimerInfo *t, steady_clock::time_point now) } } -bool QTimerInfoList::timerWait(timespec &tm) +/* + Returns the time to wait for the first timer that has not been activated yet, + otherwise returns std::nullopt. + */ +std::optional<std::chrono::milliseconds> QTimerInfoList::timerWait() { steady_clock::time_point now = updateCurrentTime(); @@ -238,15 +242,12 @@ bool QTimerInfoList::timerWait(timespec &tm) // Find first waiting timer not already active auto it = std::find_if(timers.cbegin(), timers.cend(), isWaiting); if (it == timers.cend()) - return false; + return std::nullopt; nanoseconds timeToWait = (*it)->timeout - now; if (timeToWait > 0ns) - tm = durationToTimespec(roundToMillisecond(timeToWait)); - else - tm = {0, 0}; - - return true; + return roundToMillisecond(timeToWait); + return 0ms; } /* diff --git a/src/corelib/kernel/qtimerinfo_unix_p.h b/src/corelib/kernel/qtimerinfo_unix_p.h index 98578bdc0e..d8f41955f8 100644 --- a/src/corelib/kernel/qtimerinfo_unix_p.h +++ b/src/corelib/kernel/qtimerinfo_unix_p.h @@ -46,7 +46,7 @@ public: std::chrono::steady_clock::time_point currentTime; - bool timerWait(timespec &); + std::optional<std::chrono::milliseconds> timerWait(); void timerInsert(QTimerInfo *); qint64 timerRemainingTime(int timerId); diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 41caac281b..a594259d99 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -115,6 +115,7 @@ void QCocoaEventDispatcherPrivate::maybeStartCFRunLoopTimer() return; } + using DoubleSeconds = std::chrono::duration<double, std::ratio<1>>; if (!runLoopTimerRef) { // start the CFRunLoopTimer CFAbsoluteTime ttf = CFAbsoluteTimeGetCurrent(); @@ -122,10 +123,10 @@ void QCocoaEventDispatcherPrivate::maybeStartCFRunLoopTimer() CFTimeInterval oneyear = CFTimeInterval(3600. * 24. * 365.); // Q: when should the CFRunLoopTimer fire for the first time? - struct timespec tv; - if (timerInfoList.timerWait(tv)) { + if (auto opt = timerInfoList.timerWait()) { // A: when we have timers to fire, of course - interval = qMax(tv.tv_sec + tv.tv_nsec / 1000000000., 0.0000001); + DoubleSeconds secs{*opt}; + interval = qMax(secs.count(), 0.0000001); } else { // this shouldn't really happen, but in case it does, set the timer to fire a some point in the distant future interval = oneyear; @@ -145,10 +146,10 @@ void QCocoaEventDispatcherPrivate::maybeStartCFRunLoopTimer() CFTimeInterval interval; // Q: when should the timer first next? - struct timespec tv; - if (timerInfoList.timerWait(tv)) { + if (auto opt = timerInfoList.timerWait()) { // A: when we have timers to fire, of course - interval = qMax(tv.tv_sec + tv.tv_nsec / 1000000000., 0.0000001); + DoubleSeconds secs{*opt}; + interval = qMax(secs.count(), 0.0000001); } else { // no timers can fire, but we cannot stop the CFRunLoopTimer, set the timer to fire at some // point in the distant future (the timer interval is one year) |