Skip to content

Commit d7ac21c

Browse files
RSNarafacebook-github-bot
authored andcommitted
Remove main queue execution of constantsToExport
Summary: ## Context - If a NativeModule requires main queue setup, its `constantsToExport` method is executed on the main queue. - In the TurboModule system, `constantsToExport` or `getConstants` is treated like a regular synchronous NativeModule method. Therefore, it's always executed on the JS thread. This difference in behaviour is dangerous when we're A/B testing the TurboModule infra: One could write a NativeModule that requires main queue setup, and have it expose constants that access objects/state only accessible on the UI thread. This NativeModule would work fine in the legacy infra, which could be the case if the NativeModule author is testing locally. But once it ships to prod, it may run with the TurboModule system, and crash the application. To mitigate this risk, I'm removing this special main queue execution of `constantsToExport` from the legacy infrastructure. ## Consequences - If a NativeModule's `constantsToExport` method accesses objects/state only accessible on the UI thread, it must do so by explicitly scheduling work on the main thread. I wrote up a codemod to fix this for our OSS modules: D21797048. - Eagerly initialized NativeModules that required main queue setup had their constants calculated eagerly. After the changes in this diff, those NativeModules will have their constants calculated lazily. I don't think this is a big deal because only a handful of NativeModules are eagerly initialized, and eagerly initialized NativeModules are going away anyway. Changelog: [iOS][Removed] - Main queue execution of constantsToExport in NativeModules requiring main queue setup Reviewed By: fkgozali Differential Revision: D21829091 fbshipit-source-id: df21fd5fd2ef45a291c07400f360bba801ae290f
1 parent 39d6773 commit d7ac21c

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

React/Base/RCTModuleData.h

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#import <Foundation/Foundation.h>
99

1010
#import <React/RCTInvalidating.h>
11+
#import "RCTDefines.h"
1112

1213
@protocol RCTBridgeMethod;
1314
@protocol RCTBridgeModule;
@@ -94,3 +95,6 @@ typedef id<RCTBridgeModule> (^RCTBridgeModuleProvider)(void);
9495
@property (nonatomic, assign, readonly) BOOL implementsPartialBatchDidFlush;
9596

9697
@end
98+
99+
RCT_EXTERN void RCTSetIsMainQueueExecutionOfConstantsToExportDisabled(BOOL val);
100+
RCT_EXTERN BOOL RCTIsMainQueueExecutionOfConstantsToExportDisabled();

React/Base/RCTModuleData.mm

+14-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,17 @@ int32_t getUniqueId()
2929
return counter++;
3030
}
3131
}
32+
static BOOL isMainQueueExecutionOfConstantToExportDisabled = NO;
33+
34+
void RCTSetIsMainQueueExecutionOfConstantsToExportDisabled(BOOL val)
35+
{
36+
isMainQueueExecutionOfConstantToExportDisabled = val;
37+
}
38+
39+
BOOL RCTIsMainQueueExecutionOfConstantsToExportDisabled()
40+
{
41+
return isMainQueueExecutionOfConstantToExportDisabled;
42+
}
3243

3344
@implementation RCTModuleData {
3445
NSDictionary<NSString *, id> *_constantsToExport;
@@ -389,7 +400,8 @@ - (void)gatherConstants
389400
* require.
390401
*/
391402
BridgeNativeModulePerfLogger::moduleJSRequireEndingStart([moduleName UTF8String]);
392-
if (_requiresMainQueueSetup) {
403+
404+
if (!RCTIsMainQueueExecutionOfConstantsToExportDisabled() && _requiresMainQueueSetup) {
393405
if (!RCTIsMainQueue()) {
394406
RCTLogWarn(@"Required dispatch_sync to load constants for %@. This may lead to deadlocks", _moduleClass);
395407
}
@@ -400,6 +412,7 @@ - (void)gatherConstants
400412
} else {
401413
_constantsToExport = [_instance constantsToExport] ?: @{};
402414
}
415+
403416
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
404417
} else {
405418
/**

React/CxxBridge/RCTCxxBridge.mm

+3-1
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,9 @@ - (void)_prepareModulesWithDispatchGroup:(dispatch_group_t)dispatchGroup
907907
if (self.valid && ![moduleData.moduleClass isSubclassOfClass:[RCTCxxModule class]]) {
908908
[self->_performanceLogger appendStartForTag:RCTPLNativeModuleMainThread];
909909
(void)[moduleData instance];
910-
[moduleData gatherConstants];
910+
if (!RCTIsMainQueueExecutionOfConstantsToExportDisabled()) {
911+
[moduleData gatherConstants];
912+
}
911913
[self->_performanceLogger appendStopForTag:RCTPLNativeModuleMainThread];
912914
}
913915
};

0 commit comments

Comments
 (0)