diff options
author | Christian Strømme <christian.stromme@digia.com> | 2013-10-24 16:24:48 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-25 18:11:51 +0200 |
commit | 746f7a5b28d92d962ae261c52da4d750ea3b50f0 (patch) | |
tree | 2d2acf3086a6693c82d6c8bad11a503e0851446e /src | |
parent | e1325cf26e146b68725cc1a0a02b274ce3dfbe5c (diff) |
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 <yoann.lopes@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/kernel/qjni.cpp | 29 |
1 files changed, 13 insertions, 16 deletions
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<int>, refCount) +class QJNIEnvironmentPrivateTLS +{ +public: + inline ~QJNIEnvironmentPrivateTLS() + { + QtAndroidPrivate::javaVM()->DetachCurrentThread(); + } +}; + +Q_GLOBAL_STATIC(QThreadStorage<QJNIEnvironmentPrivateTLS *>, 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() |