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) {
|
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 {
|
try {
|
||||||
runnable();
|
localRunnable();
|
||||||
} catch (const jsi::JSError& ex) {
|
} catch (const jsi::JSError& ex) {
|
||||||
throwNewJavaException(
|
throwNewJavaException(
|
||||||
JavaJSException::create(ex.getMessage().c_str(), ex.getStack().c_str(), ex)
|
JavaJSException::create(ex.getMessage().c_str(), ex.getStack().c_str(), ex)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче