Skip to content

Commit 52a9fed

Browse files
sammy-SCfacebook-github-bot
authored andcommitted
Use atomic pointer for animationDelegate_ to prevent race during teardown
Summary: Changelog: [internal] [This assumption](https://fburl.com/diffusion/yeqtvxru) in `~Scheduler` might not be completely correct. There can be a race between JS thread and main thread. With main thread settings animationDelegate_ to nullptr and JS thread reading the value. Even though they always happen one after the other, JS thread can have the value of animationDelegate_ in its cache line and changing it from main thread might not invalidate it right away. Reviewed By: JoshuaGross Differential Revision: D29237290 fbshipit-source-id: 6cb898caf7c225cf8162e7560921b563dec514b1
1 parent d1e7551 commit 52a9fed

File tree

2 files changed

+9
-7
lines changed

2 files changed

+9
-7
lines changed

ReactCommon/react/renderer/uimanager/UIManager.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -345,8 +345,9 @@ void UIManager::configureNextLayoutAnimation(
345345
RawValue const &config,
346346
jsi::Value const &successCallback,
347347
jsi::Value const &failureCallback) const {
348-
if (animationDelegate_) {
349-
animationDelegate_->uiManagerDidConfigureNextLayoutAnimation(
348+
auto animationDelegate = animationDelegate_.load();
349+
if (animationDelegate) {
350+
animationDelegate->uiManagerDidConfigureNextLayoutAnimation(
350351
runtime,
351352
config,
352353
std::move(successCallback),
@@ -435,14 +436,15 @@ void UIManager::setAnimationDelegate(UIManagerAnimationDelegate *delegate) {
435436
}
436437

437438
void UIManager::stopSurfaceForAnimationDelegate(SurfaceId surfaceId) const {
438-
if (animationDelegate_ != nullptr) {
439-
animationDelegate_->stopSurface(surfaceId);
439+
auto animationDelegate = animationDelegate_.load();
440+
if (animationDelegate) {
441+
animationDelegate->stopSurface(surfaceId);
440442
}
441443
}
442444

443445
void UIManager::animationTick() {
444-
if (animationDelegate_ != nullptr &&
445-
animationDelegate_->shouldAnimateFrame()) {
446+
auto animationDelegate = animationDelegate_.load();
447+
if (animationDelegate && animationDelegate->shouldAnimateFrame()) {
446448
shadowTreeRegistry_.enumerate(
447449
[&](ShadowTree const &shadowTree, bool &stop) {
448450
shadowTree.notifyDelegatesOfUpdates();

ReactCommon/react/renderer/uimanager/UIManager.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,8 @@ class UIManager final : public ShadowTreeDelegate {
184184
ShadowTreeRegistry const &getShadowTreeRegistry() const;
185185

186186
SharedComponentDescriptorRegistry componentDescriptorRegistry_;
187-
UIManagerAnimationDelegate *animationDelegate_{nullptr};
188187
std::atomic<UIManagerDelegate *> delegate_;
188+
std::atomic<UIManagerAnimationDelegate *> animationDelegate_{nullptr};
189189
RuntimeExecutor const runtimeExecutor_{};
190190
ShadowTreeRegistry shadowTreeRegistry_{};
191191
BackgroundExecutor const backgroundExecutor_{};

0 commit comments

Comments
 (0)