diff options
author | Morten Johan Sørvig <morten.sorvig@qt.io> | 2018-07-04 00:20:37 +0200 |
---|---|---|
committer | Morten Johan Sørvig <morten.sorvig@qt.io> | 2018-08-09 07:24:15 +0000 |
commit | a09c8b0ee6ddd13251ee1335ede73fd66e007a35 (patch) | |
tree | 9c7cb2af31892edc16b696c86bde948152b8cb2f /src/corelib/kernel/qeventdispatcher_cf.mm | |
parent | 489ae6db3c1d4c78b60f67d1c64e6bdb820560eb (diff) |
Make QEventDispatcherCoreFoundaton work on secondary threads
We were using CFRunLoopGetMain() everywhere. Get the
correct run loop using CFRunLoopGetCurrent() during
initialization, and store it.
Event dispatcher initialization must now be delayed
until after the constructor has run, since event dispatchers
may be created on the main thread and then moved to
the target thread. Initialize on first call to processEvents()
where the current thread will be the correct thread.
Use the stored m_runLoop instead of CFRunLoopGetMain().
This is required for wakeUp() and interrupt() which
may be called from another thread.
Change-Id: I6fffcfd4394899c4a12f241c42781979aaf99d5e
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src/corelib/kernel/qeventdispatcher_cf.mm')
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_cf.mm | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_cf.mm b/src/corelib/kernel/qeventdispatcher_cf.mm index 73eeaba03f..8881305b18 100644 --- a/src/corelib/kernel/qeventdispatcher_cf.mm +++ b/src/corelib/kernel/qeventdispatcher_cf.mm @@ -209,8 +209,16 @@ QEventDispatcherCoreFoundation::QEventDispatcherCoreFoundation(QObject *parent) , m_blockedRunLoopTimer(0) , m_overdueTimerScheduled(false) { - m_cfSocketNotifier.setHostEventDispatcher(this); +} + +void QEventDispatcherCoreFoundation::startingUp() +{ + // The following code must run on the event dispatcher thread, so that + // CFRunLoopGetCurrent() returns the correct run loop. + Q_ASSERT(QThread::currentThread() == thread()); + m_runLoop = QCFType<CFRunLoopRef>::constructFromGet(CFRunLoopGetCurrent()); + m_cfSocketNotifier.setHostEventDispatcher(this); m_postedEventsRunLoopSource.addToMode(kCFRunLoopCommonModes); m_runLoopActivityObserver.addToMode(kCFRunLoopCommonModes); } @@ -252,6 +260,7 @@ QEventLoop *QEventDispatcherCoreFoundation::currentEventLoop() const bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlags flags) { QT_APPLE_SCOPED_LOG_ACTIVITY(lcEventDispatcher().isDebugEnabled(), "processEvents"); + bool eventsProcessed = false; if (flags & (QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers)) @@ -413,7 +422,8 @@ bool QEventDispatcherCoreFoundation::processPostedEvents() m_processEvents.processedPostedEvents = true; - qCDebug(lcEventDispatcher) << "Sending posted events for" << m_processEvents.flags; + qCDebug(lcEventDispatcher) << "Sending posted events for" + << QEventLoop::ProcessEventsFlags(m_processEvents.flags.load()); QCoreApplication::sendPostedEvents(); return true; @@ -496,7 +506,7 @@ bool QEventDispatcherCoreFoundation::hasPendingEvents() // 'maybeHasPendingEvents' in our case. extern uint qGlobalPostedEventsCount(); - return qGlobalPostedEventsCount() || !CFRunLoopIsWaiting(CFRunLoopGetMain()); + return qGlobalPostedEventsCount() || !CFRunLoopIsWaiting(m_runLoop); } void QEventDispatcherCoreFoundation::wakeUp() @@ -516,7 +526,8 @@ void QEventDispatcherCoreFoundation::wakeUp() } m_postedEventsRunLoopSource.signal(); - CFRunLoopWakeUp(CFRunLoopGetMain()); + if (m_runLoop) + CFRunLoopWakeUp(m_runLoop); qCDebug(lcEventDispatcher) << "Signaled posted event run-loop source"; } @@ -525,7 +536,7 @@ void QEventDispatcherCoreFoundation::interrupt() { qCDebug(lcEventDispatcher) << "Marking current processEvent as interrupted"; m_processEvents.wasInterrupted = true; - CFRunLoopStop(CFRunLoopGetMain()); + CFRunLoopStop(m_runLoop); } void QEventDispatcherCoreFoundation::flush() @@ -620,7 +631,7 @@ void QEventDispatcherCoreFoundation::updateTimers() processTimers(timer); }); - CFRunLoopAddTimer(CFRunLoopGetMain(), m_runLoopTimer, kCFRunLoopCommonModes); + CFRunLoopAddTimer(m_runLoop, m_runLoopTimer, kCFRunLoopCommonModes); qCDebug(lcEventDispatcherTimers) << "Created new CFRunLoopTimer" << m_runLoopTimer; } else { |