From e549f6984e2125969fd11a5b8f4e2df866ac0495 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Thu, 9 Jul 2020 16:22:44 -0700 Subject: [PATCH] Gate TurboModule eager initialization Summary: TurboModule eager initialization is a bit dangerous if we get it wrong, which we did (twice): T69449176. This diff gates TurboModule eager init behind a MC, so that we can control (i.e: turn off/on, and do gradually rollout of) TurobModule eager initialization in isolation from the larger TurboModules experiment. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D22460359 fbshipit-source-id: 3b8dce0529f1739bd68b8b16d6a28aa572d82c2c --- React/Base/RCTBridge.h | 4 ++++ React/Base/RCTBridge.m | 11 +++++++++++ React/CxxBridge/RCTCxxBridge.mm | 2 +- .../core/platform/ios/RCTTurboModuleManager.mm | 7 ++++++- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/React/Base/RCTBridge.h b/React/Base/RCTBridge.h index 55025c416f1..a7fb8d8c763 100644 --- a/React/Base/RCTBridge.h +++ b/React/Base/RCTBridge.h @@ -158,6 +158,10 @@ RCT_EXTERN NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass); RCT_EXTERN BOOL RCTTurboModuleEnabled(void); RCT_EXTERN void RCTEnableTurboModule(BOOL enabled); +// Turn on TurboModule eager initialization +RCT_EXTERN BOOL RCTTurboModuleEagerInitEnabled(void); +RCT_EXTERN void RCTEnableTurboModuleEagerInit(BOOL enabled); + /** * Async batched bridge used to communicate with the JavaScript application. */ diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m index b14c62f7baa..91f6b1b1406 100644 --- a/React/Base/RCTBridge.m +++ b/React/Base/RCTBridge.m @@ -115,6 +115,17 @@ void RCTEnableTurboModule(BOOL enabled) turboModuleEnabled = enabled; } +static BOOL turboModuleEagerInitEnabled = NO; +BOOL RCTTurboModuleEagerInitEnabled(void) +{ + return turboModuleEagerInitEnabled; +} + +void RCTEnableTurboModuleEagerInit(BOOL enabled) +{ + turboModuleEagerInitEnabled = enabled; +} + @interface RCTBridge () @end diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index f3ad20c6ac3..ed0ace43547 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -385,7 +385,7 @@ struct RCTInstanceCallback : public InstanceCallback { * id jsExecutorFactory may create and assign an id object to * RCTCxxBridge If id is assigned by this time, eagerly initialize all TurboModules */ - if (_turboModuleRegistry) { + if (_turboModuleRegistry && RCTTurboModuleEagerInitEnabled()) { for (NSString *moduleName in [_turboModuleRegistry eagerInitModuleNames]) { [_turboModuleRegistry moduleForName:[moduleName UTF8String]]; } diff --git a/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm b/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm index e0db1ecea87..0656a085a16 100644 --- a/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm +++ b/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm @@ -396,7 +396,12 @@ static Class getFallbackClassFromName(const char *name) }; if ([self _requiresMainQueueSetup:moduleClass]) { - if (!RCTIsMainQueue()) { + /** + * When TurboModule eager initialization is disabled, we expect TurboModules requiring main queue setup to be + * required on background threads. + * TODO(T69449176) Roll out TurboModule eager initialization, and remove this check. + */ + if (!RCTIsMainQueue() && !RCTTurboModuleEagerInitEnabled()) { RCTLogWarn( @"TurboModule \"%@\" requires synchronous dispatch onto the main queue to be initialized. This may lead to deadlock.", moduleClass);