summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/ios
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-10-11 16:12:21 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-10-11 16:12:35 +0200
commitd0eb444a49f6064ecb896f62276e060cd8a4b1e8 (patch)
tree34d8dd637baf665225ada73e76604531cd2c75e5 /src/plugins/platforms/ios
parentda0cb32b8ee7cc4a991a59420a411898e63a660e (diff)
parent894f86709080fe8d20875b402adce679963c49c2 (diff)
Merge remote-tracking branch 'origin/stable' into dev
Diffstat (limited to 'src/plugins/platforms/ios')
-rw-r--r--src/plugins/platforms/ios/qioseventdispatcher.h6
-rw-r--r--src/plugins/platforms/ios/qioseventdispatcher.mm79
-rw-r--r--src/plugins/platforms/ios/qiosglobal.mm2
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm1
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);
}