From 746f7a5b28d92d962ae261c52da4d750ea3b50f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Thu, 24 Oct 2013 16:24:48 +0200 Subject: QJNI: Don't detach from the thread as long as the thread is alive. Attaching and detaching the current thread to/from the VM on each jni call, causes a new thread object to be created and triggers GC when detaching (GC alone takes anything between 10-30 ms to finish on the test device). Instead of detaching when the environment object goes out of scope, we now detach when the thread exits. Task-number: QTBUG-34279 Change-Id: Ia613934e61f914d4be63bfa1be8fdecf849928b0 Reviewed-by: Yoann Lopes --- src/corelib/kernel/qjni.cpp | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'src/corelib/kernel/qjni.cpp') diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp index 54cd2b5a75..cf839cfaef 100644 --- a/src/corelib/kernel/qjni.cpp +++ b/src/corelib/kernel/qjni.cpp @@ -162,24 +162,31 @@ static jfieldID getCachedFieldID(JNIEnv *env, return id; } -Q_GLOBAL_STATIC(QThreadStorage, refCount) +class QJNIEnvironmentPrivateTLS +{ +public: + inline ~QJNIEnvironmentPrivateTLS() + { + QtAndroidPrivate::javaVM()->DetachCurrentThread(); + } +}; + +Q_GLOBAL_STATIC(QThreadStorage, jniEnvTLS) QJNIEnvironmentPrivate::QJNIEnvironmentPrivate() : jniEnv(0) { JavaVM *vm = QtAndroidPrivate::javaVM(); if (vm->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) == JNI_EDETACHED) { - if (vm->AttachCurrentThread(&jniEnv, 0) < 0) + if (vm->AttachCurrentThread(&jniEnv, 0) != JNI_OK) return; } if (!jniEnv) return; - if (!refCount->hasLocalData()) - refCount->setLocalData(1); - else - refCount->setLocalData(refCount->localData() + 1); + if (!jniEnvTLS->hasLocalData()) + jniEnvTLS->setLocalData(new QJNIEnvironmentPrivateTLS); } JNIEnv *QJNIEnvironmentPrivate::operator->() @@ -194,16 +201,6 @@ QJNIEnvironmentPrivate::operator JNIEnv* () const QJNIEnvironmentPrivate::~QJNIEnvironmentPrivate() { - if (!jniEnv) - return; - - const int newRef = refCount->localData() - 1; - refCount->setLocalData(newRef); - - if (newRef == 0) - QtAndroidPrivate::javaVM()->DetachCurrentThread(); - - jniEnv = 0; } QJNIObjectData::QJNIObjectData() -- cgit v1.2.3