summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBogDan Vatra <bogdan@kdab.com>2015-12-17 09:30:16 +0200
committerBogDan Vatra <bogdan@kdab.com>2015-12-17 13:46:14 +0000
commit0b10d41c3db0d1a43e754a2bd923a0df8915d0e5 (patch)
treea3abcedaa3da0d7721e78fa15ac530969da3b1d5 /src
parent08ee579cf025ad868bb405835b57d31e512b6fd6 (diff)
Android: Fix crash at exit
Delay the exit call until Java part finishes the execution. We must be sure all the threads are stopped (hanged), when we call exit, otherwise java thread will try to use static vars that are freed by the qt thread. We also need to call exit from Qt thread, otherwise Qt will complain about it. Change-Id: Ia1e7a4d7d56c39d38313f040aab618ec5a68dfb6 Reviewed-by: Christian Stromme <christian.stromme@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java1
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java7
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp20
3 files changed, 25 insertions, 3 deletions
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index 4575d8a1d3..dd5a7b4fec 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -919,6 +919,7 @@ public class QtActivityDelegate
public void onDestroy()
{
if (m_quitApp) {
+ QtNative.terminateQt();
if (m_debuggerProcess != null)
m_debuggerProcess.destroy();
System.exit(0);// FIXME remove it or find a better way
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index 8880c003e7..2349ea6db1 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -294,7 +294,12 @@ public class QtNative
private static void quitApp()
{
- m_activity.finish();
+ runAction(new Runnable() {
+ @Override
+ public void run() {
+ m_activity.finish();
+ }
+ });
}
//@ANDROID-9
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index f500d6e413..dd9154f8d2 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -34,6 +34,7 @@
#include <dlfcn.h>
#include <pthread.h>
+#include <semaphore.h>
#include <qplugin.h>
#include <qdebug.h>
@@ -91,6 +92,8 @@ extern "C" typedef int (*Main)(int, char **); //use the standard main method to
static Main m_main = nullptr;
static void *m_mainLibraryHnd = nullptr;
static QList<QByteArray> m_applicationParams;
+pthread_t m_qtAppThread = 0;
+static sem_t m_exitSemaphore, m_terminateSemaphore;
struct SurfaceData
{
@@ -454,6 +457,10 @@ static void *startMainMethod(void */*data*/)
if (vm != 0)
vm->DetachCurrentThread();
+ sem_post(&m_terminateSemaphore);
+ sem_wait(&m_exitSemaphore);
+ sem_destroy(&m_exitSemaphore);
+
// We must call exit() to ensure that all global objects will be destructed
exit(ret);
return 0;
@@ -503,8 +510,13 @@ static jboolean startQtApplication(JNIEnv *env, jobject /*object*/, jstring para
return false;
}
- pthread_t appThread;
- return pthread_create(&appThread, nullptr, startMainMethod, nullptr) == 0;
+ if (sem_init(&m_exitSemaphore, 0, 0) == -1)
+ return false;
+
+ if (sem_init(&m_terminateSemaphore, 0, 0) == -1)
+ return false;
+
+ return pthread_create(&m_qtAppThread, nullptr, startMainMethod, nullptr) == 0;
}
@@ -518,6 +530,8 @@ static void quitQtAndroidPlugin(JNIEnv *env, jclass /*clazz*/)
static void terminateQt(JNIEnv *env, jclass /*clazz*/)
{
+ sem_wait(&m_terminateSemaphore);
+ sem_destroy(&m_terminateSemaphore);
env->DeleteGlobalRef(m_applicationClass);
env->DeleteGlobalRef(m_classLoaderObject);
if (m_resourcesObj)
@@ -535,6 +549,8 @@ static void terminateQt(JNIEnv *env, jclass /*clazz*/)
m_androidPlatformIntegration = nullptr;
delete m_androidAssetsFileEngineHandler;
m_androidAssetsFileEngineHandler = nullptr;
+ sem_post(&m_exitSemaphore);
+ pthread_join(m_qtAppThread, nullptr);
}
static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface, jint w, jint h)