From 06c88be6e370a17cba0e4b4f679fc32b86963c30 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Wed, 19 Mar 2025 21:16:05 -0700 Subject: [PATCH] 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 --- .../React/CoreModules/RCTPlatform.mm | 57 ++++++++++--------- packages/react-native/package.json | 8 ++- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/packages/react-native/React/CoreModules/RCTPlatform.mm b/packages/react-native/React/CoreModules/RCTPlatform.mm index ec8a5f3220e..2aa4e28be8e 100644 --- a/packages/react-native/React/CoreModules/RCTPlatform.mm +++ b/packages/react-native/React/CoreModules/RCTPlatform.mm @@ -10,6 +10,7 @@ #import #import +#import #import #import @@ -39,10 +40,12 @@ static NSString *interfaceIdiom(UIUserInterfaceIdiom idiom) } } -@interface RCTPlatform () +@interface RCTPlatform () @end -@implementation RCTPlatform +@implementation RCTPlatform { + ModuleConstants _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({ + .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)constantsToExport { - return (ModuleConstants)[self getConstants]; + return _constants; } - (ModuleConstants)getConstants { - __block ModuleConstants constants; - RCTUnsafeExecuteOnMainQueueSync(^{ - UIDevice *device = [UIDevice currentDevice]; - auto versions = RCTGetReactNativeVersion(); - constants = typedConstants({ - .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)getTurboModule:(const ObjCTurboModule::InitParams &)params diff --git a/packages/react-native/package.json b/packages/react-native/package.json index 6fdcfa48049..63ca1cb983d 100644 --- a/packages/react-native/package.json +++ b/packages/react-native/package.json @@ -149,7 +149,13 @@ { "name": "FBReactNativeSpec", "type": "modules", - "ios": {}, + "ios": { + "modules": { + "PlatformConstants": { + "unstableRequiresMainQueueSetup": true + } + } + }, "android": {}, "jsSrcsDir": "src" },