From 8d613c6f327b79bf5252cc8fb639d8697259703f Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Fri, 24 Jul 2020 23:50:50 -0700 Subject: [PATCH] Fabric: Implementation of BackgroundExecutor on iOS (and gating) Summary: This is an implementation of `BackgroundExecutor` on iOS. In case if the experiment is successful, we will make it mandatory for all platforms. Changelog: [Internal] Fabric-specific internal change. Reviewed By: JoshuaGross Differential Revision: D22743722 fbshipit-source-id: 7756d2947e962720b9970d48c74929ab407c0440 --- React/Fabric/RCTSurfacePresenter.mm | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/React/Fabric/RCTSurfacePresenter.mm b/React/Fabric/RCTSurfacePresenter.mm index bda325862c3a78..838b5f906361ec 100644 --- a/React/Fabric/RCTSurfacePresenter.mm +++ b/React/Fabric/RCTSurfacePresenter.mm @@ -60,6 +60,33 @@ static inline LayoutContext RCTGetLayoutContext() .fontSizeMultiplier = RCTFontSizeMultiplier()}; } +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 &&callback) { + if (RCTIsMainQueue()) { + callback(); + return; + } + + auto copyableCallback = callback; + dispatch_async(RCTGetBackgroundQueue(), ^{ + copyableCallback(); + }); + }; +} + @interface RCTSurfacePresenter () @end @@ -312,6 +339,10 @@ - (RCTScheduler *)_createScheduler return std::make_unique(activities, owner); }; + if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:enable_background_executor_ios")) { + toolbox.backgroundExecutor = RCTGetBackgroundExecutor(); + } + if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:enable_run_loop_based_event_beat_ios")) { toolbox.synchronousEventBeatFactory = [runtimeExecutor](EventBeat::SharedOwnerBox const &ownerBox) { auto runLoopObserver =