Skip to content

Commit 9c35b5b

Browse files
RSNarafacebook-github-bot
authored andcommitted
Dispatch promise methods to the NativeModules thread
Summary: In D17480605 (689233b), I made all methods with void return types dispatch to the NativeModules thread. This diff makes the same change to methods with promise return types. **Note:** The changes are disabled for now. I'll add an MC so that we can test this in production in a later diff. Changelog: [Android][Fixed] - Make promise NativeModule methods dispatch to NativeModules thread Reviewed By: PeteTheHeat Differential Revision: D22489338 fbshipit-source-id: d5b030871f9f7b3f48eb111225516521493cb05e
1 parent aa1d31e commit 9c35b5b

File tree

6 files changed

+64
-10
lines changed

6 files changed

+64
-10
lines changed

ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ public TurboModuleManager(
6161
jsContext.get(),
6262
(CallInvokerHolderImpl) jsCallInvokerHolder,
6363
(CallInvokerHolderImpl) nativeCallInvokerHolder,
64-
delegate);
64+
delegate,
65+
false);
6566
installJSIBindings();
6667

6768
mEagerInitModuleNames =
@@ -278,7 +279,8 @@ private native HybridData initHybrid(
278279
long jsContext,
279280
CallInvokerHolderImpl jsCallInvokerHolder,
280281
CallInvokerHolderImpl nativeCallInvokerHolder,
281-
TurboModuleManagerDelegate tmmDelegate);
282+
TurboModuleManagerDelegate tmmDelegate,
283+
boolean enablePromiseAsyncDispatch);
282284

283285
private native void installJSIBindings();
284286

ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,13 @@ jni::local_ref<TurboModuleManager::jhybriddata> TurboModuleManager::initHybrid(
3939
jlong jsContext,
4040
jni::alias_ref<CallInvokerHolder::javaobject> jsCallInvokerHolder,
4141
jni::alias_ref<CallInvokerHolder::javaobject> nativeCallInvokerHolder,
42-
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate) {
42+
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate,
43+
bool enablePromiseAsyncDispatch) {
4344
auto jsCallInvoker = jsCallInvokerHolder->cthis()->getCallInvoker();
4445
auto nativeCallInvoker = nativeCallInvokerHolder->cthis()->getCallInvoker();
4546

47+
JavaTurboModule::enablePromiseAsyncDispatch(enablePromiseAsyncDispatch);
48+
4649
return makeCxxInstance(
4750
jThis,
4851
(jsi::Runtime *)jsContext,

ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ class TurboModuleManager : public jni::HybridClass<TurboModuleManager> {
3030
jlong jsContext,
3131
jni::alias_ref<CallInvokerHolder::javaobject> jsCallInvokerHolder,
3232
jni::alias_ref<CallInvokerHolder::javaobject> nativeCallInvokerHolder,
33-
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate);
33+
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate,
34+
bool enablePromiseAsyncDispatch);
3435
static void registerNatives();
3536

3637
private:

ReactCommon/turbomodule/core/BUCK

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
load("@fbsource//tools/build_defs/apple:flag_defs.bzl", "OBJC_ARC_PREPROCESSOR_FLAGS", "get_preprocessor_flags_for_build_mode", "get_static_library_ios_flags")
2-
load("//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "APPLE", "react_native_target", "react_native_xplat_target", "rn_xplat_cxx_library", "subdir_glob")
2+
load("//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "APPLE", "FBJNI_TARGET", "react_native_target", "react_native_xplat_target", "rn_xplat_cxx_library", "subdir_glob")
33

44
rn_xplat_cxx_library(
55
name = "core",
@@ -22,6 +22,7 @@ rn_xplat_cxx_library(
2222
],
2323
fbandroid_deps = [
2424
react_native_target("jni/react/jni:jni"),
25+
FBJNI_TARGET,
2526
],
2627
fbandroid_exported_headers = subdir_glob(
2728
[
@@ -40,7 +41,6 @@ rn_xplat_cxx_library(
4041
],
4142
fbobjc_inherited_buck_flags = get_static_library_ios_flags(),
4243
fbobjc_preprocessor_flags = OBJC_ARC_PREPROCESSOR_FLAGS + get_preprocessor_flags_for_build_mode(),
43-
force_static = True,
4444
ios_deps = [
4545
"//xplat/FBBaseLite:FBBaseLite",
4646
"//xplat/js/react-native-github:RCTCxxModule",

ReactCommon/turbomodule/core/platform/android/JavaTurboModule.cpp

+45-4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ JavaTurboModule::JavaTurboModule(const InitParams &params)
2828
instance_(jni::make_global(params.instance)),
2929
nativeInvoker_(params.nativeInvoker) {}
3030

31+
bool JavaTurboModule::isPromiseAsyncDispatchEnabled_ = false;
32+
void JavaTurboModule::enablePromiseAsyncDispatch(bool enable) {
33+
isPromiseAsyncDispatchEnabled_ = enable;
34+
}
35+
3136
namespace {
3237
jni::local_ref<JCxxCallbackImpl::JavaPart> createJavaCallbackFromJSIFunction(
3338
jsi::Function &&function,
@@ -227,7 +232,8 @@ JNIArgs JavaTurboModule::convertJSIArgsToJNIArgs(
227232

228233
auto makeGlobalIfNecessary =
229234
[&globalRefs, env, valueKind](jobject obj) -> jobject {
230-
if (valueKind == VoidKind) {
235+
if (valueKind == VoidKind ||
236+
(valueKind == PromiseKind && isPromiseAsyncDispatchEnabled_)) {
231237
jobject globalObj = env->NewGlobalRef(obj);
232238
globalRefs.push_back(globalObj);
233239
env->DeleteLocalRef(obj);
@@ -586,7 +592,13 @@ jsi::Value JavaTurboModule::invokeJavaMethod(
586592
runtime,
587593
jsi::PropNameID::forAscii(runtime, "fn"),
588594
2,
589-
[this, &jargs, argCount, instance, methodID, env](
595+
[this,
596+
&jargs,
597+
&globalRefs,
598+
argCount,
599+
instance_ = instance_,
600+
methodID,
601+
env](
590602
jsi::Runtime &runtime,
591603
const jsi::Value &thisVal,
592604
const jsi::Value *promiseConstructorArgs,
@@ -619,8 +631,37 @@ jsi::Value JavaTurboModule::invokeJavaMethod(
619631
jobject promise = env->NewObject(
620632
jPromiseImpl, jPromiseImplConstructor, resolve, reject);
621633

622-
jargs[argCount].l = promise;
623-
env->CallVoidMethodA(instance, methodID, jargs.data());
634+
if (isPromiseAsyncDispatchEnabled_) {
635+
jobject globalPromise = env->NewGlobalRef(promise);
636+
637+
globalRefs.push_back(globalPromise);
638+
env->DeleteLocalRef(promise);
639+
640+
jargs[argCount].l = globalPromise;
641+
642+
nativeInvoker_->invokeAsync(
643+
[jargs, globalRefs, methodID, instance_ = instance_]() mutable
644+
-> void {
645+
/**
646+
* TODO(ramanpreet): Why do we have to require the
647+
* environment again? Why does JNI crash when we use the env
648+
* from the upper scope?
649+
*/
650+
JNIEnv *env = jni::Environment::current();
651+
652+
env->CallVoidMethodA(
653+
instance_.get(), methodID, jargs.data());
654+
FACEBOOK_JNI_THROW_PENDING_EXCEPTION();
655+
656+
for (auto globalRef : globalRefs) {
657+
env->DeleteGlobalRef(globalRef);
658+
}
659+
});
660+
661+
} else {
662+
jargs[argCount].l = promise;
663+
env->CallVoidMethodA(instance_.get(), methodID, jargs.data());
664+
}
624665

625666
return jsi::Value::undefined();
626667
});

ReactCommon/turbomodule/core/platform/android/JavaTurboModule.h

+7
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,17 @@ class JSI_EXPORT JavaTurboModule : public TurboModule {
4949
const jsi::Value *args,
5050
size_t argCount);
5151

52+
static void enablePromiseAsyncDispatch(bool enable);
53+
5254
private:
5355
jni::global_ref<JTurboModule> instance_;
5456
std::shared_ptr<CallInvoker> nativeInvoker_;
5557

58+
/**
59+
* Experiments
60+
*/
61+
static bool isPromiseAsyncDispatchEnabled_;
62+
5663
JNIArgs convertJSIArgsToJNIArgs(
5764
JNIEnv *env,
5865
jsi::Runtime &rt,

0 commit comments

Comments
 (0)