Skip to content

Commit dd12edf

Browse files
[0.81] Implement mechanism to prevent ShadowTree commit exhaustion (#52736)
* Implement mechanism to prevent ShadowTree commit exhaustion (#52645) Summary: Pull Request resolved: #52645 Changelog: [internal] This add a new feature flag to test a fix for #51870 Reviewed By: cortinico, sammy-SC Differential Revision: D78418504 fbshipit-source-id: 2792026b6936393d196fd1e3162f8b2c61a38ed6 * Fix incorrect locking and attempts check in ShadowTree experiment (#52681) Summary: Pull Request resolved: #52681 Changelog: [internal] In the original change I made in D78418504 / #52645 I made 2 mistakes: 1. Used a lock that would try to re-lock on itself without it being recursive (which would cause a deadlock). I didn't see that because when testing I didn't hit the case where we'd exhaust the options. 2. The `attemps` variable wasn't incremented, so we never left the loop in case of exhaustion. This propagates a flag to `tryCommit` to indicate we've already locked on the commitMutex_ so we don't need to lock again in that case and increases the counter, fixing the issue. Reviewed By: cortinico Differential Revision: D78497509 fbshipit-source-id: 546ccd0c84aed5416ce1aef47d79419b4fe06f66 * Rollout `preventShadowTreeCommitExhaustionWithLocking` in experimental (#52709) Summary: Pull Request resolved: #52709 We want to make user for folks in OSS to try `preventShadowTreeCommitExhaustionWithLocking`. Therefore I'm updating the OSS release channel for this flag to experimental. Changelog: [Internal] [Changed] - Rollout `preventShadowTreeCommitExhaustionWithLocking` in experimental Reviewed By: rubennorte Differential Revision: D78558655 fbshipit-source-id: 02a9d216c7b2f8f7bdc1340213f82b70c5692dc7 --------- Co-authored-by: Rubén Norte <[email protected]>
1 parent d61decc commit dd12edf

24 files changed

+193
-47
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<a4a7c66f4603fc6a56018aba12c942ee>>
7+
* @generated SignedSource<<f5f8c15a68610c9453d4085626effee2>>
88
*/
99

1010
/**
@@ -312,6 +312,12 @@ public object ReactNativeFeatureFlags {
312312
@JvmStatic
313313
public fun preparedTextCacheSize(): Double = accessor.preparedTextCacheSize()
314314

315+
/**
316+
* 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.
317+
*/
318+
@JvmStatic
319+
public fun preventShadowTreeCommitExhaustionWithLocking(): Boolean = accessor.preventShadowTreeCommitExhaustionWithLocking()
320+
315321
/**
316322
* Enables storing js caller stack when creating promise in native module. This is useful in case of Promise rejection and tracing the cause.
317323
*/

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<9b6d83d6ea0acbc13bce19d869699079>>
7+
* @generated SignedSource<<773ddcede573164ba82db671341ddc3f>>
88
*/
99

1010
/**
@@ -67,6 +67,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
6767
private var fuseboxNetworkInspectionEnabledCache: Boolean? = null
6868
private var hideOffscreenVirtualViewsOnIOSCache: Boolean? = null
6969
private var preparedTextCacheSizeCache: Double? = null
70+
private var preventShadowTreeCommitExhaustionWithLockingCache: Boolean? = null
7071
private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null
7172
private var updateRuntimeShadowNodeReferencesOnCommitCache: Boolean? = null
7273
private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null
@@ -502,6 +503,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
502503
return cached
503504
}
504505

506+
override fun preventShadowTreeCommitExhaustionWithLocking(): Boolean {
507+
var cached = preventShadowTreeCommitExhaustionWithLockingCache
508+
if (cached == null) {
509+
cached = ReactNativeFeatureFlagsCxxInterop.preventShadowTreeCommitExhaustionWithLocking()
510+
preventShadowTreeCommitExhaustionWithLockingCache = cached
511+
}
512+
return cached
513+
}
514+
505515
override fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean {
506516
var cached = traceTurboModulePromiseRejectionsOnAndroidCache
507517
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<75760457dea789ab0951d3a22be3341c>>
7+
* @generated SignedSource<<96fca46813d841eb7f4d043010513999>>
88
*/
99

1010
/**
@@ -122,6 +122,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
122122

123123
@DoNotStrip @JvmStatic public external fun preparedTextCacheSize(): Double
124124

125+
@DoNotStrip @JvmStatic public external fun preventShadowTreeCommitExhaustionWithLocking(): Boolean
126+
125127
@DoNotStrip @JvmStatic public external fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean
126128

127129
@DoNotStrip @JvmStatic public external fun updateRuntimeShadowNodeReferencesOnCommit(): Boolean

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<48fa8921cc2947a713974c9926e1d806>>
7+
* @generated SignedSource<<8ebd61411e0e0ac8c8b307cf803f1206>>
88
*/
99

1010
/**
@@ -117,6 +117,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
117117

118118
override fun preparedTextCacheSize(): Double = 200.0
119119

120+
override fun preventShadowTreeCommitExhaustionWithLocking(): Boolean = false
121+
120122
override fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean = false
121123

122124
override fun updateRuntimeShadowNodeReferencesOnCommit(): Boolean = false

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<356261385b837def94ac5a4ca7ffd05d>>
7+
* @generated SignedSource<<a7e62fa950e2716e664e7f6d30d4c941>>
88
*/
99

1010
/**
@@ -71,6 +71,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
7171
private var fuseboxNetworkInspectionEnabledCache: Boolean? = null
7272
private var hideOffscreenVirtualViewsOnIOSCache: Boolean? = null
7373
private var preparedTextCacheSizeCache: Double? = null
74+
private var preventShadowTreeCommitExhaustionWithLockingCache: Boolean? = null
7475
private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null
7576
private var updateRuntimeShadowNodeReferencesOnCommitCache: Boolean? = null
7677
private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null
@@ -553,6 +554,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
553554
return cached
554555
}
555556

557+
override fun preventShadowTreeCommitExhaustionWithLocking(): Boolean {
558+
var cached = preventShadowTreeCommitExhaustionWithLockingCache
559+
if (cached == null) {
560+
cached = currentProvider.preventShadowTreeCommitExhaustionWithLocking()
561+
accessedFeatureFlags.add("preventShadowTreeCommitExhaustionWithLocking")
562+
preventShadowTreeCommitExhaustionWithLockingCache = cached
563+
}
564+
return cached
565+
}
566+
556567
override fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean {
557568
var cached = traceTurboModulePromiseRejectionsOnAndroidCache
558569
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<c8b19934d19d6b4514a0395edecb1330>>
7+
* @generated SignedSource<<93aab733661b558c1701b728c18b3d00>>
88
*/
99

1010
/**
@@ -23,5 +23,5 @@ public open class ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android :
2323
// We could use JNI to get the defaults from C++,
2424
// but that is more expensive than just duplicating the defaults here.
2525

26-
26+
override fun preventShadowTreeCommitExhaustionWithLocking(): Boolean = true
2727
}

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<8abf9bfb81265ae0c840457eb6c199bd>>
7+
* @generated SignedSource<<f3b9aa1ed32aa3e013e16d4abb10b9cf>>
88
*/
99

1010
/**
@@ -117,6 +117,8 @@ public interface ReactNativeFeatureFlagsProvider {
117117

118118
@DoNotStrip public fun preparedTextCacheSize(): Double
119119

120+
@DoNotStrip public fun preventShadowTreeCommitExhaustionWithLocking(): Boolean
121+
120122
@DoNotStrip public fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean
121123

122124
@DoNotStrip public fun updateRuntimeShadowNodeReferencesOnCommit(): Boolean

packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<5effd7d4ac8034424144ea68c82b61a7>>
7+
* @generated SignedSource<<7fac1c2c0c3ce131442319925e4231dc>>
88
*/
99

1010
/**
@@ -321,6 +321,12 @@ class ReactNativeFeatureFlagsJavaProvider
321321
return method(javaProvider_);
322322
}
323323

324+
bool preventShadowTreeCommitExhaustionWithLocking() override {
325+
static const auto method =
326+
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("preventShadowTreeCommitExhaustionWithLocking");
327+
return method(javaProvider_);
328+
}
329+
324330
bool traceTurboModulePromiseRejectionsOnAndroid() override {
325331
static const auto method =
326332
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("traceTurboModulePromiseRejectionsOnAndroid");
@@ -626,6 +632,11 @@ double JReactNativeFeatureFlagsCxxInterop::preparedTextCacheSize(
626632
return ReactNativeFeatureFlags::preparedTextCacheSize();
627633
}
628634

635+
bool JReactNativeFeatureFlagsCxxInterop::preventShadowTreeCommitExhaustionWithLocking(
636+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
637+
return ReactNativeFeatureFlags::preventShadowTreeCommitExhaustionWithLocking();
638+
}
639+
629640
bool JReactNativeFeatureFlagsCxxInterop::traceTurboModulePromiseRejectionsOnAndroid(
630641
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
631642
return ReactNativeFeatureFlags::traceTurboModulePromiseRejectionsOnAndroid();
@@ -853,6 +864,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
853864
makeNativeMethod(
854865
"preparedTextCacheSize",
855866
JReactNativeFeatureFlagsCxxInterop::preparedTextCacheSize),
867+
makeNativeMethod(
868+
"preventShadowTreeCommitExhaustionWithLocking",
869+
JReactNativeFeatureFlagsCxxInterop::preventShadowTreeCommitExhaustionWithLocking),
856870
makeNativeMethod(
857871
"traceTurboModulePromiseRejectionsOnAndroid",
858872
JReactNativeFeatureFlagsCxxInterop::traceTurboModulePromiseRejectionsOnAndroid),

packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<f7bf09b9287dc649901b99ca3f250c28>>
7+
* @generated SignedSource<<07daae0284829d56b7eaa330b1973e02>>
88
*/
99

1010
/**
@@ -171,6 +171,9 @@ class JReactNativeFeatureFlagsCxxInterop
171171
static double preparedTextCacheSize(
172172
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
173173

174+
static bool preventShadowTreeCommitExhaustionWithLocking(
175+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
176+
174177
static bool traceTurboModulePromiseRejectionsOnAndroid(
175178
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
176179

packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<20c25bf5541e37cd5c918684925726df>>
7+
* @generated SignedSource<<0179ba45718903d6fec6dcc19b0e1aaa>>
88
*/
99

1010
/**
@@ -214,6 +214,10 @@ double ReactNativeFeatureFlags::preparedTextCacheSize() {
214214
return getAccessor().preparedTextCacheSize();
215215
}
216216

217+
bool ReactNativeFeatureFlags::preventShadowTreeCommitExhaustionWithLocking() {
218+
return getAccessor().preventShadowTreeCommitExhaustionWithLocking();
219+
}
220+
217221
bool ReactNativeFeatureFlags::traceTurboModulePromiseRejectionsOnAndroid() {
218222
return getAccessor().traceTurboModulePromiseRejectionsOnAndroid();
219223
}

0 commit comments

Comments
 (0)