Make PlatformConstants use main queue setup (#50111)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/50111

## Rationale
Rendering can now include main -> js sync calls.

If we allow js -> main sync calls during rendering, react native can deadlock.

So, this diff moves the js -> main sync calls to "main queue module setup", which occurs before rendering.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D71480047

fbshipit-source-id: e36a4dd317bbbf46a6766f01fbf4d69a83a45c17
This commit is contained in:
Ramanpreet Nara
2025-03-19 21:16:05 -07:00
committed by Facebook GitHub Bot
parent ed8749ce59
commit 06c88be6e3
2 changed files with 37 additions and 28 deletions
@@ -10,6 +10,7 @@
#import <UIKit/UIKit.h>
#import <FBReactNativeSpec/FBReactNativeSpec.h>
#import <React/RCTInitializing.h>
#import <React/RCTUtils.h>
#import <React/RCTVersion.h>
@@ -39,10 +40,12 @@ static NSString *interfaceIdiom(UIUserInterfaceIdiom idiom)
}
}
@interface RCTPlatform () <NativePlatformConstantsIOSSpec>
@interface RCTPlatform () <NativePlatformConstantsIOSSpec, RCTInitializing>
@end
@implementation RCTPlatform
@implementation RCTPlatform {
ModuleConstants<JS::NativePlatformConstantsIOS::Constants> _constants;
}
RCT_EXPORT_MODULE(PlatformConstants)
@@ -51,6 +54,29 @@ RCT_EXPORT_MODULE(PlatformConstants)
return YES;
}
- (void)initialize
{
UIDevice *device = [UIDevice currentDevice];
auto versions = RCTGetReactNativeVersion();
_constants = typedConstants<JS::NativePlatformConstantsIOS::Constants>({
.forceTouchAvailable = RCTForceTouchAvailable() ? true : false,
.osVersion = [device systemVersion],
.systemName = [device systemName],
.interfaceIdiom = interfaceIdiom([device userInterfaceIdiom]),
.isTesting = RCTRunningInTestEnvironment() ? true : false,
.reactNativeVersion = JS::NativePlatformConstantsIOS::ConstantsReactNativeVersion::Builder(
{.minor = [versions[@"minor"] doubleValue],
.major = [versions[@"major"] doubleValue],
.patch = [versions[@"patch"] doubleValue],
.prerelease = [versions[@"prerelease"] isKindOfClass:[NSNull class]] ? nullptr : versions[@"prerelease"]}),
#if TARGET_OS_MACCATALYST
.isMacCatalyst = true,
#else
.isMacCatalyst = false,
#endif
});
}
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
@@ -59,35 +85,12 @@ RCT_EXPORT_MODULE(PlatformConstants)
// TODO: Use the generated struct return type.
- (ModuleConstants<JS::NativePlatformConstantsIOS::Constants>)constantsToExport
{
return (ModuleConstants<JS::NativePlatformConstantsIOS::Constants>)[self getConstants];
return _constants;
}
- (ModuleConstants<JS::NativePlatformConstantsIOS::Constants>)getConstants
{
__block ModuleConstants<JS::NativePlatformConstantsIOS::Constants> constants;
RCTUnsafeExecuteOnMainQueueSync(^{
UIDevice *device = [UIDevice currentDevice];
auto versions = RCTGetReactNativeVersion();
constants = typedConstants<JS::NativePlatformConstantsIOS::Constants>({
.forceTouchAvailable = RCTForceTouchAvailable() ? true : false,
.osVersion = [device systemVersion],
.systemName = [device systemName],
.interfaceIdiom = interfaceIdiom([device userInterfaceIdiom]),
.isTesting = RCTRunningInTestEnvironment() ? true : false,
.reactNativeVersion = JS::NativePlatformConstantsIOS::ConstantsReactNativeVersion::Builder(
{.minor = [versions[@"minor"] doubleValue],
.major = [versions[@"major"] doubleValue],
.patch = [versions[@"patch"] doubleValue],
.prerelease = [versions[@"prerelease"] isKindOfClass:[NSNull class]] ? nullptr : versions[@"prerelease"]}),
#if TARGET_OS_MACCATALYST
.isMacCatalyst = true,
#else
.isMacCatalyst = false,
#endif
});
});
return constants;
return _constants;
}
- (std::shared_ptr<TurboModule>)getTurboModule:(const ObjCTurboModule::InitParams &)params
+7 -1
View File
@@ -149,7 +149,13 @@
{
"name": "FBReactNativeSpec",
"type": "modules",
"ios": {},
"ios": {
"modules": {
"PlatformConstants": {
"unstableRequiresMainQueueSetup": true
}
}
},
"android": {},
"jsSrcsDir": "src"
},