Skip to content

Port RCTDisplayLink fix from React Native macOS#35359

Closed
Saadnajmi wants to merge 2 commits into
facebook:mainfrom
Saadnajmi:displaylink
Closed

Port RCTDisplayLink fix from React Native macOS#35359
Saadnajmi wants to merge 2 commits into
facebook:mainfrom
Saadnajmi:displaylink

Conversation

@Saadnajmi
Copy link
Copy Markdown
Contributor

Summary

Cherry pick microsoft@e877ebf from React Native macOS into React Native Core. We've had this bug fix in our fork for a while now, so it's probably safe.

=== Original change notes ===

First, misc straightforward deprecated API updates.

Second, defensive changes to potentially address RCTDisplayLink crash.
Real-world data suggests crashes with this stack:
CVDisplayLink::start()
-[RCTDisplayLink updateJSDisplayLinkState] (RCTDisplayLink.m:157)
-[RCTDisplayLink registerModuleForFrameUpdates:withModuleData:]_block_invoke (RCTDisplayLink.m:67)
-[RCTTiming timerDidFire] (RCTTiming.mm:324)
-[_RCTTimingProxy timerDidFire] (RCTTiming.mm:93)

Some symbols are missing in this stack, presumably due to compiler optimizations.
-updateJSDisplayLinkState is calling CVDisplayLinkStart as a result of a
call to "_jsDisplayLink.paused = NO".
-registerModuleForFrameUpdates block is presumably getting called via pauseCallback,
likely via [RCTTiming startTimers], presumably owned by RCTCxxBridge.

The most likely immediate explanation for the crash is that we are calling
CVDisplayLinkStart with a zombie _displayLink pointer.
However there is a lot of indirection here as well as thread-hopping, and
unfortunately no clearly incorrect code that would explain such a zombie pointer.

Some defensive changes:
-explicitly remove the association to pauseCallback when underlying display link object is invalidated.
-remove a prior attempt at additional check in updateJSDisplayLinkState itself as it is not relevant.
-make sure we explicitly set _displayLink to NULL when we release it, such that there is one less failure point.

Changelog

[Internal] [Changed] - RCTDisplayLink fix plus bonus deprecated API cleanup

Test Plan

CI should pass.

ntre and others added 2 commits November 15, 2022 18:32
Defensive changes to Mac RCTDisplayLink

Real-world data suggests crashes with this stack:
  CVDisplayLink::start()
  -[RCTDisplayLink updateJSDisplayLinkState] (RCTDisplayLink.m:157)
  -[RCTDisplayLink registerModuleForFrameUpdates:withModuleData:]_block_invoke (RCTDisplayLink.m:67)
  -[RCTTiming timerDidFire] (RCTTiming.mm:324)
  -[_RCTTimingProxy timerDidFire] (RCTTiming.mm:93)

Some symbols are missing in this stack, presumably due to compiler optimizations.
-updateJSDisplayLinkState is calling CVDisplayLinkStart as a result of a
call to "_jsDisplayLink.paused = NO".
-registerModuleForFrameUpdates block is presumably getting called via pauseCallback,
likely via [RCTTiming startTimers], presumably owned by RCTCxxBridge.

The most likely immediate explanation for the crash is that we are calling
CVDisplayLinkStart with a zombie _displayLink pointer.
However there is a lot of indirection here as well as thread-hopping, and
unfortunately no clearly incorrect code that would explain such a zombie pointer.

Some defensive changes:
-explicitly remove the association to pauseCallback when underlying display link object is invalidated.
-remove a prior attempt at additional check in updateJSDisplayLinkState itself as it is not relevant.
-make sure we explicitly set _displayLink to NULL when we release it, such that there is one less failure point.
@facebook-github-bot facebook-github-bot added CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. p: Microsoft Partner: Microsoft Partner labels Nov 16, 2022
@analysis-bot
Copy link
Copy Markdown

Platform Engine Arch Size (bytes) Diff
ios - universal n/a --

Base commit: 5fda72f
Branch: main

@analysis-bot
Copy link
Copy Markdown

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 7,099,140 -114
android hermes armeabi-v7a 6,468,954 -37
android hermes x86 7,516,865 -272
android hermes x86_64 7,375,628 -191
android jsc arm64-v8a 8,963,989 +0
android jsc armeabi-v7a 7,695,475 +0
android jsc x86 9,026,538 +0
android jsc x86_64 9,504,682 +0

Base commit: 5fda72f
Branch: main

@pull-bot
Copy link
Copy Markdown

PR build artifact for 97dbcd2 is ready.
To use, download tarball from "Artifacts" tab in this CircleCI job then run yarn add <path to tarball> in your React Native project.

@facebook-github-bot
Copy link
Copy Markdown
Contributor

@christophpurrer has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@Saadnajmi Saadnajmi deleted the displaylink branch November 16, 2022 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. p: Microsoft Partner: Microsoft Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants