diff options
author | Christian Strømme <christian.stromme@theqtcompany.com> | 2015-03-24 13:09:44 +0100 |
---|---|---|
committer | Christian Stromme <christian.stromme@theqtcompany.com> | 2015-03-30 13:12:51 +0000 |
commit | 6b19eec63190c385a465c29b1f811214c6257034 (patch) | |
tree | 6b35b0933be85a69c40e1d2fe5f6d47bfd84e856 /src | |
parent | a68b03d6a9828cd4a060db42a744e7df5a00bb07 (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 <s.galin@2gis.ru>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/kernel/qjni.cpp | 15 |
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) return; - } - 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->() |