Fix crash in OpenGLDriver::destroyStream#9801
Conversation
Fixes a SIGSEGV crash that occurs during `ExternalStreamManagerAndroid::release()` when users provide a custom Platform instance during Engine creation. When a custom Platform is used, ExternalStreamManagerAndroid is instantiated on the application's thread. Its constructor was caching a C++ reference (`VirtualMachineEnv& mVm`) to the `thread_local` VirtualMachineEnv instance belonging to the application thread. Later, when the Filament backend thread executed `release()`, it accessed this cached reference. This caused the backend thread to retrieve the `JNIEnv*` from the application thread's `thread_local` instance, and subsequently call `env->DeleteGlobalRef()`. A thread must use its own `JNIEnv` pointer, so using the application thread's pointer from the backend thread resulted in a crash. BUGS=[489814416]
In the current Filament design, a stream is created in the application thread via |
| UTILS_NOINLINE | ||
| JNIEnv* ExternalStreamManagerAndroid::getEnvironmentSlow() noexcept { | ||
| JNIEnv* const env = mVm.getEnvironment(); | ||
| JNIEnv* const env = VirtualMachineEnv::get().getEnvironment(); |
There was a problem hiding this comment.
VirtualMachineEnv::get() is documented as "must be called on the backend thread"
This is also the case for VirtualMachineEnv::getEnvironment().
I think what should happen instead is that ExternalStreamManager should always be created from the backend thread (this broke, guess, when we allowed custom Platforms).
And, we should use VirtualMachineEnv::getThreadEnvironment() to get a JNIEnv from any thread.
There was a problem hiding this comment.
Yeah I moved the creation to the backend side.
4e34202 to
4004224
Compare
4004224 to
567367a
Compare
Fixes a SIGSEGV crash that occurs during
ExternalStreamManagerAndroid::release()when users provide a custom Platform instance during Engine creation.When a custom Platform is used, ExternalStreamManagerAndroid is instantiated on the application's thread. Its constructor was caching a C++ reference (
VirtualMachineEnv& mVm) to thethread_localVirtualMachineEnv instance belonging to the application thread.Later, when the Filament backend thread executed
release(), it accessed this cached reference. This caused the backend thread to retrieve theJNIEnv*from the application thread'sthread_localinstance, and subsequently callenv->DeleteGlobalRef(). A thread must use its ownJNIEnvpointer, so using the application thread's pointer from the backend thread resulted in a crash.BUGS=[489814416]