delete background executor (#45110)

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

changelog: [internal]

Reviewed By: fkgozali, javache

Differential Revision: D58737295

fbshipit-source-id: 1f644b910e07a27cffb9107502aefd9b382d8f93
This commit is contained in:
Samuel Susla
2024-07-10 04:28:22 -07:00
committed by Facebook GitHub Bot
parent 082706ccd4
commit 8f98c58d38
32 changed files with 52 additions and 378 deletions
@@ -43,33 +43,6 @@
using namespace facebook;
using namespace facebook::react;
static dispatch_queue_t RCTGetBackgroundQueue()
{
static dispatch_queue_t queue;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dispatch_queue_attr_t attr =
dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INTERACTIVE, 0);
queue = dispatch_queue_create("com.facebook.react.background", attr);
});
return queue;
}
static BackgroundExecutor RCTGetBackgroundExecutor()
{
return [](std::function<void()> &&callback) {
if (RCTIsMainQueue()) {
callback();
return;
}
auto copyableCallback = callback;
dispatch_async(RCTGetBackgroundQueue(), ^{
copyableCallback();
});
};
}
@interface RCTSurfacePresenter () <RCTSchedulerDelegate, RCTMountingManagerDelegate>
@end
@@ -288,10 +261,6 @@ static BackgroundExecutor RCTGetBackgroundExecutor()
toolbox.runtimeExecutor = runtimeExecutor;
toolbox.bridgelessBindingsExecutor = _bridgelessBindingsExecutor;
if (ReactNativeFeatureFlags::enableBackgroundExecutor()) {
toolbox.backgroundExecutor = RCTGetBackgroundExecutor();
}
toolbox.asynchronousEventBeatFactory =
[runtimeExecutor](const EventBeat::SharedOwnerBox &ownerBox) -> std::unique_ptr<EventBeat> {
auto runLoopObserver =
@@ -534,9 +534,6 @@ public class com/facebook/react/bridge/AssertionException : java/lang/RuntimeExc
public fun <init> (Ljava/lang/String;)V
}
public class com/facebook/react/bridge/BackgroundExecutor {
}
public class com/facebook/react/bridge/BaseActivityEventListener : com/facebook/react/bridge/ActivityEventListener {
public fun <init> ()V
public fun onActivityResult (IILandroid/content/Intent;)V
@@ -1,64 +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.
*/
package com.facebook.react.bridge;
import com.facebook.proguard.annotations.DoNotStrip;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
@DoNotStrip
public class BackgroundExecutor {
private static final String TAG = "FabricBackgroundExecutor";
private static class NamedThreadFactory implements ThreadFactory {
private final String mName;
public NamedThreadFactory(String name) {
mName = name;
}
@Override
public Thread newThread(Runnable r) {
Thread thread = Executors.defaultThreadFactory().newThread(r);
thread.setName(mName);
return thread;
}
}
private final ExecutorService mExecutorService;
@DoNotStrip
private BackgroundExecutor(String name) {
mExecutorService = Executors.newFixedThreadPool(1, new NamedThreadFactory(name));
}
@DoNotStrip
private void queueRunnable(Runnable runnable) {
// Very rarely, an NPE is hit here - probably has to do with deallocation
// race conditions and the JNI.
// It's not clear yet which of these is most prevalent, or if either is a concern.
// If we don't find these logs in production then we can probably safely remove the logging,
// but it's also cheap to leave it here.
if (runnable == null) {
ReactSoftExceptionLogger.logSoftException(
TAG, new ReactNoCrashSoftException("runnable is null"));
return;
}
final ExecutorService executorService = mExecutorService;
if (executorService == null) {
ReactSoftExceptionLogger.logSoftException(
TAG, new ReactNoCrashSoftException("executorService is null"));
return;
}
executorService.execute(runnable);
}
}
@@ -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<<9e8a8beb3d769dbf5067ea8f7f7e083a>>
* @generated SignedSource<<e7aaf58d91c8e25685f2a3ec5ca171a9>>
*/
/**
@@ -58,12 +58,6 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun destroyFabricSurfacesInReactInstanceManager(): Boolean = accessor.destroyFabricSurfacesInReactInstanceManager()
/**
* Enables the use of a background executor to compute layout and commit updates on Fabric (this system is deprecated and should not be used).
*/
@JvmStatic
public fun enableBackgroundExecutor(): Boolean = accessor.enableBackgroundExecutor()
/**
* Clean yoga node when <TextInput /> does not change.
*/
@@ -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<<42c6f880b8d84f9c7b232f8ea392eed2>>
* @generated SignedSource<<bd5baae4bc2e8a619f99dea15766e803>>
*/
/**
@@ -25,7 +25,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
private var allowRecursiveCommitsWithSynchronousMountOnAndroidCache: Boolean? = null
private var batchRenderingUpdatesInEventLoopCache: Boolean? = null
private var destroyFabricSurfacesInReactInstanceManagerCache: Boolean? = null
private var enableBackgroundExecutorCache: Boolean? = null
private var enableCleanTextInputYogaNodeCache: Boolean? = null
private var enableGranularShadowTreeStateReconciliationCache: Boolean? = null
private var enableMicrotasksCache: Boolean? = null
@@ -94,15 +93,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
return cached
}
override fun enableBackgroundExecutor(): Boolean {
var cached = enableBackgroundExecutorCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.enableBackgroundExecutor()
enableBackgroundExecutorCache = cached
}
return cached
}
override fun enableCleanTextInputYogaNode(): Boolean {
var cached = enableCleanTextInputYogaNodeCache
if (cached == null) {
@@ -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<<46dae6ea607040efd2fc55f7ef3594df>>
* @generated SignedSource<<317e652e32f680ed7cfa4989a8133dad>>
*/
/**
@@ -38,8 +38,6 @@ public object ReactNativeFeatureFlagsCxxInterop {
@DoNotStrip @JvmStatic public external fun destroyFabricSurfacesInReactInstanceManager(): Boolean
@DoNotStrip @JvmStatic public external fun enableBackgroundExecutor(): Boolean
@DoNotStrip @JvmStatic public external fun enableCleanTextInputYogaNode(): Boolean
@DoNotStrip @JvmStatic public external fun enableGranularShadowTreeStateReconciliation(): Boolean
@@ -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<<eeaa1e6cd97dd1dd4de7ee498ce6c30a>>
* @generated SignedSource<<9821cf51f5220e5a6e121044d024e1e6>>
*/
/**
@@ -33,8 +33,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
override fun destroyFabricSurfacesInReactInstanceManager(): Boolean = false
override fun enableBackgroundExecutor(): Boolean = false
override fun enableCleanTextInputYogaNode(): Boolean = false
override fun enableGranularShadowTreeStateReconciliation(): Boolean = false
@@ -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<<5d4631b6ae53f2bb2cfc44bad2f05980>>
* @generated SignedSource<<1f61054f14a12ed03d8ee5f32221ec1f>>
*/
/**
@@ -29,7 +29,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
private var allowRecursiveCommitsWithSynchronousMountOnAndroidCache: Boolean? = null
private var batchRenderingUpdatesInEventLoopCache: Boolean? = null
private var destroyFabricSurfacesInReactInstanceManagerCache: Boolean? = null
private var enableBackgroundExecutorCache: Boolean? = null
private var enableCleanTextInputYogaNodeCache: Boolean? = null
private var enableGranularShadowTreeStateReconciliationCache: Boolean? = null
private var enableMicrotasksCache: Boolean? = null
@@ -103,16 +102,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
return cached
}
override fun enableBackgroundExecutor(): Boolean {
var cached = enableBackgroundExecutorCache
if (cached == null) {
cached = currentProvider.enableBackgroundExecutor()
accessedFeatureFlags.add("enableBackgroundExecutor")
enableBackgroundExecutorCache = cached
}
return cached
}
override fun enableCleanTextInputYogaNode(): Boolean {
var cached = enableCleanTextInputYogaNodeCache
if (cached == null) {
@@ -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<<53a55d7cae6f18a4192f28a6f44b0c3b>>
* @generated SignedSource<<a3ee4e4eae374959d5211897be02b983>>
*/
/**
@@ -33,8 +33,6 @@ public interface ReactNativeFeatureFlagsProvider {
@DoNotStrip public fun destroyFabricSurfacesInReactInstanceManager(): Boolean
@DoNotStrip public fun enableBackgroundExecutor(): Boolean
@DoNotStrip public fun enableCleanTextInputYogaNode(): Boolean
@DoNotStrip public fun enableGranularShadowTreeStateReconciliation(): Boolean
@@ -12,7 +12,6 @@
#include "EventBeatManager.h"
#include "EventEmitterWrapper.h"
#include "FabricMountingManager.h"
#include "JBackgroundExecutor.h"
#include "ReactNativeConfigHolder.h"
#include "SurfaceHandlerBinding.h"
@@ -416,11 +415,6 @@ void Binding::installFabricUIManager(
toolbox.asynchronousEventBeatFactory = asynchronousBeatFactory;
if (ReactNativeFeatureFlags::enableBackgroundExecutor()) {
backgroundExecutor_ = JBackgroundExecutor::create("fabric_bg");
toolbox.backgroundExecutor = backgroundExecutor_;
}
animationDriver_ = std::make_shared<LayoutAnimationDriver>(
runtimeExecutor, contextContainer, this);
scheduler_ =
@@ -1,28 +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 "JBackgroundExecutor.h"
#include <fbjni/NativeRunnable.h>
#include <fbjni/fbjni.h>
namespace facebook::react {
using namespace facebook::jni;
BackgroundExecutor JBackgroundExecutor::create(const std::string& name) {
auto instance = make_global(newInstance(name));
return [instance = std::move(instance)](std::function<void()>&& runnable) {
static auto method =
javaClassStatic()->getMethod<void(JRunnable::javaobject)>(
"queueRunnable");
auto jrunnable = JNativeRunnable::newObjectCxxArgs(std::move(runnable));
method(instance, jrunnable.get());
};
}
} // namespace facebook::react
@@ -1,23 +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.
*/
#pragma once
#include <fbjni/fbjni.h>
#include <react/renderer/uimanager/primitives.h>
namespace facebook::react {
class JBackgroundExecutor : public jni::JavaClass<JBackgroundExecutor> {
public:
static auto constexpr kJavaDescriptor =
"Lcom/facebook/react/bridge/BackgroundExecutor;";
static BackgroundExecutor create(const std::string& name);
};
} // namespace facebook::react
@@ -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<<9eee86e80b454c80ba6c64efe2a5fcac>>
* @generated SignedSource<<03c48c7281afa746734af581d6a17aa3>>
*/
/**
@@ -69,12 +69,6 @@ class ReactNativeFeatureFlagsProviderHolder
return method(javaProvider_);
}
bool enableBackgroundExecutor() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableBackgroundExecutor");
return method(javaProvider_);
}
bool enableCleanTextInputYogaNode() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableCleanTextInputYogaNode");
@@ -236,11 +230,6 @@ bool JReactNativeFeatureFlagsCxxInterop::destroyFabricSurfacesInReactInstanceMan
return ReactNativeFeatureFlags::destroyFabricSurfacesInReactInstanceManager();
}
bool JReactNativeFeatureFlagsCxxInterop::enableBackgroundExecutor(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableBackgroundExecutor();
}
bool JReactNativeFeatureFlagsCxxInterop::enableCleanTextInputYogaNode(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableCleanTextInputYogaNode();
@@ -383,9 +372,6 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"destroyFabricSurfacesInReactInstanceManager",
JReactNativeFeatureFlagsCxxInterop::destroyFabricSurfacesInReactInstanceManager),
makeNativeMethod(
"enableBackgroundExecutor",
JReactNativeFeatureFlagsCxxInterop::enableBackgroundExecutor),
makeNativeMethod(
"enableCleanTextInputYogaNode",
JReactNativeFeatureFlagsCxxInterop::enableCleanTextInputYogaNode),
@@ -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<<7702364bf684f25181e821004dba5383>>
* @generated SignedSource<<37f8ec65fb26fc58260a5846ab933098>>
*/
/**
@@ -45,9 +45,6 @@ class JReactNativeFeatureFlagsCxxInterop
static bool destroyFabricSurfacesInReactInstanceManager(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool enableBackgroundExecutor(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool enableCleanTextInputYogaNode(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
@@ -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<<8cf29c249e71cc9b2890fafc9c548f99>>
* @generated SignedSource<<8943825039460c1a95d0fdb6113f42e6>>
*/
/**
@@ -41,10 +41,6 @@ bool ReactNativeFeatureFlags::destroyFabricSurfacesInReactInstanceManager() {
return getAccessor().destroyFabricSurfacesInReactInstanceManager();
}
bool ReactNativeFeatureFlags::enableBackgroundExecutor() {
return getAccessor().enableBackgroundExecutor();
}
bool ReactNativeFeatureFlags::enableCleanTextInputYogaNode() {
return getAccessor().enableCleanTextInputYogaNode();
}
@@ -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<<ee2d7923b7407f81c25368750ccd06fe>>
* @generated SignedSource<<241d9d028d103ce587a886521af41fa8>>
*/
/**
@@ -62,11 +62,6 @@ class ReactNativeFeatureFlags {
*/
RN_EXPORT static bool destroyFabricSurfacesInReactInstanceManager();
/**
* Enables the use of a background executor to compute layout and commit updates on Fabric (this system is deprecated and should not be used).
*/
RN_EXPORT static bool enableBackgroundExecutor();
/**
* Clean yoga node when <TextInput /> does not change.
*/
@@ -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<<3ed39da69d501fb7a5fa5d8f88462302>>
* @generated SignedSource<<aae133e9640a2794af28f95ef357c1b0>>
*/
/**
@@ -119,24 +119,6 @@ bool ReactNativeFeatureFlagsAccessor::destroyFabricSurfacesInReactInstanceManage
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::enableBackgroundExecutor() {
auto flagValue = enableBackgroundExecutor_.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(5, "enableBackgroundExecutor");
flagValue = currentProvider_->enableBackgroundExecutor();
enableBackgroundExecutor_ = flagValue;
}
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::enableCleanTextInputYogaNode() {
auto flagValue = enableCleanTextInputYogaNode_.load();
@@ -146,7 +128,7 @@ bool ReactNativeFeatureFlagsAccessor::enableCleanTextInputYogaNode() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(6, "enableCleanTextInputYogaNode");
markFlagAsAccessed(5, "enableCleanTextInputYogaNode");
flagValue = currentProvider_->enableCleanTextInputYogaNode();
enableCleanTextInputYogaNode_ = flagValue;
@@ -164,7 +146,7 @@ bool ReactNativeFeatureFlagsAccessor::enableGranularShadowTreeStateReconciliatio
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(7, "enableGranularShadowTreeStateReconciliation");
markFlagAsAccessed(6, "enableGranularShadowTreeStateReconciliation");
flagValue = currentProvider_->enableGranularShadowTreeStateReconciliation();
enableGranularShadowTreeStateReconciliation_ = flagValue;
@@ -182,7 +164,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMicrotasks() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(8, "enableMicrotasks");
markFlagAsAccessed(7, "enableMicrotasks");
flagValue = currentProvider_->enableMicrotasks();
enableMicrotasks_ = flagValue;
@@ -200,7 +182,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSynchronousStateUpdates() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(9, "enableSynchronousStateUpdates");
markFlagAsAccessed(8, "enableSynchronousStateUpdates");
flagValue = currentProvider_->enableSynchronousStateUpdates();
enableSynchronousStateUpdates_ = flagValue;
@@ -218,7 +200,7 @@ bool ReactNativeFeatureFlagsAccessor::enableUIConsistency() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(10, "enableUIConsistency");
markFlagAsAccessed(9, "enableUIConsistency");
flagValue = currentProvider_->enableUIConsistency();
enableUIConsistency_ = flagValue;
@@ -236,7 +218,7 @@ bool ReactNativeFeatureFlagsAccessor::fetchImagesInViewPreallocation() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(11, "fetchImagesInViewPreallocation");
markFlagAsAccessed(10, "fetchImagesInViewPreallocation");
flagValue = currentProvider_->fetchImagesInViewPreallocation();
fetchImagesInViewPreallocation_ = flagValue;
@@ -254,7 +236,7 @@ bool ReactNativeFeatureFlagsAccessor::fixIncorrectScrollViewStateUpdateOnAndroid
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(12, "fixIncorrectScrollViewStateUpdateOnAndroid");
markFlagAsAccessed(11, "fixIncorrectScrollViewStateUpdateOnAndroid");
flagValue = currentProvider_->fixIncorrectScrollViewStateUpdateOnAndroid();
fixIncorrectScrollViewStateUpdateOnAndroid_ = flagValue;
@@ -272,7 +254,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(13, "fixMappingOfEventPrioritiesBetweenFabricAndReact");
markFlagAsAccessed(12, "fixMappingOfEventPrioritiesBetweenFabricAndReact");
flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact();
fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue;
@@ -290,7 +272,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMissedFabricStateUpdatesOnAndroid() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(14, "fixMissedFabricStateUpdatesOnAndroid");
markFlagAsAccessed(13, "fixMissedFabricStateUpdatesOnAndroid");
flagValue = currentProvider_->fixMissedFabricStateUpdatesOnAndroid();
fixMissedFabricStateUpdatesOnAndroid_ = flagValue;
@@ -308,7 +290,7 @@ bool ReactNativeFeatureFlagsAccessor::fixStoppedSurfaceRemoveDeleteTreeUIFrameCa
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(15, "fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak");
markFlagAsAccessed(14, "fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak");
flagValue = currentProvider_->fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak();
fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak_ = flagValue;
@@ -326,7 +308,7 @@ bool ReactNativeFeatureFlagsAccessor::forceBatchingMountItemsOnAndroid() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(16, "forceBatchingMountItemsOnAndroid");
markFlagAsAccessed(15, "forceBatchingMountItemsOnAndroid");
flagValue = currentProvider_->forceBatchingMountItemsOnAndroid();
forceBatchingMountItemsOnAndroid_ = flagValue;
@@ -344,7 +326,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledDebug() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(17, "fuseboxEnabledDebug");
markFlagAsAccessed(16, "fuseboxEnabledDebug");
flagValue = currentProvider_->fuseboxEnabledDebug();
fuseboxEnabledDebug_ = flagValue;
@@ -362,7 +344,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(18, "fuseboxEnabledRelease");
markFlagAsAccessed(17, "fuseboxEnabledRelease");
flagValue = currentProvider_->fuseboxEnabledRelease();
fuseboxEnabledRelease_ = flagValue;
@@ -380,7 +362,7 @@ bool ReactNativeFeatureFlagsAccessor::lazyAnimationCallbacks() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(19, "lazyAnimationCallbacks");
markFlagAsAccessed(18, "lazyAnimationCallbacks");
flagValue = currentProvider_->lazyAnimationCallbacks();
lazyAnimationCallbacks_ = flagValue;
@@ -398,7 +380,7 @@ bool ReactNativeFeatureFlagsAccessor::preventDoubleTextMeasure() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(20, "preventDoubleTextMeasure");
markFlagAsAccessed(19, "preventDoubleTextMeasure");
flagValue = currentProvider_->preventDoubleTextMeasure();
preventDoubleTextMeasure_ = flagValue;
@@ -416,7 +398,7 @@ bool ReactNativeFeatureFlagsAccessor::setAndroidLayoutDirection() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(21, "setAndroidLayoutDirection");
markFlagAsAccessed(20, "setAndroidLayoutDirection");
flagValue = currentProvider_->setAndroidLayoutDirection();
setAndroidLayoutDirection_ = flagValue;
@@ -434,7 +416,7 @@ bool ReactNativeFeatureFlagsAccessor::useImmediateExecutorInAndroidBridgeless()
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(22, "useImmediateExecutorInAndroidBridgeless");
markFlagAsAccessed(21, "useImmediateExecutorInAndroidBridgeless");
flagValue = currentProvider_->useImmediateExecutorInAndroidBridgeless();
useImmediateExecutorInAndroidBridgeless_ = flagValue;
@@ -452,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::useModernRuntimeScheduler() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(23, "useModernRuntimeScheduler");
markFlagAsAccessed(22, "useModernRuntimeScheduler");
flagValue = currentProvider_->useModernRuntimeScheduler();
useModernRuntimeScheduler_ = flagValue;
@@ -470,7 +452,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(24, "useNativeViewConfigsInBridgelessMode");
markFlagAsAccessed(23, "useNativeViewConfigsInBridgelessMode");
flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode();
useNativeViewConfigsInBridgelessMode_ = flagValue;
@@ -488,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdate() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(25, "useRuntimeShadowNodeReferenceUpdate");
markFlagAsAccessed(24, "useRuntimeShadowNodeReferenceUpdate");
flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdate();
useRuntimeShadowNodeReferenceUpdate_ = flagValue;
@@ -506,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdateOnLayou
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(26, "useRuntimeShadowNodeReferenceUpdateOnLayout");
markFlagAsAccessed(25, "useRuntimeShadowNodeReferenceUpdateOnLayout");
flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdateOnLayout();
useRuntimeShadowNodeReferenceUpdateOnLayout_ = flagValue;
@@ -524,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::useStateAlignmentMechanism() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(27, "useStateAlignmentMechanism");
markFlagAsAccessed(26, "useStateAlignmentMechanism");
flagValue = currentProvider_->useStateAlignmentMechanism();
useStateAlignmentMechanism_ = flagValue;
@@ -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<<c18adec4842a4dba2aeb6a1c7cea89ff>>
* @generated SignedSource<<8457544cbbdc11e26d6b0aeff95a77d7>>
*/
/**
@@ -36,7 +36,6 @@ class ReactNativeFeatureFlagsAccessor {
bool allowRecursiveCommitsWithSynchronousMountOnAndroid();
bool batchRenderingUpdatesInEventLoop();
bool destroyFabricSurfacesInReactInstanceManager();
bool enableBackgroundExecutor();
bool enableCleanTextInputYogaNode();
bool enableGranularShadowTreeStateReconciliation();
bool enableMicrotasks();
@@ -69,14 +68,13 @@ class ReactNativeFeatureFlagsAccessor {
std::unique_ptr<ReactNativeFeatureFlagsProvider> currentProvider_;
bool wasOverridden_;
std::array<std::atomic<const char*>, 28> accessedFeatureFlags_;
std::array<std::atomic<const char*>, 27> accessedFeatureFlags_;
std::atomic<std::optional<bool>> commonTestFlag_;
std::atomic<std::optional<bool>> allowCollapsableChildren_;
std::atomic<std::optional<bool>> allowRecursiveCommitsWithSynchronousMountOnAndroid_;
std::atomic<std::optional<bool>> batchRenderingUpdatesInEventLoop_;
std::atomic<std::optional<bool>> destroyFabricSurfacesInReactInstanceManager_;
std::atomic<std::optional<bool>> enableBackgroundExecutor_;
std::atomic<std::optional<bool>> enableCleanTextInputYogaNode_;
std::atomic<std::optional<bool>> enableGranularShadowTreeStateReconciliation_;
std::atomic<std::optional<bool>> enableMicrotasks_;
@@ -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<<c1afc0d636e9f14d300f3dcaa736fc19>>
* @generated SignedSource<<ff7cf1b21321c180c2a5d8bdb81a85bc>>
*/
/**
@@ -47,10 +47,6 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
return false;
}
bool enableBackgroundExecutor() override {
return false;
}
bool enableCleanTextInputYogaNode() override {
return false;
}
@@ -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<<b9f9a760a88ac81dfc4800af3d677bdd>>
* @generated SignedSource<<e2955fd37121ad6512c0c51e3c8555e6>>
*/
/**
@@ -30,7 +30,6 @@ class ReactNativeFeatureFlagsProvider {
virtual bool allowRecursiveCommitsWithSynchronousMountOnAndroid() = 0;
virtual bool batchRenderingUpdatesInEventLoop() = 0;
virtual bool destroyFabricSurfacesInReactInstanceManager() = 0;
virtual bool enableBackgroundExecutor() = 0;
virtual bool enableCleanTextInputYogaNode() = 0;
virtual bool enableGranularShadowTreeStateReconciliation() = 0;
virtual bool enableMicrotasks() = 0;
@@ -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<<b3f6cda1d6c647053de5b55c47aa05ba>>
* @generated SignedSource<<3d3e82742a1ab405f385ec1d4716b744>>
*/
/**
@@ -62,11 +62,6 @@ bool NativeReactNativeFeatureFlags::destroyFabricSurfacesInReactInstanceManager(
return ReactNativeFeatureFlags::destroyFabricSurfacesInReactInstanceManager();
}
bool NativeReactNativeFeatureFlags::enableBackgroundExecutor(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::enableBackgroundExecutor();
}
bool NativeReactNativeFeatureFlags::enableCleanTextInputYogaNode(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::enableCleanTextInputYogaNode();
@@ -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<<10d4e36c2d21fb327828ab46fbcad6c2>>
* @generated SignedSource<<a483015b2f4c8fe6c5f3e1c10e275a1f>>
*/
/**
@@ -45,8 +45,6 @@ class NativeReactNativeFeatureFlags
bool destroyFabricSurfacesInReactInstanceManager(jsi::Runtime& runtime);
bool enableBackgroundExecutor(jsi::Runtime& runtime);
bool enableCleanTextInputYogaNode(jsi::Runtime& runtime);
bool enableGranularShadowTreeStateReconciliation(jsi::Runtime& runtime);
@@ -58,17 +58,6 @@ void NativeMutationObserver::connect(
SyncCallback<jsi::Value(jsi::Value)> getPublicInstanceFromInstanceHandle) {
auto& uiManager = getUIManagerFromRuntime(runtime);
// MutationObserver is not compatible with background executor.
// When using background executor, we commit trees outside the JS thread.
// In that case, we can't safely access the JS runtime in commit hooks to
// get references to mutated nodes (which we need to do at that point
// to ensure we are retaining removed nodes).
if (uiManager.hasBackgroundExecutor()) {
throw jsi::JSError(
runtime,
"MutationObserver: could not start observation because MutationObserver is incompatible with UIManager using background executor.");
}
runtime_ = &runtime;
notifyMutationObservers_.emplace(std::move(notifyMutationObservers));
getPublicInstanceFromInstanceHandle_.emplace(
@@ -51,8 +51,8 @@ Scheduler::Scheduler(
eventPerformanceLogger_ =
std::make_shared<EventPerformanceLogger>(performanceEntryReporter_);
auto uiManager = std::make_shared<UIManager>(
runtimeExecutor_, schedulerToolbox.backgroundExecutor, contextContainer_);
auto uiManager =
std::make_shared<UIManager>(runtimeExecutor_, contextContainer_);
auto eventOwnerBox = std::make_shared<EventBeat::OwnerBox>();
eventOwnerBox->owner = eventDispatcher_;
@@ -55,16 +55,6 @@ struct SchedulerToolbox final {
*/
EventBeat::Factory asynchronousEventBeatFactory;
/*
* General-purpose executor that is used to dispatch work on some utility
* queue (mostly) asynchronously to avoid unnecessary blocking the caller
* queue.
* The concrete implementation can use a serial or concurrent queue.
* Due to architectural constraints, the concrete implementation *must* call
* the call back synchronously if the executor is invoked on the main thread.
*/
BackgroundExecutor backgroundExecutor;
/*
* A list of `UIManagerCommitHook`s that should be registered in `UIManager`.
*/
@@ -44,11 +44,9 @@ ShadowNodeListWrapper::~ShadowNodeListWrapper() = default;
UIManager::UIManager(
const RuntimeExecutor& runtimeExecutor,
BackgroundExecutor backgroundExecutor,
ContextContainer::Shared contextContainer)
: runtimeExecutor_(runtimeExecutor),
shadowTreeRegistry_(),
backgroundExecutor_(std::move(backgroundExecutor)),
contextContainer_(std::move(contextContainer)),
leakChecker_(constructLeakCheckerIfNeeded(runtimeExecutor)),
lazyShadowTreeRevisionConsistencyManager_(
@@ -41,7 +41,6 @@ class UIManager final : public ShadowTreeDelegate {
public:
UIManager(
const RuntimeExecutor& runtimeExecutor,
BackgroundExecutor backgroundExecutor,
ContextContainer::Shared contextContainer);
~UIManager() override;
@@ -199,10 +198,6 @@ class UIManager final : public ShadowTreeDelegate {
void reportMount(SurfaceId surfaceId) const;
bool hasBackgroundExecutor() const {
return backgroundExecutor_ != nullptr;
}
private:
friend class UIManagerBinding;
friend class Scheduler;
@@ -227,7 +222,6 @@ class UIManager final : public ShadowTreeDelegate {
UIManagerAnimationDelegate* animationDelegate_{nullptr};
const RuntimeExecutor runtimeExecutor_{};
ShadowTreeRegistry shadowTreeRegistry_{};
const BackgroundExecutor backgroundExecutor_{};
ContextContainer::Shared contextContainer_;
mutable std::shared_mutex commitHookMutex_;
@@ -488,14 +488,11 @@ jsi::Value UIManagerBinding::get(
if (methodName == "completeRoot") {
auto paramCount = 2;
std::weak_ptr<UIManager> weakUIManager = uiManager_;
// Enhanced version of the method that uses `backgroundExecutor` and
// captures a shared pointer to `UIManager`.
return jsi::Function::createFromHostFunction(
runtime,
name,
paramCount,
[weakUIManager, uiManager, methodName, paramCount](
[uiManager, methodName, paramCount](
jsi::Runtime& runtime,
const jsi::Value& /*thisValue*/,
const jsi::Value* arguments,
@@ -506,47 +503,13 @@ jsi::Value UIManagerBinding::get(
RuntimeSchedulerBinding::getBinding(runtime);
auto surfaceId = surfaceIdFromValue(runtime, arguments[0]);
if (uiManager->backgroundExecutor_) {
auto weakShadowNodeList =
weakShadowNodeListFromValue(runtime, arguments[1]);
static std::atomic_uint_fast8_t completeRootEventCounter{0};
static std::atomic_uint_fast32_t mostRecentSurfaceId{0};
completeRootEventCounter += 1;
mostRecentSurfaceId = surfaceId;
uiManager->backgroundExecutor_(
[weakUIManager,
weakShadowNodeList,
surfaceId,
eventCount = completeRootEventCounter.load()] {
auto shouldYield = [=]() -> bool {
// If `completeRootEventCounter` was incremented, another
// `completeSurface` call has been scheduled and current
// `completeSurface` should yield to it.
return completeRootEventCounter > eventCount &&
mostRecentSurfaceId == surfaceId;
};
auto shadowNodeList =
shadowNodeListFromWeakList(weakShadowNodeList);
auto strongUIManager = weakUIManager.lock();
if (shadowNodeList && strongUIManager) {
strongUIManager->completeSurface(
surfaceId,
shadowNodeList,
{.enableStateReconciliation = true,
.mountSynchronously = false,
.shouldYield = shouldYield});
}
});
} else {
auto shadowNodeList =
shadowNodeListFromValue(runtime, arguments[1]);
uiManager->completeSurface(
surfaceId,
shadowNodeList,
{.enableStateReconciliation = true,
.mountSynchronously = false,
.shouldYield = nullptr});
}
auto shadowNodeList = shadowNodeListFromValue(runtime, arguments[1]);
uiManager->completeSurface(
surfaceId,
shadowNodeList,
{.enableStateReconciliation = true,
.mountSynchronously = false,
.shouldYield = nullptr});
return jsi::Value::undefined();
});
@@ -58,10 +58,7 @@ class PointerEventsProcessorTest : public ::testing::Test {
// tests)
RuntimeExecutor runtimeExecutor =
[](std::function<void(facebook::jsi::Runtime & runtime)>&& callback) {};
BackgroundExecutor backgroundExecutor =
[](std::function<void()>&& callback) {};
uiManager_ = std::make_unique<UIManager>(
runtimeExecutor, backgroundExecutor, contextContainer);
uiManager_ = std::make_unique<UIManager>(runtimeExecutor, contextContainer);
uiManager_->setComponentDescriptorRegistry(componentDescriptorRegistry);
// Create a hierarchy of nodes
@@ -59,11 +59,6 @@ const definitions: FeatureFlagDefinitions = {
description:
'When enabled, ReactInstanceManager will clean up Fabric surfaces on destroy().',
},
enableBackgroundExecutor: {
defaultValue: false,
description:
'Enables the use of a background executor to compute layout and commit updates on Fabric (this system is deprecated and should not be used).',
},
enableCleanTextInputYogaNode: {
defaultValue: false,
description: 'Clean yoga node when <TextInput /> does not change.',
@@ -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<<10ac1007b023454a91ce77ccd2642f8a>>
* @generated SignedSource<<4faca2a942651f80d6ec51640c89c962>>
* @flow strict-local
*/
@@ -46,7 +46,6 @@ export type ReactNativeFeatureFlags = {
allowRecursiveCommitsWithSynchronousMountOnAndroid: Getter<boolean>,
batchRenderingUpdatesInEventLoop: Getter<boolean>,
destroyFabricSurfacesInReactInstanceManager: Getter<boolean>,
enableBackgroundExecutor: Getter<boolean>,
enableCleanTextInputYogaNode: Getter<boolean>,
enableGranularShadowTreeStateReconciliation: Getter<boolean>,
enableMicrotasks: Getter<boolean>,
@@ -136,10 +135,6 @@ export const batchRenderingUpdatesInEventLoop: Getter<boolean> = createNativeFla
* When enabled, ReactInstanceManager will clean up Fabric surfaces on destroy().
*/
export const destroyFabricSurfacesInReactInstanceManager: Getter<boolean> = createNativeFlagGetter('destroyFabricSurfacesInReactInstanceManager', false);
/**
* Enables the use of a background executor to compute layout and commit updates on Fabric (this system is deprecated and should not be used).
*/
export const enableBackgroundExecutor: Getter<boolean> = createNativeFlagGetter('enableBackgroundExecutor', false);
/**
* Clean yoga node when <TextInput /> does not change.
*/
@@ -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<<fa3c2e01ffabec3be303a69d1a7043ce>>
* @generated SignedSource<<701db8462ddd5b19233084bf8ce94bc4>>
* @flow strict-local
*/
@@ -28,7 +28,6 @@ export interface Spec extends TurboModule {
+allowRecursiveCommitsWithSynchronousMountOnAndroid?: () => boolean;
+batchRenderingUpdatesInEventLoop?: () => boolean;
+destroyFabricSurfacesInReactInstanceManager?: () => boolean;
+enableBackgroundExecutor?: () => boolean;
+enableCleanTextInputYogaNode?: () => boolean;
+enableGranularShadowTreeStateReconciliation?: () => boolean;
+enableMicrotasks?: () => boolean;