Files
react-native/ReactCommon/react/renderer/scheduler/AsynchronousEventBeatV2.cpp
T
Samuel Susla 1b592631a7 Prevent redundant dispatches onto RuntimeExecutor queue in AsynchronousEventBeat::induce
Summary:
Changelog: [internal]

Current implementation of `AsynchronousEventBeat` dispatches lambdas through `RuntimeExecutor` regardless if it has done so previously.

So if `AsynchronousEventBeat::induce` is called 30 times, it will dispatch 30 lambdas.

In `AsynchronousEventBeatV2`, we make sure only single lambda is dispatched to `RuntimeExecutor` at a time.

Reviewed By: mdvacca

Differential Revision: D27940300

fbshipit-source-id: 2bad25c86315c1712b4a1da8c1d4702734cec70f
2021-04-24 03:21:09 -07:00

59 lines
1.5 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "AsynchronousEventBeatV2.h"
#include <react/debug/react_native_assert.h>
namespace facebook::react {
AsynchronousEventBeatV2::AsynchronousEventBeatV2(
RunLoopObserver::Unique uiRunLoopObserver,
RuntimeExecutor runtimeExecutor)
: EventBeat({}),
uiRunLoopObserver_(std::move(uiRunLoopObserver)),
runtimeExecutor_(std::move(runtimeExecutor)) {
uiRunLoopObserver_->setDelegate(this);
uiRunLoopObserver_->enable();
}
void AsynchronousEventBeatV2::activityDidChange(
RunLoopObserver::Delegate const *delegate,
RunLoopObserver::Activity) const noexcept {
react_native_assert(delegate == this);
induce();
}
void AsynchronousEventBeatV2::induce() const {
if (!isRequested_ || isBeatCallbackScheduled_) {
return;
}
isRequested_ = false;
// Here we know that `this` object exists because the caller has a strong
// pointer to `owner`. To ensure the object will exist inside
// `runtimeExecutor_` callback, we need to copy the pointer there.
auto weakOwner = uiRunLoopObserver_->getOwner();
isBeatCallbackScheduled_ = true;
runtimeExecutor_([this, weakOwner](jsi::Runtime &runtime) {
isBeatCallbackScheduled_ = false;
auto owner = weakOwner.lock();
if (!owner) {
return;
}
if (beatCallback_) {
beatCallback_(runtime);
}
});
}
} // namespace facebook::react