From 3eec4a3ea985fd8d10ac8c52fccbd0c687937594 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Thu, 20 Feb 2025 06:31:34 -0800 Subject: [PATCH] Back out "Throw exception with name of TurboModule instead of deadlock during sync rendering" (#49554) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/49554 For some reason, this diff completely breaks the linker on iOS. I tried to look for a fix forward, but unsuccessfully. I'm reverting this diff to get CI green again, but this requires more investigation. ## Changelog: [Internal] - Revert D69805065 Reviewed By: sammy-SC, huntie Differential Revision: D69920338 fbshipit-source-id: 8e1d34b5314d8ead51c127208ae2d2250f7d3724 --- .../featureflags/ReactNativeFeatureFlags.kt | 8 +--- .../ReactNativeFeatureFlagsCxxAccessor.kt | 12 +----- .../ReactNativeFeatureFlagsCxxInterop.kt | 4 +- .../ReactNativeFeatureFlagsDefaults.kt | 4 +- .../ReactNativeFeatureFlagsLocalAccessor.kt | 13 +------ .../ReactNativeFeatureFlagsProvider.kt | 4 +- .../JReactNativeFeatureFlagsCxxInterop.cpp | 16 +------- .../JReactNativeFeatureFlagsCxxInterop.h | 5 +-- .../featureflags/ReactNativeFeatureFlags.cpp | 6 +-- .../featureflags/ReactNativeFeatureFlags.h | 7 +--- .../ReactNativeFeatureFlagsAccessor.cpp | 38 +++++-------------- .../ReactNativeFeatureFlagsAccessor.h | 6 +-- .../ReactNativeFeatureFlagsDefaults.h | 6 +-- .../ReactNativeFeatureFlagsDynamicProvider.h | 11 +----- .../ReactNativeFeatureFlagsProvider.h | 3 +- .../ios/React-NativeModulesApple.podspec | 3 +- .../ios/ReactCommon/RCTTurboModuleManager.mm | 32 +--------------- .../NativeReactNativeFeatureFlags.cpp | 7 +--- .../NativeReactNativeFeatureFlags.h | 4 +- .../ReactCommon/RuntimeExecutor.cpp | 17 --------- .../ReactCommon/RuntimeExecutor.h | 14 ------- .../ReactNativeFeatureFlags.config.js | 11 ------ .../featureflags/ReactNativeFeatureFlags.js | 7 +--- .../specs/NativeReactNativeFeatureFlags.js | 3 +- 24 files changed, 31 insertions(+), 210 deletions(-) delete mode 100644 packages/react-native/ReactCommon/runtimeexecutor/ReactCommon/RuntimeExecutor.cpp diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index 9ea7bc27cef..80420f09774 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<99417ea22d1bf969d71388c600d42e85>> + * @generated SignedSource<<6e8144a48ab65f3b5ad8dd601cee2114>> */ /** @@ -226,12 +226,6 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun lazyAnimationCallbacks(): Boolean = accessor.lazyAnimationCallbacks() - /** - * Throw an exception instead of deadlocking when a TurboModule that requires main queue setup is initialized during a synchronous render on iOS. - */ - @JvmStatic - public fun throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS(): Boolean = accessor.throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS() - /** * Enables storing js caller stack when creating promise in native module. This is useful in case of Promise rejection and tracing the cause. */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index 5b8b2fe06c3..5d6b275337e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<3ede8912be1a2874050bab4c88a0a416>> + * @generated SignedSource<> */ /** @@ -53,7 +53,6 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var fuseboxEnabledReleaseCache: Boolean? = null private var fuseboxNetworkInspectionEnabledCache: Boolean? = null private var lazyAnimationCallbacksCache: Boolean? = null - private var throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOSCache: Boolean? = null private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null private var useEditTextStockAndroidFocusBehaviorCache: Boolean? = null @@ -361,15 +360,6 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } - override fun throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS(): Boolean { - var cached = throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOSCache - if (cached == null) { - cached = ReactNativeFeatureFlagsCxxInterop.throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS() - throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOSCache = cached - } - return cached - } - override fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean { var cached = traceTurboModulePromiseRejectionsOnAndroidCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index a38007ebfec..6c0b4b1ba40 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<33adb23bfdb99c531c674f4c6d09ddbd>> + * @generated SignedSource<> */ /** @@ -94,8 +94,6 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun lazyAnimationCallbacks(): Boolean - @DoNotStrip @JvmStatic public external fun throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS(): Boolean - @DoNotStrip @JvmStatic public external fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean @DoNotStrip @JvmStatic public external fun useAlwaysAvailableJSErrorHandling(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index ee69db5cab0..0ce19bf7171 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<94ffd31d788dae979b92c7a347f2ad40>> + * @generated SignedSource<<5315bd93234b8c00b7d029081231eeeb>> */ /** @@ -89,8 +89,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun lazyAnimationCallbacks(): Boolean = false - override fun throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS(): Boolean = false - override fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean = false override fun useAlwaysAvailableJSErrorHandling(): Boolean = false diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index aca0cdd4d21..5c212ccae04 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<15176fdf014740aa34039cfd82943ae2>> + * @generated SignedSource<> */ /** @@ -57,7 +57,6 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var fuseboxEnabledReleaseCache: Boolean? = null private var fuseboxNetworkInspectionEnabledCache: Boolean? = null private var lazyAnimationCallbacksCache: Boolean? = null - private var throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOSCache: Boolean? = null private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null private var useEditTextStockAndroidFocusBehaviorCache: Boolean? = null @@ -398,16 +397,6 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } - override fun throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS(): Boolean { - var cached = throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOSCache - if (cached == null) { - cached = currentProvider.throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS() - accessedFeatureFlags.add("throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS") - throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOSCache = cached - } - return cached - } - override fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean { var cached = traceTurboModulePromiseRejectionsOnAndroidCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index 6634920dac8..24d527c0899 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<98ad5281b51418af43620a89a40a3c45>> + * @generated SignedSource<<51121a77716b7748f993496eff5f6bfb>> */ /** @@ -89,8 +89,6 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun lazyAnimationCallbacks(): Boolean - @DoNotStrip public fun throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS(): Boolean - @DoNotStrip public fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean @DoNotStrip public fun useAlwaysAvailableJSErrorHandling(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index 92f40898540..8c5753cd10f 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -237,12 +237,6 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } - bool throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS() override { - static const auto method = - getReactNativeFeatureFlagsProviderJavaClass()->getMethod("throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS"); - return method(javaProvider_); - } - bool traceTurboModulePromiseRejectionsOnAndroid() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("traceTurboModulePromiseRejectionsOnAndroid"); @@ -466,11 +460,6 @@ bool JReactNativeFeatureFlagsCxxInterop::lazyAnimationCallbacks( return ReactNativeFeatureFlags::lazyAnimationCallbacks(); } -bool JReactNativeFeatureFlagsCxxInterop::throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS( - facebook::jni::alias_ref /*unused*/) { - return ReactNativeFeatureFlags::throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS(); -} - bool JReactNativeFeatureFlagsCxxInterop::traceTurboModulePromiseRejectionsOnAndroid( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::traceTurboModulePromiseRejectionsOnAndroid(); @@ -646,9 +635,6 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "lazyAnimationCallbacks", JReactNativeFeatureFlagsCxxInterop::lazyAnimationCallbacks), - makeNativeMethod( - "throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS", - JReactNativeFeatureFlagsCxxInterop::throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS), makeNativeMethod( "traceTurboModulePromiseRejectionsOnAndroid", JReactNativeFeatureFlagsCxxInterop::traceTurboModulePromiseRejectionsOnAndroid), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index f768b70716f..8e6ca51f366 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<0bf1c23eda1c41a60eaae19e87c541e9>> */ /** @@ -129,9 +129,6 @@ class JReactNativeFeatureFlagsCxxInterop static bool lazyAnimationCallbacks( facebook::jni::alias_ref); - static bool throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS( - facebook::jni::alias_ref); - static bool traceTurboModulePromiseRejectionsOnAndroid( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index d17a47dba8a..826a0e3f369 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<5ea68e0bf3cbf7822d7a3e80f7dffc72>> + * @generated SignedSource<<0a3119b99e455127d8a404963a23eb96>> */ /** @@ -158,10 +158,6 @@ bool ReactNativeFeatureFlags::lazyAnimationCallbacks() { return getAccessor().lazyAnimationCallbacks(); } -bool ReactNativeFeatureFlags::throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS() { - return getAccessor().throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS(); -} - bool ReactNativeFeatureFlags::traceTurboModulePromiseRejectionsOnAndroid() { return getAccessor().traceTurboModulePromiseRejectionsOnAndroid(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index ff9e9726f69..092ca0e553a 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<9be3692ca63703f32de54e24d4ceb6e9>> + * @generated SignedSource<> */ /** @@ -204,11 +204,6 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool lazyAnimationCallbacks(); - /** - * Throw an exception instead of deadlocking when a TurboModule that requires main queue setup is initialized during a synchronous render on iOS. - */ - RN_EXPORT static bool throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS(); - /** * Enables storing js caller stack when creating promise in native module. This is useful in case of Promise rejection and tracing the cause. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 67b9548d4f8..2fccefca4d4 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<12be545f9fb06b76cb6c521e1d381bf1>> + * @generated SignedSource<<41f3b407b98e268ba80f8cd8bb960321>> */ /** @@ -623,24 +623,6 @@ bool ReactNativeFeatureFlagsAccessor::lazyAnimationCallbacks() { return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS() { - auto flagValue = throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS_.load(); - - if (!flagValue.has_value()) { - // This block is not exclusive but it is not necessary. - // If multiple threads try to initialize the feature flag, we would only - // be accessing the provider multiple times but the end state of this - // instance and the returned flag value would be the same. - - markFlagAsAccessed(33, "throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS"); - - flagValue = currentProvider_->throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS(); - throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS_ = flagValue; - } - - return flagValue.value(); -} - bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid() { auto flagValue = traceTurboModulePromiseRejectionsOnAndroid_.load(); @@ -650,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(34, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(33, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -668,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(35, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(34, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -686,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::useEditTextStockAndroidFocusBehavior() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "useEditTextStockAndroidFocusBehavior"); + markFlagAsAccessed(35, "useEditTextStockAndroidFocusBehavior"); flagValue = currentProvider_->useEditTextStockAndroidFocusBehavior(); useEditTextStockAndroidFocusBehavior_ = flagValue; @@ -704,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "useFabricInterop"); + markFlagAsAccessed(36, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -722,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(38, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(37, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -740,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(39, "useOptimizedEventBatchingOnAndroid"); + markFlagAsAccessed(38, "useOptimizedEventBatchingOnAndroid"); flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid(); useOptimizedEventBatchingOnAndroid_ = flagValue; @@ -758,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "useRawPropsJsiValue"); + markFlagAsAccessed(39, "useRawPropsJsiValue"); flagValue = currentProvider_->useRawPropsJsiValue(); useRawPropsJsiValue_ = flagValue; @@ -776,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(41, "useTurboModuleInterop"); + markFlagAsAccessed(40, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -794,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModules() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(42, "useTurboModules"); + markFlagAsAccessed(41, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 013db19ef7a..80fcc077ae2 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<65caac2e749261ca919780dff302ef57>> + * @generated SignedSource<> */ /** @@ -65,7 +65,6 @@ class ReactNativeFeatureFlagsAccessor { bool fuseboxEnabledRelease(); bool fuseboxNetworkInspectionEnabled(); bool lazyAnimationCallbacks(); - bool throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS(); bool traceTurboModulePromiseRejectionsOnAndroid(); bool useAlwaysAvailableJSErrorHandling(); bool useEditTextStockAndroidFocusBehavior(); @@ -86,7 +85,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 43> accessedFeatureFlags_; + std::array, 42> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> disableMountItemReorderingAndroid_; @@ -121,7 +120,6 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> fuseboxEnabledRelease_; std::atomic> fuseboxNetworkInspectionEnabled_; std::atomic> lazyAnimationCallbacks_; - std::atomic> throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS_; std::atomic> traceTurboModulePromiseRejectionsOnAndroid_; std::atomic> useAlwaysAvailableJSErrorHandling_; std::atomic> useEditTextStockAndroidFocusBehavior_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 68e6ce11ef7..678b9169300 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<1ade51e6e5c82275c5c01b72df630eee>> */ /** @@ -159,10 +159,6 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } - bool throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS() override { - return false; - } - bool traceTurboModulePromiseRejectionsOnAndroid() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index afb4799d24a..d06ebfc72d0 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<95aa462c1a48b2299c2a82adf74c58df>> */ /** @@ -342,15 +342,6 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::lazyAnimationCallbacks(); } - bool throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS() override { - auto value = values_["throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS"]; - if (!value.isNull()) { - return value.getBool(); - } - - return ReactNativeFeatureFlagsDefaults::throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS(); - } - bool traceTurboModulePromiseRejectionsOnAndroid() override { auto value = values_["traceTurboModulePromiseRejectionsOnAndroid"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 3a88a248a7c..cd78fcef43c 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<716d5779133c4ee8c9d20e4a71065d59>> + * @generated SignedSource<> */ /** @@ -58,7 +58,6 @@ class ReactNativeFeatureFlagsProvider { virtual bool fuseboxEnabledRelease() = 0; virtual bool fuseboxNetworkInspectionEnabled() = 0; virtual bool lazyAnimationCallbacks() = 0; - virtual bool throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS() = 0; virtual bool traceTurboModulePromiseRejectionsOnAndroid() = 0; virtual bool useAlwaysAvailableJSErrorHandling() = 0; virtual bool useEditTextStockAndroidFocusBehavior() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/React-NativeModulesApple.podspec b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/React-NativeModulesApple.podspec index bdda78a7e2e..e9c20fba642 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/React-NativeModulesApple.podspec +++ b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/React-NativeModulesApple.podspec @@ -34,7 +34,7 @@ Pod::Spec.new do |s| s.platforms = min_supported_versions s.source = source s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags - s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fast_float/include\" \"$(PODS_ROOT)/fmt/include\" \"$(PODS_ROOT)/Headers/Private/React-Core\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-debug/React_featureflags.framework/Headers\"", + s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fast_float/include\" \"$(PODS_ROOT)/fmt/include\" \"$(PODS_ROOT)/Headers/Private/React-Core\"", "USE_HEADERMAP" => "YES", "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(), "GCC_WARN_PEDANTIC" => "YES" } @@ -51,7 +51,6 @@ Pod::Spec.new do |s| s.dependency "React-Core" s.dependency "React-cxxreact" s.dependency "React-jsi" - s.dependency "React-featureflags" s.dependency "React-runtimeexecutor" add_dependency(s, "React-jsinspector", :framework_name => 'jsinspector_modern') diff --git a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm index d97d5cd3714..4e873126642 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm +++ b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm @@ -29,11 +29,9 @@ #import #import #import -#import #import #import #import -#import using namespace facebook; using namespace facebook::react; @@ -576,35 +574,7 @@ typedef struct { }; if ([self _requiresMainQueueSetup:moduleClass]) { - if (ReactNativeFeatureFlags::throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS()) { - static int32_t modulesSettingUpOnMainQueueCount = 0; - bool needsUnlock = NO; - - // This function can be recursive. If it's called recursively, we need to skip the lock. - // We can't use a recursive mutex instead because the lock is needed on multiple threads. - if (modulesSettingUpOnMainQueueCount == 0) { - if (!facebook::react::getMainThreadMutex()->try_lock()) { - NSString *reason = [NSString - stringWithFormat: - @"TurboModule %@ which requires main queue setup is initializing during sync rendering. This would have caused a deadlock. Please fix this by avoiding main queue setup or eager initializing this TurboModule.", - NSStringFromClass(moduleClass)]; - NSException *exception = [NSException exceptionWithName:@"UnsafeTurboModuleException" - reason:reason - userInfo:nil]; - @throw exception; - } - needsUnlock = true; - } - modulesSettingUpOnMainQueueCount++; - RCTUnsafeExecuteOnMainQueueSync(work); - modulesSettingUpOnMainQueueCount--; - if (needsUnlock) { - facebook::react::getMainThreadMutex()->unlock(); - } - } else { - RCTUnsafeExecuteOnMainQueueSync(work); - } - + RCTUnsafeExecuteOnMainQueueSync(work); } else { work(); } diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index fd57f3c01b8..aef893b2de6 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<9a4f0e72b7e6518347f65253c018220a>> */ /** @@ -209,11 +209,6 @@ bool NativeReactNativeFeatureFlags::lazyAnimationCallbacks( return ReactNativeFeatureFlags::lazyAnimationCallbacks(); } -bool NativeReactNativeFeatureFlags::throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS( - jsi::Runtime& /*runtime*/) { - return ReactNativeFeatureFlags::throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS(); -} - bool NativeReactNativeFeatureFlags::traceTurboModulePromiseRejectionsOnAndroid( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::traceTurboModulePromiseRejectionsOnAndroid(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 055e6cfa93e..958e00099df 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<805e70470028c1a98ef49e6aaf18fd03>> + * @generated SignedSource<<16deece14930c9b259f6f7594127fe55>> */ /** @@ -103,8 +103,6 @@ class NativeReactNativeFeatureFlags bool lazyAnimationCallbacks(jsi::Runtime& runtime); - bool throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS(jsi::Runtime& runtime); - bool traceTurboModulePromiseRejectionsOnAndroid(jsi::Runtime& runtime); bool useAlwaysAvailableJSErrorHandling(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/runtimeexecutor/ReactCommon/RuntimeExecutor.cpp b/packages/react-native/ReactCommon/runtimeexecutor/ReactCommon/RuntimeExecutor.cpp deleted file mode 100644 index 3ebc8e1760d..00000000000 --- a/packages/react-native/ReactCommon/runtimeexecutor/ReactCommon/RuntimeExecutor.cpp +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include "RuntimeExecutor.h" - -namespace facebook::react { - -std::mutex* getMainThreadMutex() { - static std::mutex mainThreadMutex; - return &mainThreadMutex; -} - -} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/runtimeexecutor/ReactCommon/RuntimeExecutor.h b/packages/react-native/ReactCommon/runtimeexecutor/ReactCommon/RuntimeExecutor.h index 050b7940ce2..fe151954d52 100644 --- a/packages/react-native/ReactCommon/runtimeexecutor/ReactCommon/RuntimeExecutor.h +++ b/packages/react-native/ReactCommon/runtimeexecutor/ReactCommon/RuntimeExecutor.h @@ -14,8 +14,6 @@ namespace facebook::react { -std::mutex* getMainThreadMutex(); - /* * Takes a function and calls it with a reference to a Runtime. The function * will be called when it is safe to do so (i.e. it ensures non-concurrent @@ -33,16 +31,6 @@ using RuntimeExecutor = * Use this method when the caller needs to *be blocked* by executing the * `callback` and requires that the callback will be executed on the same * thread. - * Example order of events (when not a sync call in runtimeExecutor callback): - * - [UI thread] Lock all mutexes at start - * - [UI thread] mutex1.lock before callback - * - [JS thread] Set runtimePtr in runtimeExecutor callback - * - [JS thread] mutex1.unlock in runtimeExecutor callback - * - [UI thread] Call callback - * - [JS thread] mutex2.lock in runtimeExecutor callback - * - [UI thread] mutex2.unlock after callback - * - [UI thread] mutex3.lock after callback - * - [JS thread] mutex3.unlock in runtimeExecutor callback */ inline static void executeSynchronouslyOnSameThread_CAN_DEADLOCK( const RuntimeExecutor& runtimeExecutor, @@ -54,7 +42,6 @@ inline static void executeSynchronouslyOnSameThread_CAN_DEADLOCK( std::mutex mutex2; std::mutex mutex3; - getMainThreadMutex()->lock(); mutex1.lock(); mutex2.lock(); mutex3.lock(); @@ -83,7 +70,6 @@ inline static void executeSynchronouslyOnSameThread_CAN_DEADLOCK( callback(*runtimePtr); mutex2.unlock(); mutex3.lock(); - getMainThreadMutex()->unlock(); } template diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 2a6e552f9cf..98a1c661e01 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -398,17 +398,6 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, - throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS: { - defaultValue: false, - metadata: { - dateAdded: '2025-02-18', - description: - 'Throw an exception instead of deadlocking when a TurboModule that requires main queue setup is initialized during a synchronous render on iOS.', - expectedReleaseValue: true, - purpose: 'experimentation', - }, - ossReleaseStage: 'none', - }, traceTurboModulePromiseRejectionsOnAndroid: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 9378d65c35e..7810a833816 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<4bdedb6bbe2199cb99e72e86bfffe372>> * @flow strict */ @@ -82,7 +82,6 @@ export type ReactNativeFeatureFlags = $ReadOnly<{ fuseboxEnabledRelease: Getter, fuseboxNetworkInspectionEnabled: Getter, lazyAnimationCallbacks: Getter, - throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS: Getter, traceTurboModulePromiseRejectionsOnAndroid: Getter, useAlwaysAvailableJSErrorHandling: Getter, useEditTextStockAndroidFocusBehavior: Getter, @@ -305,10 +304,6 @@ export const fuseboxNetworkInspectionEnabled: Getter = createNativeFlag * Only enqueue Choreographer calls if there is an ongoing animation, instead of enqueueing every frame. */ export const lazyAnimationCallbacks: Getter = createNativeFlagGetter('lazyAnimationCallbacks', false); -/** - * Throw an exception instead of deadlocking when a TurboModule that requires main queue setup is initialized during a synchronous render on iOS. - */ -export const throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS: Getter = createNativeFlagGetter('throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS', false); /** * Enables storing js caller stack when creating promise in native module. This is useful in case of Promise rejection and tracing the cause. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index b9aa6ade897..82bbaeec6c9 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<06a03507366a38dfc43868e94d75fcf1>> * @flow strict */ @@ -57,7 +57,6 @@ export interface Spec extends TurboModule { +fuseboxEnabledRelease?: () => boolean; +fuseboxNetworkInspectionEnabled?: () => boolean; +lazyAnimationCallbacks?: () => boolean; - +throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS?: () => boolean; +traceTurboModulePromiseRejectionsOnAndroid?: () => boolean; +useAlwaysAvailableJSErrorHandling?: () => boolean; +useEditTextStockAndroidFocusBehavior?: () => boolean;