Commit dfd6fc7b authored by Tor Arne Vestbø's avatar Tor Arne Vestbø
Browse files

iOS: Only use root level native runloop if at first level of processEvents


We used to support calling QEventLoop::exec() from within a processEvent
recursion and still jump down to the root native runloop, but this does
not work as intended due to how QEventDispatcherCoreFoundation uses
flags in its ProcessEventsState for e.g. deferred wake up or timer
updates. The logic in QEventDispatcherCoreFoundation assumes that
the next recursion to processEvents will be handled by itself, so
that it can interpret the flags in ProcessEventsState. The iOS
event dispatcher subclass, QIOSEventDispatcher, does neither of
these things, and should only be used from a 'clean' state.

Change-Id: I44fa156feecc45772806002465c35bef0797ead2
Reviewed-by: default avatarRichard Moe Gustavsen <richard.gustavsen@theqtcompany.com>
Showing with 9 additions and 13 deletions
......@@ -52,7 +52,7 @@ public:
void interruptEventLoopExec();
private:
uint m_processEventCallsAfterExec;
uint m_processEventLevel;
RunLoopObserver<QIOSEventDispatcher> m_runLoopExitObserver;
};
......
......@@ -422,7 +422,7 @@ QT_USE_NAMESPACE
QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent)
: QEventDispatcherCoreFoundation(parent)
, m_processEventCallsAfterExec(0)
, m_processEventLevel(0)
, m_runLoopExitObserver(this, &QIOSEventDispatcher::handleRunLoopExit, kCFRunLoopExit)
{
}
......@@ -439,8 +439,8 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo
return false;
}
if (!m_processEventCallsAfterExec && (flags & QEventLoop::EventLoopExec)) {
++m_processEventCallsAfterExec;
if (!m_processEventLevel && (flags & QEventLoop::EventLoopExec)) {
++m_processEventLevel;
m_runLoopExitObserver.addToMode(kCFRunLoopCommonModes);
......@@ -465,13 +465,9 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo
Q_UNREACHABLE();
}
if (m_processEventCallsAfterExec)
++m_processEventCallsAfterExec;
++m_processEventLevel;
bool processedEvents = QEventDispatcherCoreFoundation::processEvents(flags);
if (m_processEventCallsAfterExec)
--m_processEventCallsAfterExec;
--m_processEventLevel;
return processedEvents;
}
......@@ -481,7 +477,7 @@ void QIOSEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity)
Q_UNUSED(activity);
Q_ASSERT(activity == kCFRunLoopExit);
if (m_processEventCallsAfterExec == 1 && !QThreadData::current()->eventLoops.top()->isRunning()) {
if (m_processEventLevel == 1 && !QThreadData::current()->eventLoops.top()->isRunning()) {
qEventDispatcherDebug() << "Root runloop level exited";
interruptEventLoopExec();
}
......@@ -489,9 +485,9 @@ void QIOSEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity)
void QIOSEventDispatcher::interruptEventLoopExec()
{
Q_ASSERT(m_processEventCallsAfterExec == 1);
Q_ASSERT(m_processEventLevel == 1);
--m_processEventCallsAfterExec;
--m_processEventLevel;
m_runLoopExitObserver.removeFromMode(kCFRunLoopCommonModes);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment