From 54c5a79fd0d711dd30c8813b7c5b3ce23e7429ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 1 Oct 2013 17:13:45 +0200 Subject: iOS: Handle qApp re-exec after application termination from iOS' side MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the user for some reason spins a new QApplication event loop after an initial one has been exited as a result of the application being terminated by iOS we need to prevent further event loops from starting. Change-Id: Ief8a69cebacebd5be63a1aca87a2a1babc809879 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/qioseventdispatcher.mm | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 3de7c996f5..24f6210f97 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -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,8 +391,7 @@ 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 @@ -421,6 +425,13 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo if (!rootLevelRunLoopIntegration()) return QEventDispatcherCoreFoundation::processEvents(flags); + if (applicationAboutToTerminate) { + qEventDispatcherDebug() << "Detected QEventLoop exec after application termination"; + // Re-issue exit, and return immediately + qApp->exit(kApplicationWillTerminateExitCode); + return false; + } + QCoreApplicationPrivate *qApplication = static_cast(QObjectPrivate::get(qApp)); if (!m_processEventCallsAfterAppExec && qApplication->in_exec) { Q_ASSERT(flags & QEventLoop::EventLoopExec); -- cgit v1.2.3