mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
[0.81] Clean up feature flag preventShadowTreeCommitExhaustionWithLocking (#52862)
* Clean up feature flag preventShadowTreeCommitExhaustionWithLocking (#52791) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/52791 Changelog: [internal] This cleans up this feature flag as it doesn't work as intended. We'll try another approach with a different flag instead. Reviewed By: sammy-SC Differential Revision: D78815892 fbshipit-source-id: 4c651a3a225de9cfb54d00346343c7f2e3bea1d5 * Implement solution for ShadowTree commmit exhaustion using recursive locks (behind a flag) (#52795) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/52795 Changelog: [internal] This is another attempt to fix https://github.com/facebook/react-native/issues/51870, inspired by https://github.com/facebook/react-native/pull/52314 but gated behind a feature flag until we've tested it carefully. Reviewed By: sammy-SC Differential Revision: D78817100 fbshipit-source-id: 45e6cae019b212528f2b2e74b9f52fe43d07f537 * [LOCAL] Correctly sort preventShadowTreeCommitExhaustion after merge conflict --------- Co-authored-by: Rubén Norte <rubennorte@meta.com>
This commit is contained in:
co-authored by
Rubén Norte
parent
5f3d297eec
commit
cb20a1cd32
+2
-2
@@ -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<<f5f8c15a68610c9453d4085626effee2>>
|
||||
* @generated SignedSource<<3e4d74a17c15742d35db9e4247f3e1c1>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -316,7 +316,7 @@ public object ReactNativeFeatureFlags {
|
||||
* Enables a new mechanism in ShadowTree to prevent problems caused by multiple threads trying to commit concurrently. If a thread tries to commit a few times unsuccessfully, it will acquire a lock and try again.
|
||||
*/
|
||||
@JvmStatic
|
||||
public fun preventShadowTreeCommitExhaustionWithLocking(): Boolean = accessor.preventShadowTreeCommitExhaustionWithLocking()
|
||||
public fun preventShadowTreeCommitExhaustion(): Boolean = accessor.preventShadowTreeCommitExhaustion()
|
||||
|
||||
/**
|
||||
* Enables storing js caller stack when creating promise in native module. This is useful in case of Promise rejection and tracing the cause.
|
||||
|
||||
+6
-6
@@ -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<<773ddcede573164ba82db671341ddc3f>>
|
||||
* @generated SignedSource<<e7c1c6d184681d98320aac2a23c06288>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -67,7 +67,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
|
||||
private var fuseboxNetworkInspectionEnabledCache: Boolean? = null
|
||||
private var hideOffscreenVirtualViewsOnIOSCache: Boolean? = null
|
||||
private var preparedTextCacheSizeCache: Double? = null
|
||||
private var preventShadowTreeCommitExhaustionWithLockingCache: Boolean? = null
|
||||
private var preventShadowTreeCommitExhaustionCache: Boolean? = null
|
||||
private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null
|
||||
private var updateRuntimeShadowNodeReferencesOnCommitCache: Boolean? = null
|
||||
private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null
|
||||
@@ -503,11 +503,11 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun preventShadowTreeCommitExhaustionWithLocking(): Boolean {
|
||||
var cached = preventShadowTreeCommitExhaustionWithLockingCache
|
||||
override fun preventShadowTreeCommitExhaustion(): Boolean {
|
||||
var cached = preventShadowTreeCommitExhaustionCache
|
||||
if (cached == null) {
|
||||
cached = ReactNativeFeatureFlagsCxxInterop.preventShadowTreeCommitExhaustionWithLocking()
|
||||
preventShadowTreeCommitExhaustionWithLockingCache = cached
|
||||
cached = ReactNativeFeatureFlagsCxxInterop.preventShadowTreeCommitExhaustion()
|
||||
preventShadowTreeCommitExhaustionCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
+2
-2
@@ -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<<96fca46813d841eb7f4d043010513999>>
|
||||
* @generated SignedSource<<ba62d616188ed439c85c66cfd055810d>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -122,7 +122,7 @@ public object ReactNativeFeatureFlagsCxxInterop {
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun preparedTextCacheSize(): Double
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun preventShadowTreeCommitExhaustionWithLocking(): Boolean
|
||||
@DoNotStrip @JvmStatic public external fun preventShadowTreeCommitExhaustion(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean
|
||||
|
||||
|
||||
+2
-2
@@ -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<<8ebd61411e0e0ac8c8b307cf803f1206>>
|
||||
* @generated SignedSource<<12c2727291b635ef7c3163d153669c2c>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -117,7 +117,7 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
|
||||
|
||||
override fun preparedTextCacheSize(): Double = 200.0
|
||||
|
||||
override fun preventShadowTreeCommitExhaustionWithLocking(): Boolean = false
|
||||
override fun preventShadowTreeCommitExhaustion(): Boolean = false
|
||||
|
||||
override fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean = false
|
||||
|
||||
|
||||
+7
-7
@@ -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<<a7e62fa950e2716e664e7f6d30d4c941>>
|
||||
* @generated SignedSource<<3ea9946ef21c8ac8bb9bb63712636e89>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -71,7 +71,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
|
||||
private var fuseboxNetworkInspectionEnabledCache: Boolean? = null
|
||||
private var hideOffscreenVirtualViewsOnIOSCache: Boolean? = null
|
||||
private var preparedTextCacheSizeCache: Double? = null
|
||||
private var preventShadowTreeCommitExhaustionWithLockingCache: Boolean? = null
|
||||
private var preventShadowTreeCommitExhaustionCache: Boolean? = null
|
||||
private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null
|
||||
private var updateRuntimeShadowNodeReferencesOnCommitCache: Boolean? = null
|
||||
private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null
|
||||
@@ -554,12 +554,12 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun preventShadowTreeCommitExhaustionWithLocking(): Boolean {
|
||||
var cached = preventShadowTreeCommitExhaustionWithLockingCache
|
||||
override fun preventShadowTreeCommitExhaustion(): Boolean {
|
||||
var cached = preventShadowTreeCommitExhaustionCache
|
||||
if (cached == null) {
|
||||
cached = currentProvider.preventShadowTreeCommitExhaustionWithLocking()
|
||||
accessedFeatureFlags.add("preventShadowTreeCommitExhaustionWithLocking")
|
||||
preventShadowTreeCommitExhaustionWithLockingCache = cached
|
||||
cached = currentProvider.preventShadowTreeCommitExhaustion()
|
||||
accessedFeatureFlags.add("preventShadowTreeCommitExhaustion")
|
||||
preventShadowTreeCommitExhaustionCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
+2
-2
@@ -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<<93aab733661b558c1701b728c18b3d00>>
|
||||
* @generated SignedSource<<58da46268043f086730132430735b720>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -23,5 +23,5 @@ public open class ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android :
|
||||
// We could use JNI to get the defaults from C++,
|
||||
// but that is more expensive than just duplicating the defaults here.
|
||||
|
||||
override fun preventShadowTreeCommitExhaustionWithLocking(): Boolean = true
|
||||
override fun preventShadowTreeCommitExhaustion(): Boolean = true
|
||||
}
|
||||
|
||||
+2
-2
@@ -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<<f3b9aa1ed32aa3e013e16d4abb10b9cf>>
|
||||
* @generated SignedSource<<1e81de36735c6c9286b228c75c9a0228>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -117,7 +117,7 @@ public interface ReactNativeFeatureFlagsProvider {
|
||||
|
||||
@DoNotStrip public fun preparedTextCacheSize(): Double
|
||||
|
||||
@DoNotStrip public fun preventShadowTreeCommitExhaustionWithLocking(): Boolean
|
||||
@DoNotStrip public fun preventShadowTreeCommitExhaustion(): Boolean
|
||||
|
||||
@DoNotStrip public fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean
|
||||
|
||||
|
||||
+7
-7
@@ -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<<7fac1c2c0c3ce131442319925e4231dc>>
|
||||
* @generated SignedSource<<cf7b6ff66c614ca2acc6667a80c5590d>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -321,9 +321,9 @@ class ReactNativeFeatureFlagsJavaProvider
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool preventShadowTreeCommitExhaustionWithLocking() override {
|
||||
bool preventShadowTreeCommitExhaustion() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("preventShadowTreeCommitExhaustionWithLocking");
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("preventShadowTreeCommitExhaustion");
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
@@ -632,9 +632,9 @@ double JReactNativeFeatureFlagsCxxInterop::preparedTextCacheSize(
|
||||
return ReactNativeFeatureFlags::preparedTextCacheSize();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::preventShadowTreeCommitExhaustionWithLocking(
|
||||
bool JReactNativeFeatureFlagsCxxInterop::preventShadowTreeCommitExhaustion(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::preventShadowTreeCommitExhaustionWithLocking();
|
||||
return ReactNativeFeatureFlags::preventShadowTreeCommitExhaustion();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::traceTurboModulePromiseRejectionsOnAndroid(
|
||||
@@ -865,8 +865,8 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
|
||||
"preparedTextCacheSize",
|
||||
JReactNativeFeatureFlagsCxxInterop::preparedTextCacheSize),
|
||||
makeNativeMethod(
|
||||
"preventShadowTreeCommitExhaustionWithLocking",
|
||||
JReactNativeFeatureFlagsCxxInterop::preventShadowTreeCommitExhaustionWithLocking),
|
||||
"preventShadowTreeCommitExhaustion",
|
||||
JReactNativeFeatureFlagsCxxInterop::preventShadowTreeCommitExhaustion),
|
||||
makeNativeMethod(
|
||||
"traceTurboModulePromiseRejectionsOnAndroid",
|
||||
JReactNativeFeatureFlagsCxxInterop::traceTurboModulePromiseRejectionsOnAndroid),
|
||||
|
||||
+2
-2
@@ -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<<07daae0284829d56b7eaa330b1973e02>>
|
||||
* @generated SignedSource<<dae981c66bf0751fd2863937ecf255d8>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -171,7 +171,7 @@ class JReactNativeFeatureFlagsCxxInterop
|
||||
static double preparedTextCacheSize(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool preventShadowTreeCommitExhaustionWithLocking(
|
||||
static bool preventShadowTreeCommitExhaustion(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool traceTurboModulePromiseRejectionsOnAndroid(
|
||||
|
||||
@@ -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<<0179ba45718903d6fec6dcc19b0e1aaa>>
|
||||
* @generated SignedSource<<f73bbcd926a835c09b70d814c6662dbb>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -214,8 +214,8 @@ double ReactNativeFeatureFlags::preparedTextCacheSize() {
|
||||
return getAccessor().preparedTextCacheSize();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlags::preventShadowTreeCommitExhaustionWithLocking() {
|
||||
return getAccessor().preventShadowTreeCommitExhaustionWithLocking();
|
||||
bool ReactNativeFeatureFlags::preventShadowTreeCommitExhaustion() {
|
||||
return getAccessor().preventShadowTreeCommitExhaustion();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlags::traceTurboModulePromiseRejectionsOnAndroid() {
|
||||
|
||||
@@ -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<<5055890d2cb2fb46a940f8308f014f0b>>
|
||||
* @generated SignedSource<<da14545268455bfd4cd35e5c2ecf81ee>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -277,7 +277,7 @@ class ReactNativeFeatureFlags {
|
||||
/**
|
||||
* Enables a new mechanism in ShadowTree to prevent problems caused by multiple threads trying to commit concurrently. If a thread tries to commit a few times unsuccessfully, it will acquire a lock and try again.
|
||||
*/
|
||||
RN_EXPORT static bool preventShadowTreeCommitExhaustionWithLocking();
|
||||
RN_EXPORT static bool preventShadowTreeCommitExhaustion();
|
||||
|
||||
/**
|
||||
* Enables storing js caller stack when creating promise in native module. This is useful in case of Promise rejection and tracing the cause.
|
||||
|
||||
+6
-6
@@ -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<<ea72f787f16b0c96ad745e82067591a9>>
|
||||
* @generated SignedSource<<681bff71eb87886a108f67b3162b030c>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -875,8 +875,8 @@ double ReactNativeFeatureFlagsAccessor::preparedTextCacheSize() {
|
||||
return flagValue.value();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlagsAccessor::preventShadowTreeCommitExhaustionWithLocking() {
|
||||
auto flagValue = preventShadowTreeCommitExhaustionWithLocking_.load();
|
||||
bool ReactNativeFeatureFlagsAccessor::preventShadowTreeCommitExhaustion() {
|
||||
auto flagValue = preventShadowTreeCommitExhaustion_.load();
|
||||
|
||||
if (!flagValue.has_value()) {
|
||||
// This block is not exclusive but it is not necessary.
|
||||
@@ -884,10 +884,10 @@ bool ReactNativeFeatureFlagsAccessor::preventShadowTreeCommitExhaustionWithLocki
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(47, "preventShadowTreeCommitExhaustionWithLocking");
|
||||
markFlagAsAccessed(47, "preventShadowTreeCommitExhaustion");
|
||||
|
||||
flagValue = currentProvider_->preventShadowTreeCommitExhaustionWithLocking();
|
||||
preventShadowTreeCommitExhaustionWithLocking_ = flagValue;
|
||||
flagValue = currentProvider_->preventShadowTreeCommitExhaustion();
|
||||
preventShadowTreeCommitExhaustion_ = flagValue;
|
||||
}
|
||||
|
||||
return flagValue.value();
|
||||
|
||||
+3
-3
@@ -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<<5ed90d5ed1a03a16f551cd1cf6cbdeb3>>
|
||||
* @generated SignedSource<<e5a8a196b35c010d92d3f616979891a9>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -79,7 +79,7 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
bool fuseboxNetworkInspectionEnabled();
|
||||
bool hideOffscreenVirtualViewsOnIOS();
|
||||
double preparedTextCacheSize();
|
||||
bool preventShadowTreeCommitExhaustionWithLocking();
|
||||
bool preventShadowTreeCommitExhaustion();
|
||||
bool traceTurboModulePromiseRejectionsOnAndroid();
|
||||
bool updateRuntimeShadowNodeReferencesOnCommit();
|
||||
bool useAlwaysAvailableJSErrorHandling();
|
||||
@@ -151,7 +151,7 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
std::atomic<std::optional<bool>> fuseboxNetworkInspectionEnabled_;
|
||||
std::atomic<std::optional<bool>> hideOffscreenVirtualViewsOnIOS_;
|
||||
std::atomic<std::optional<double>> preparedTextCacheSize_;
|
||||
std::atomic<std::optional<bool>> preventShadowTreeCommitExhaustionWithLocking_;
|
||||
std::atomic<std::optional<bool>> preventShadowTreeCommitExhaustion_;
|
||||
std::atomic<std::optional<bool>> traceTurboModulePromiseRejectionsOnAndroid_;
|
||||
std::atomic<std::optional<bool>> updateRuntimeShadowNodeReferencesOnCommit_;
|
||||
std::atomic<std::optional<bool>> useAlwaysAvailableJSErrorHandling_;
|
||||
|
||||
+2
-2
@@ -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<<d9fdce0b92313eff37d7146d25b80d4a>>
|
||||
* @generated SignedSource<<9832c18e4c7ccf232b7222e2356f99d9>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -215,7 +215,7 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
|
||||
return 200.0;
|
||||
}
|
||||
|
||||
bool preventShadowTreeCommitExhaustionWithLocking() override {
|
||||
bool preventShadowTreeCommitExhaustion() override {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -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<<ae01d3b37b41ff2ef7fdc26977954b7e>>
|
||||
* @generated SignedSource<<19f0a48bcfa8f8ffaf634e85301adc7e>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -468,13 +468,13 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef
|
||||
return ReactNativeFeatureFlagsDefaults::preparedTextCacheSize();
|
||||
}
|
||||
|
||||
bool preventShadowTreeCommitExhaustionWithLocking() override {
|
||||
auto value = values_["preventShadowTreeCommitExhaustionWithLocking"];
|
||||
bool preventShadowTreeCommitExhaustion() override {
|
||||
auto value = values_["preventShadowTreeCommitExhaustion"];
|
||||
if (!value.isNull()) {
|
||||
return value.getBool();
|
||||
}
|
||||
|
||||
return ReactNativeFeatureFlagsDefaults::preventShadowTreeCommitExhaustionWithLocking();
|
||||
return ReactNativeFeatureFlagsDefaults::preventShadowTreeCommitExhaustion();
|
||||
}
|
||||
|
||||
bool traceTurboModulePromiseRejectionsOnAndroid() override {
|
||||
|
||||
+2
-2
@@ -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<<16c5fdf431579bbfd454a28c06f28c41>>
|
||||
* @generated SignedSource<<f33ea0f19a27ec6124d8dbf1a043b4ce>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -27,7 +27,7 @@ class ReactNativeFeatureFlagsOverridesOSSExperimental : public ReactNativeFeatur
|
||||
public:
|
||||
ReactNativeFeatureFlagsOverridesOSSExperimental() = default;
|
||||
|
||||
bool preventShadowTreeCommitExhaustionWithLocking() override {
|
||||
bool preventShadowTreeCommitExhaustion() override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
+2
-2
@@ -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<<bf06b42a9dfc43a3bfe4e8e59587ea71>>
|
||||
* @generated SignedSource<<815769cc8d08e19b2598dd1862ed5060>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -72,7 +72,7 @@ class ReactNativeFeatureFlagsProvider {
|
||||
virtual bool fuseboxNetworkInspectionEnabled() = 0;
|
||||
virtual bool hideOffscreenVirtualViewsOnIOS() = 0;
|
||||
virtual double preparedTextCacheSize() = 0;
|
||||
virtual bool preventShadowTreeCommitExhaustionWithLocking() = 0;
|
||||
virtual bool preventShadowTreeCommitExhaustion() = 0;
|
||||
virtual bool traceTurboModulePromiseRejectionsOnAndroid() = 0;
|
||||
virtual bool updateRuntimeShadowNodeReferencesOnCommit() = 0;
|
||||
virtual bool useAlwaysAvailableJSErrorHandling() = 0;
|
||||
|
||||
+3
-3
@@ -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<<b6c1cb535484fe2a5ff839ca2a9ece46>>
|
||||
* @generated SignedSource<<474a64af739969acebb4bb9bb1005168>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -279,9 +279,9 @@ double NativeReactNativeFeatureFlags::preparedTextCacheSize(
|
||||
return ReactNativeFeatureFlags::preparedTextCacheSize();
|
||||
}
|
||||
|
||||
bool NativeReactNativeFeatureFlags::preventShadowTreeCommitExhaustionWithLocking(
|
||||
bool NativeReactNativeFeatureFlags::preventShadowTreeCommitExhaustion(
|
||||
jsi::Runtime& /*runtime*/) {
|
||||
return ReactNativeFeatureFlags::preventShadowTreeCommitExhaustionWithLocking();
|
||||
return ReactNativeFeatureFlags::preventShadowTreeCommitExhaustion();
|
||||
}
|
||||
|
||||
bool NativeReactNativeFeatureFlags::traceTurboModulePromiseRejectionsOnAndroid(
|
||||
|
||||
+2
-2
@@ -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<<03ab35c55476b69046e67235b66533a0>>
|
||||
* @generated SignedSource<<bfaa3cc7ab3eeff306337b06b7ae978a>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -130,7 +130,7 @@ class NativeReactNativeFeatureFlags
|
||||
|
||||
double preparedTextCacheSize(jsi::Runtime& runtime);
|
||||
|
||||
bool preventShadowTreeCommitExhaustionWithLocking(jsi::Runtime& runtime);
|
||||
bool preventShadowTreeCommitExhaustion(jsi::Runtime& runtime);
|
||||
|
||||
bool traceTurboModulePromiseRejectionsOnAndroid(jsi::Runtime& runtime);
|
||||
|
||||
|
||||
@@ -22,12 +22,12 @@
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
using CommitStatus = ShadowTree::CommitStatus;
|
||||
using CommitMode = ShadowTree::CommitMode;
|
||||
|
||||
namespace {
|
||||
const int MAX_COMMIT_ATTEMPTS_BEFORE_LOCKING = 3;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
using CommitStatus = ShadowTree::CommitStatus;
|
||||
using CommitMode = ShadowTree::CommitMode;
|
||||
|
||||
/*
|
||||
* Generates (possibly) a new tree where all nodes with non-obsolete `State`
|
||||
@@ -214,7 +214,8 @@ void ShadowTree::setCommitMode(CommitMode commitMode) const {
|
||||
auto revision = ShadowTreeRevision{};
|
||||
|
||||
{
|
||||
std::unique_lock lock(commitMutex_);
|
||||
ShadowTree::UniqueLock lock = uniqueCommitLock();
|
||||
|
||||
if (commitMode_ == commitMode) {
|
||||
return;
|
||||
}
|
||||
@@ -231,7 +232,7 @@ void ShadowTree::setCommitMode(CommitMode commitMode) const {
|
||||
}
|
||||
|
||||
CommitMode ShadowTree::getCommitMode() const {
|
||||
std::shared_lock lock(commitMutex_);
|
||||
SharedLock lock = sharedCommitLock();
|
||||
return commitMode_;
|
||||
}
|
||||
|
||||
@@ -245,7 +246,7 @@ CommitStatus ShadowTree::commit(
|
||||
const CommitOptions& commitOptions) const {
|
||||
[[maybe_unused]] int attempts = 0;
|
||||
|
||||
if (ReactNativeFeatureFlags::preventShadowTreeCommitExhaustionWithLocking()) {
|
||||
if (ReactNativeFeatureFlags::preventShadowTreeCommitExhaustion()) {
|
||||
while (attempts < MAX_COMMIT_ATTEMPTS_BEFORE_LOCKING) {
|
||||
auto status = tryCommit(transaction, commitOptions);
|
||||
if (status != CommitStatus::Failed) {
|
||||
@@ -255,8 +256,8 @@ CommitStatus ShadowTree::commit(
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_lock lock(commitMutex_);
|
||||
return tryCommit(transaction, commitOptions, true);
|
||||
std::unique_lock lock(commitMutexRecursive_);
|
||||
return tryCommit(transaction, commitOptions);
|
||||
}
|
||||
} else {
|
||||
while (true) {
|
||||
@@ -276,8 +277,7 @@ CommitStatus ShadowTree::commit(
|
||||
|
||||
CommitStatus ShadowTree::tryCommit(
|
||||
const ShadowTreeCommitTransaction& transaction,
|
||||
const CommitOptions& commitOptions,
|
||||
bool hasLocked) const {
|
||||
const CommitOptions& commitOptions) const {
|
||||
TraceSection s("ShadowTree::commit");
|
||||
|
||||
auto telemetry = TransactionTelemetry{};
|
||||
@@ -289,10 +289,7 @@ CommitStatus ShadowTree::tryCommit(
|
||||
|
||||
{
|
||||
// Reading `currentRevision_` in shared manner.
|
||||
std::shared_lock lock(commitMutex_, std::defer_lock);
|
||||
if (!hasLocked) {
|
||||
lock.lock();
|
||||
}
|
||||
SharedLock lock = sharedCommitLock();
|
||||
commitMode = commitMode_;
|
||||
oldRevision = currentRevision_;
|
||||
}
|
||||
@@ -333,10 +330,7 @@ CommitStatus ShadowTree::tryCommit(
|
||||
|
||||
{
|
||||
// Updating `currentRevision_` in unique manner if it hasn't changed.
|
||||
std::unique_lock lock(commitMutex_, std::defer_lock);
|
||||
if (!hasLocked) {
|
||||
lock.lock();
|
||||
}
|
||||
UniqueLock lock = uniqueCommitLock();
|
||||
|
||||
if (currentRevision_.number != oldRevision.number) {
|
||||
return CommitStatus::Failed;
|
||||
@@ -375,7 +369,7 @@ CommitStatus ShadowTree::tryCommit(
|
||||
}
|
||||
|
||||
ShadowTreeRevision ShadowTree::getCurrentRevision() const {
|
||||
std::shared_lock lock(commitMutex_);
|
||||
SharedLock lock = sharedCommitLock();
|
||||
return currentRevision_;
|
||||
}
|
||||
|
||||
@@ -423,4 +417,20 @@ void ShadowTree::notifyDelegatesOfUpdates() const {
|
||||
delegate_.shadowTreeDidFinishTransaction(mountingCoordinator_, true);
|
||||
}
|
||||
|
||||
inline ShadowTree::UniqueLock ShadowTree::uniqueCommitLock() const {
|
||||
if (ReactNativeFeatureFlags::preventShadowTreeCommitExhaustion()) {
|
||||
return std::unique_lock{commitMutexRecursive_};
|
||||
} else {
|
||||
return std::unique_lock{commitMutex_};
|
||||
}
|
||||
}
|
||||
|
||||
inline ShadowTree::SharedLock ShadowTree::sharedCommitLock() const {
|
||||
if (ReactNativeFeatureFlags::preventShadowTreeCommitExhaustion()) {
|
||||
return std::unique_lock{commitMutexRecursive_};
|
||||
} else {
|
||||
return std::shared_lock{commitMutex_};
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
|
||||
#include <react/renderer/components/root/RootShadowNode.h>
|
||||
#include <react/renderer/core/LayoutConstraints.h>
|
||||
@@ -111,8 +113,7 @@ class ShadowTree final {
|
||||
*/
|
||||
CommitStatus tryCommit(
|
||||
const ShadowTreeCommitTransaction& transaction,
|
||||
const CommitOptions& commitOptions,
|
||||
bool hasLocked = false) const;
|
||||
const CommitOptions& commitOptions) const;
|
||||
|
||||
/*
|
||||
* Calls `tryCommit` in a loop until it finishes successfully.
|
||||
@@ -151,10 +152,21 @@ class ShadowTree final {
|
||||
const SurfaceId surfaceId_;
|
||||
const ShadowTreeDelegate& delegate_;
|
||||
mutable std::shared_mutex commitMutex_;
|
||||
mutable std::recursive_mutex commitMutexRecursive_;
|
||||
mutable CommitMode commitMode_{
|
||||
CommitMode::Normal}; // Protected by `commitMutex_`.
|
||||
mutable ShadowTreeRevision currentRevision_; // Protected by `commitMutex_`.
|
||||
std::shared_ptr<const MountingCoordinator> mountingCoordinator_;
|
||||
|
||||
using UniqueLock = std::variant<
|
||||
std::unique_lock<std::shared_mutex>,
|
||||
std::unique_lock<std::recursive_mutex>>;
|
||||
using SharedLock = std::variant<
|
||||
std::shared_lock<std::shared_mutex>,
|
||||
std::unique_lock<std::recursive_mutex>>;
|
||||
|
||||
inline UniqueLock uniqueCommitLock() const;
|
||||
inline SharedLock sharedCommitLock() const;
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
@@ -543,10 +543,10 @@ const definitions: FeatureFlagDefinitions = {
|
||||
},
|
||||
ossReleaseStage: 'none',
|
||||
},
|
||||
preventShadowTreeCommitExhaustionWithLocking: {
|
||||
preventShadowTreeCommitExhaustion: {
|
||||
defaultValue: false,
|
||||
metadata: {
|
||||
dateAdded: '2025-07-14',
|
||||
dateAdded: '2025-07-23',
|
||||
description:
|
||||
'Enables a new mechanism in ShadowTree to prevent problems caused by multiple threads trying to commit concurrently. If a thread tries to commit a few times unsuccessfully, it will acquire a lock and try again.',
|
||||
expectedReleaseValue: true,
|
||||
|
||||
@@ -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<<595a51e39658c12aab12032f7b928615>>
|
||||
* @generated SignedSource<<999a8d329cdab258ac64c03b24f1a516>>
|
||||
* @flow strict
|
||||
* @noformat
|
||||
*/
|
||||
@@ -98,7 +98,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{
|
||||
fuseboxNetworkInspectionEnabled: Getter<boolean>,
|
||||
hideOffscreenVirtualViewsOnIOS: Getter<boolean>,
|
||||
preparedTextCacheSize: Getter<number>,
|
||||
preventShadowTreeCommitExhaustionWithLocking: Getter<boolean>,
|
||||
preventShadowTreeCommitExhaustion: Getter<boolean>,
|
||||
traceTurboModulePromiseRejectionsOnAndroid: Getter<boolean>,
|
||||
updateRuntimeShadowNodeReferencesOnCommit: Getter<boolean>,
|
||||
useAlwaysAvailableJSErrorHandling: Getter<boolean>,
|
||||
@@ -387,7 +387,7 @@ export const preparedTextCacheSize: Getter<number> = createNativeFlagGetter('pre
|
||||
/**
|
||||
* Enables a new mechanism in ShadowTree to prevent problems caused by multiple threads trying to commit concurrently. If a thread tries to commit a few times unsuccessfully, it will acquire a lock and try again.
|
||||
*/
|
||||
export const preventShadowTreeCommitExhaustionWithLocking: Getter<boolean> = createNativeFlagGetter('preventShadowTreeCommitExhaustionWithLocking', false);
|
||||
export const preventShadowTreeCommitExhaustion: Getter<boolean> = createNativeFlagGetter('preventShadowTreeCommitExhaustion', false);
|
||||
/**
|
||||
* Enables storing js caller stack when creating promise in native module. This is useful in case of Promise rejection and tracing the cause.
|
||||
*/
|
||||
|
||||
+2
-2
@@ -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<<9d6574da819c190bed0458559c66a089>>
|
||||
* @generated SignedSource<<1b84b6e04c214f6c2798010372937990>>
|
||||
* @flow strict
|
||||
* @noformat
|
||||
*/
|
||||
@@ -72,7 +72,7 @@ export interface Spec extends TurboModule {
|
||||
+fuseboxNetworkInspectionEnabled?: () => boolean;
|
||||
+hideOffscreenVirtualViewsOnIOS?: () => boolean;
|
||||
+preparedTextCacheSize?: () => number;
|
||||
+preventShadowTreeCommitExhaustionWithLocking?: () => boolean;
|
||||
+preventShadowTreeCommitExhaustion?: () => boolean;
|
||||
+traceTurboModulePromiseRejectionsOnAndroid?: () => boolean;
|
||||
+updateRuntimeShadowNodeReferencesOnCommit?: () => boolean;
|
||||
+useAlwaysAvailableJSErrorHandling?: () => boolean;
|
||||
|
||||
Reference in New Issue
Block a user