destroy callbacks even if they aren't called, when java object is destroyed

Summary:
JSI callbacks are only destroyed if the callback is called. If the callback is never called, we're potentially leaking a lot of callbacks.

To mitigate this, we add a wrapper object that is owned by the std::function. Whenever the std::function is destroyed, the wrapper is destroyed and it deallocates the callback as well.

Changelog: [Internal]

Reviewed By: RSNara

Differential Revision: D27436402

fbshipit-source-id: d153640d5d7988c7fadaf2cb332ec00dadd0689a
This commit is contained in:
Joshua Gross
2021-04-01 16:26:47 -07:00
committed by Facebook GitHub Bot
parent 0901830977
commit 3d1afbbda3
7 changed files with 93 additions and 30 deletions
@@ -23,6 +23,13 @@ public class ReactFeatureFlags {
*/
public static volatile boolean useTurboModules = false;
/**
* Should application use the new TM callback manager in Cxx? This is assumed to be a sane
* default, but it's new. We will delete once (1) we know it's safe to ship and (2) we have
* quantified impact.
*/
public static volatile boolean useTurboModulesRAIICallbackManager = false;
/** Should we dispatch TurboModule methods with promise returns to the NativeModules thread? */
public static volatile boolean enableTurboModulePromiseAsyncDispatch = false;
@@ -16,6 +16,7 @@ import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.CxxModuleWrapper;
import com.facebook.react.bridge.JSIModule;
import com.facebook.react.bridge.RuntimeExecutor;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.turbomodule.core.interfaces.TurboModuleRegistry;
@@ -58,7 +59,8 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry {
runtimeExecutor,
(CallInvokerHolderImpl) jsCallInvokerHolder,
(CallInvokerHolderImpl) nativeCallInvokerHolder,
delegate);
delegate,
ReactFeatureFlags.useTurboModulesRAIICallbackManager);
installJSIBindings();
mEagerInitModuleNames =
@@ -290,7 +292,8 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry {
RuntimeExecutor runtimeExecutor,
CallInvokerHolderImpl jsCallInvokerHolder,
CallInvokerHolderImpl nativeCallInvokerHolder,
TurboModuleManagerDelegate tmmDelegate);
TurboModuleManagerDelegate tmmDelegate,
boolean useTurboModulesRAIICallbackManager);
private native void installJSIBindings();
@@ -39,10 +39,15 @@ jni::local_ref<TurboModuleManager::jhybriddata> TurboModuleManager::initHybrid(
jni::alias_ref<JRuntimeExecutor::javaobject> runtimeExecutor,
jni::alias_ref<CallInvokerHolder::javaobject> jsCallInvokerHolder,
jni::alias_ref<CallInvokerHolder::javaobject> nativeCallInvokerHolder,
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate) {
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate,
bool useTurboModulesRAIICallbackManager) {
auto jsCallInvoker = jsCallInvokerHolder->cthis()->getCallInvoker();
auto nativeCallInvoker = nativeCallInvokerHolder->cthis()->getCallInvoker();
if (useTurboModulesRAIICallbackManager) {
JavaTurboModule::enableUseTurboModulesRAIICallbackManager(true);
}
return makeCxxInstance(
jThis,
runtimeExecutor->cthis()->get(),
@@ -32,7 +32,8 @@ class TurboModuleManager : public jni::HybridClass<TurboModuleManager> {
jni::alias_ref<JRuntimeExecutor::javaobject> runtimeExecutor,
jni::alias_ref<CallInvokerHolder::javaobject> jsCallInvokerHolder,
jni::alias_ref<CallInvokerHolder::javaobject> nativeCallInvokerHolder,
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate);
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate,
bool useTurboModulesRAIICallbackManager);
static void registerNatives();
private: