Quick for Android: Call quitQt() after main() exits

In Quick for Android case, if Qt exits itself (Qt.exit() in QML, etc),
we get deadlock in startQtApplication after the user-provided main()
exits.

This is due to terminateQt waiting for a semaphore that - in a normal
Q4A context - is called when the hosting Activity itself is destroyed
from another thread via an activity status callback.

Task-number: QTBUG-130342
Change-Id: I9cd701e0ea86a445e13a6568c4954de6e356e98a
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
This commit is contained in:
Petri Virkkunen 2024-12-12 15:20:55 +02:00
parent 3bcf55daa5
commit dad9ce46f0
2 changed files with 13 additions and 9 deletions

View File

@ -378,6 +378,7 @@ public class QtNative
static void quitQt() static void quitQt()
{ {
runAction(() -> {
terminateQt(); terminateQt();
m_stateDetails.isStarted = false; m_stateDetails.isStarted = false;
notifyAppStateDetailsChanged(m_stateDetails); notifyAppStateDetailsChanged(m_stateDetails);
@ -385,6 +386,7 @@ public class QtNative
synchronized (m_qtThreadLock) { synchronized (m_qtThreadLock) {
m_qtThread = null; m_qtThread = null;
} }
});
} }
@UsedFromNativeCode @UsedFromNativeCode

View File

@ -471,8 +471,10 @@ static void startQtApplication(JNIEnv */*env*/, jclass /*clazz*/)
qWarning() << "dlclose failed:" << dlerror(); qWarning() << "dlclose failed:" << dlerror();
} }
if (m_applicationClass && QtAndroid::isQtApplication()) if (m_applicationClass) {
QJniObject::callStaticMethod<void>(m_applicationClass, "quitApp", "()V"); const auto quitMethodName = QtAndroid::isQtApplication() ? "quitApp" : "quitQt";
QJniObject::callStaticMethod<void>(m_applicationClass, quitMethodName);
}
sem_post(&m_terminateSemaphore); sem_post(&m_terminateSemaphore);
sem_wait(&m_exitSemaphore); sem_wait(&m_exitSemaphore);