JNI: emit warning in debug mode in case of JNI environment conflicts

If a QJniObject method that uses the stored JNIEnv pointer is called
from a different thread than the one the object was created in, then a
FATAL abort of the JNI runtime is likely, but hard to debug (the error
messages from JNI are visible in the logcat log of adb).

In debug mode, compare the stored JNIEnv pointer with the one provided
for the current thread, and emit a critical runtime warning if they do
not match, as this indicates a race condition to the underlying JAVA
object.

Change-Id: Ief578f445bcfab1939ddbe95c6ba796279be9115
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
This commit is contained in:
Volker Hilsheimer 2023-10-11 13:37:31 +02:00
parent 944200b5a9
commit ed2fbed479

View File

@ -736,9 +736,20 @@ QJniObject::~QJniObject()
{}
/*! \internal
While we can synchronize concurrent access to a QJniObject on the C++ side,
we cannot synchronize access across C++ and Java, so any concurrent access to
a QJniObject, except the most basic ref-counting operations (destructor and
assignment) is wrong. All calls must happen from the thread that created the
QJniObject.
*/
JNIEnv *QJniObject::jniEnv() const noexcept
{
Q_ASSERT_X([this]{
QJniEnvironment currentThreadEnv;
return currentThreadEnv.jniEnv() == d->jniEnv();
}(), __FUNCTION__, "QJniEnvironment mismatch, probably accessing this Java object"
" from the wrong thread!");
return d->jniEnv();
}