summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qeventdispatcher_cf.mm26
-rw-r--r--src/corelib/kernel/qeventdispatcher_glib.cpp13
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix.cpp11
-rw-r--r--src/corelib/kernel/qeventdispatcher_wasm.cpp18
-rw-r--r--src/corelib/kernel/qtimerinfo_unix.cpp15
-rw-r--r--src/corelib/kernel/qtimerinfo_unix_p.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm13
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)