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:
Родитель
821166c111
Коммит
6dcd0de96c
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче