From dad9ce46f0f91cd64a3b4daa11c9e7a5941ac7e4 Mon Sep 17 00:00:00 2001 From: Petri Virkkunen Date: Thu, 12 Dec 2024 15:20:55 +0200 Subject: [PATCH] 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 --- .../src/org/qtproject/qt/android/QtNative.java | 16 +++++++++------- src/plugins/platforms/android/androidjnimain.cpp | 6 ++++-- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt/android/QtNative.java b/src/android/jar/src/org/qtproject/qt/android/QtNative.java index 33ffd58482f..9f759b18c7e 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtNative.java @@ -378,13 +378,15 @@ public class QtNative static void quitQt() { - terminateQt(); - m_stateDetails.isStarted = false; - notifyAppStateDetailsChanged(m_stateDetails); - getQtThread().exit(); - synchronized (m_qtThreadLock) { - m_qtThread = null; - } + runAction(() -> { + terminateQt(); + m_stateDetails.isStarted = false; + notifyAppStateDetailsChanged(m_stateDetails); + getQtThread().exit(); + synchronized (m_qtThreadLock) { + m_qtThread = null; + } + }); } @UsedFromNativeCode diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 1089f24e9d3..8919aefe82c 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -471,8 +471,10 @@ static void startQtApplication(JNIEnv */*env*/, jclass /*clazz*/) qWarning() << "dlclose failed:" << dlerror(); } - if (m_applicationClass && QtAndroid::isQtApplication()) - QJniObject::callStaticMethod(m_applicationClass, "quitApp", "()V"); + if (m_applicationClass) { + const auto quitMethodName = QtAndroid::isQtApplication() ? "quitApp" : "quitQt"; + QJniObject::callStaticMethod(m_applicationClass, quitMethodName); + } sem_post(&m_terminateSemaphore); sem_wait(&m_exitSemaphore);