path: root/src
diff options
authorChristian Strømme <>2015-03-24 13:09:44 +0100
committerChristian Stromme <>2015-03-30 13:12:51 +0000
commit6b19eec63190c385a465c29b1f811214c6257034 (patch)
tree6b35b0933be85a69c40e1d2fe5f6d47bfd84e856 /src
parenta68b03d6a9828cd4a060db42a744e7df5a00bb07 (diff)
Android: Only take ownership of threads we explicitly attach to.
Previously we would take ownership of all threads when attempting to attach it to the VM, regardless if it was already attached or not, to avoid expensive re-attachments in our own code. The downside of this approach is that we might hijack threads the user wants to control themselves, and the later detach the thread while it still in use, e.g., after the QApplication instance is destroyed. This change does not add any infrastructure to enable more advanced management of attached threads, so threads might still be hijacked if the user make a call directly or indirectly through the QJNI API's on a thread that's not attached. Task-number: QTBUG-45110 Change-Id: I30f7faa2d8c2c35151e2ac8875ebf839bcd6c7c6 Reviewed-by: Sergey Galin <> Reviewed-by: Eskil Abrahamsen Blomfeldt <>
Diffstat (limited to 'src')
1 files changed, 8 insertions, 7 deletions
diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp
index 694463b9d8..22c0f03afc 100644
--- a/src/corelib/kernel/qjni.cpp
+++ b/src/corelib/kernel/qjni.cpp
@@ -221,17 +221,18 @@ QJNIEnvironmentPrivate::QJNIEnvironmentPrivate()
: jniEnv(0)
JavaVM *vm = QtAndroidPrivate::javaVM();
- if (vm->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) == JNI_EDETACHED) {
+ const jint ret = vm->GetEnv((void**)&jniEnv, JNI_VERSION_1_6);
+ if (ret == JNI_OK) // Already attached
+ return;
+ if (ret == JNI_EDETACHED) { // We need to (re-)attach
JavaVMAttachArgs args = { JNI_VERSION_1_6, qJniThreadName, Q_NULLPTR };
if (vm->AttachCurrentThread(&jniEnv, &args) != JNI_OK)
- }
- if (!jniEnv)
- return;
- if (!jniEnvTLS->hasLocalData())
- jniEnvTLS->setLocalData(new QJNIEnvironmentPrivateTLS);
+ if (!jniEnvTLS->hasLocalData()) // If we attached the thread we own it.
+ jniEnvTLS->setLocalData(new QJNIEnvironmentPrivateTLS);
+ }
JNIEnv *QJNIEnvironmentPrivate::operator->()