diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-10-11 16:12:21 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-10-11 16:12:35 +0200 |
commit | d0eb444a49f6064ecb896f62276e060cd8a4b1e8 (patch) | |
tree | 34d8dd637baf665225ada73e76604531cd2c75e5 /src/plugins/platforms/ios | |
parent | da0cb32b8ee7cc4a991a59420a411898e63a660e (diff) | |
parent | 894f86709080fe8d20875b402adce679963c49c2 (diff) |
Merge remote-tracking branch 'origin/stable' into dev
Change-Id: Ib8cfeee7d9ca15e8ad520e428b72c200827a8628
Diffstat (limited to 'src/plugins/platforms/ios')
-rw-r--r-- | src/plugins/platforms/ios/qioseventdispatcher.h | 6 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qioseventdispatcher.mm | 79 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qiosglobal.mm | 2 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qiosintegration.mm | 1 |
4 files changed, 46 insertions, 42 deletions
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index 83267e80ea..f2272ecd68 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -58,11 +58,11 @@ public: void handleRunLoopExit(CFRunLoopActivity activity); - void checkIfApplicationShouldQuit(); - void interruptQApplicationExec(); + void checkIfEventLoopShouldExit(); + void interruptEventLoopExec(); private: - uint m_processEventCallsAfterAppExec; + uint m_processEventCallsAfterExec; RunLoopObserver<QIOSEventDispatcher> m_runLoopExitObserver; }; diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 3de7c996f5..f7df792362 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -244,7 +244,7 @@ enum SetJumpResult { kJumpPointSetSuccessfully = 0, kJumpedFromEventDispatcherProcessEvents, - kJumpedFromQApplicationExecInterrupt, + kJumpedFromEventLoopExecInterrupt, kJumpedFromUserMainTrampoline, }; @@ -365,6 +365,11 @@ static bool rootLevelRunLoopIntegration() } } +// We treat applicationWillTerminate as SIGTERM, even if it can't be ignored, +// and follow the bash convention of encoding the signal number in the upper +// four bits of the exit code (exit(3) will only pass on the lower 8 bits). +static const char kApplicationWillTerminateExitCode = SIGTERM | 0x80; + + (void) applicationWillTerminate { if (!isQtApplication()) @@ -386,14 +391,13 @@ static bool rootLevelRunLoopIntegration() switch (setjmp(applicationWillTerminateJumpPoint)) { case kJumpPointSetSuccessfully: qEventDispatcherDebug() << "Exiting qApp with SIGTERM exit code"; qIndent(); - // We treat applicationWillTerminate as SIGTERM, even if it can't be ignored - qApp->exit(128 + SIGTERM); + qApp->exit(kApplicationWillTerminateExitCode); // The runloop will not exit when the application is about to terminate, // so we'll never see the exit activity and have a chance to return from - // QApplication::exec(). We initiate the return manually as a workaround. - qEventDispatcherDebug() << "Manually triggering return from QApp exec"; - static_cast<QIOSEventDispatcher *>(qApp->eventDispatcher())->interruptQApplicationExec(); + // QEventLoop::exec(). We initiate the return manually as a workaround. + qEventDispatcherDebug() << "Manually triggering return from event loop exec"; + static_cast<QIOSEventDispatcher *>(qApp->eventDispatcher())->interruptEventLoopExec(); break; case kJumpedFromUserMainTrampoline: // The user's main has returned, so we're ready to let iOS terminate the application @@ -411,7 +415,7 @@ QT_USE_NAMESPACE QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) : QEventDispatcherCoreFoundation(parent) - , m_processEventCallsAfterAppExec(0) + , m_processEventCallsAfterExec(0) , m_runLoopExitObserver(this, &QIOSEventDispatcher::handleRunLoopExit, kCFRunLoopExit) { } @@ -421,27 +425,29 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo if (!rootLevelRunLoopIntegration()) return QEventDispatcherCoreFoundation::processEvents(flags); - QCoreApplicationPrivate *qApplication = static_cast<QCoreApplicationPrivate *>(QObjectPrivate::get(qApp)); - if (!m_processEventCallsAfterAppExec && qApplication->in_exec) { - Q_ASSERT(flags & QEventLoop::EventLoopExec); + if (applicationAboutToTerminate) { + qEventDispatcherDebug() << "Detected QEventLoop exec after application termination"; + // Re-issue exit, and return immediately + qApp->exit(kApplicationWillTerminateExitCode); + return false; + } - // We know that app->in_exec is set just before executing the main event loop, - // so the first processEvents call after that will be the main event loop. - ++m_processEventCallsAfterAppExec; + if (!m_processEventCallsAfterExec && (flags & QEventLoop::EventLoopExec)) { + ++m_processEventCallsAfterExec; - // We set a new jump point here that we can return to when the Qt application - // is asked to exit, so that we can return from QCoreApplication::exec(). + // We set a new jump point here that we can return to when the event loop + // is asked to exit, so that we can return from QEventLoop::exec(). switch (setjmp(processEventExitJumpPoint)) { case kJumpPointSetSuccessfully: - qEventDispatcherDebug() << "QApplication exec detected, jumping back to native runloop"; + qEventDispatcherDebug() << "QEventLoop exec detected, jumping back to native runloop"; longjmp(processEventEnterJumpPoint, kJumpedFromEventDispatcherProcessEvents); break; - case kJumpedFromQApplicationExecInterrupt: - // QCoreApplication has quit (either by the hand of the user, or the iOS termination + case kJumpedFromEventLoopExecInterrupt: + // The event loop has exited (either by the hand of the user, or the iOS termination // signal), and we jumped back though processEventExitJumpPoint. We return from processEvents, - // which will emit aboutToQuit and then return to the user's main, which can do - // whatever it wants, including calling exec() on the application again. - qEventDispatcherDebug() << "kJumpedFromQApplicationExecInterrupt, returning with eventsProcessed = true"; + // which will emit aboutToQuit if it's QApplication's event loop, and then return to the user's + // main, which can do whatever it wants, including calling exec() on the application again. + qEventDispatcherDebug() << "kJumpedFromEventLoopExecInterrupt, returning with eventsProcessed = true"; return true; default: qFatal("Unexpected jump result in event loop integration"); @@ -450,19 +456,19 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo Q_UNREACHABLE(); } - if (m_processEventCallsAfterAppExec) - ++m_processEventCallsAfterAppExec; + if (m_processEventCallsAfterExec) + ++m_processEventCallsAfterExec; bool processedEvents = QEventDispatcherCoreFoundation::processEvents(flags); - if (m_processEventCallsAfterAppExec) - --m_processEventCallsAfterAppExec; + if (m_processEventCallsAfterExec) + --m_processEventCallsAfterExec; // If we're running with nested event loops and the application is quit, // then the forwarded interrupt call will happen while our processEvent // counter is still 2, and we won't detect that we're about to fall down // to the root iOS run-loop. We do an extra check here to catch that case. - checkIfApplicationShouldQuit(); + checkIfEventLoopShouldExit(); return processedEvents; } @@ -477,12 +483,12 @@ void QIOSEventDispatcher::interrupt() // If an interrupt happens as part of a non-nested event loop, that is, // by processing an event or timer in the root iOS run-loop, we'll be // able to detect it here. - checkIfApplicationShouldQuit(); + checkIfEventLoopShouldExit(); } -void QIOSEventDispatcher::checkIfApplicationShouldQuit() +void QIOSEventDispatcher::checkIfEventLoopShouldExit() { - if (QThreadData::current()->quitNow && m_processEventCallsAfterAppExec == 1) { + if (m_processEventCallsAfterExec == 1) { qEventDispatcherDebug() << "Hit root runloop level, watching for runloop exit"; m_runLoopExitObserver.addToMode(kCFRunLoopCommonModes); } @@ -494,26 +500,25 @@ void QIOSEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity) m_runLoopExitObserver.removeFromMode(kCFRunLoopCommonModes); - interruptQApplicationExec(); + interruptEventLoopExec(); } -void QIOSEventDispatcher::interruptQApplicationExec() +void QIOSEventDispatcher::interruptEventLoopExec() { - Q_ASSERT(QThreadData::current()->quitNow); - Q_ASSERT(m_processEventCallsAfterAppExec == 1); + Q_ASSERT(m_processEventCallsAfterExec == 1); - --m_processEventCallsAfterAppExec; + --m_processEventCallsAfterExec; // We re-set applicationProcessEventsReturnPoint here so that future - // calls to QApplication::exec() will end up back here after entering + // calls to QEventLoop::exec() will end up back here after entering // processEvents, instead of back in didFinishLaunchingWithOptions. switch (setjmp(processEventEnterJumpPoint)) { case kJumpPointSetSuccessfully: qEventDispatcherDebug() << "Jumping back to processEvents"; - longjmp(processEventExitJumpPoint, kJumpedFromQApplicationExecInterrupt); + longjmp(processEventExitJumpPoint, kJumpedFromEventLoopExecInterrupt); break; case kJumpedFromEventDispatcherProcessEvents: - // QCoreApplication was re-executed + // QEventLoop was re-executed qEventDispatcherDebug() << "kJumpedFromEventDispatcherProcessEvents"; break; default: diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index 537d63ae77..9b8462a6cc 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE bool isQtApplication() { - // Returns true if the plugin is in full control of the whole application. This means + // Returns \c true if the plugin is in full control of the whole application. This means // that we control the application delegate and the top view controller, and can take // actions that impacts all parts of the application. The opposite means that we are // embedded inside a native iOS application, and should be more focused on playing along diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index b9bb82a326..dcad6121be 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -126,7 +126,6 @@ QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *wind // Used when the QWindow's surface type is set by the client to QSurface::OpenGLSurface QPlatformOpenGLContext *QIOSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { - Q_UNUSED(context); return new QIOSContext(context); } |