Fabric: Ressetting callable inside `JMessageQueueThread`

Summary:
We recently realized that `JNativeRunnable` instances that RN uses to pass C++ callables to Java land actually are GC managed objects. That makes their lifetime quite unpredictable (longer than necessary). Normally, it's fine but some C++ code explicitly relies on deallocation order.
To make the behavior of `JMessageQueueThread` more predictable, now we clear/reset stored `std::function` object right after an invocation to explicitly free all associated resources (`JNativeRunnable` still holds some wrapper but that wrapper holds nothing).

Changelog: [INTERNAL]

Reviewed By: JoshuaGross

Differential Revision: D18603390

fbshipit-source-id: 362f6cc0901cbe14d3360b928c98e204d277b1aa
This commit is contained in:
Valentin Shergin 2019-11-21 16:03:06 -08:00 коммит произвёл Facebook Github Bot
Родитель 821166c111
Коммит 6dcd0de96c
1 изменённых файлов: 13 добавлений и 2 удалений

Просмотреть файл

@ -32,9 +32,20 @@ struct JavaJSException : jni::JavaClass<JavaJSException, JThrowable> {
};
std::function<void()> wrapRunnable(std::function<void()>&& runnable) {
return [runnable=std::move(runnable)] {
return [runnable = std::move(runnable)]() mutable {
if (!runnable) {
// Runnable is empty, nothing to run.
return;
}
auto localRunnable = std::move(runnable);
// Clearing `runnable` to free all associated resources that stored lambda
// might retain.
runnable = nullptr;
try {
runnable();
localRunnable();
} catch (const jsi::JSError& ex) {
throwNewJavaException(
JavaJSException::create(ex.getMessage().c_str(), ex.getStack().c_str(), ex)