Skip to content

Commit 490559a

Browse files
ntreSaadnajmi
authored andcommitted
Mac RCTDisplayLink fix plus bonus deprecated API cleanup (microsoft#854)
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.
1 parent 5fda72f commit 490559a

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

React/Base/RCTDisplayLink.m

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,15 @@ - (void)dealloc
9595

9696
- (void)invalidate
9797
{
98+
// [TODO: GH#858
99+
// ensure observer callbacks do not hold a reference to weak self via pauseCallback
100+
for (RCTModuleData *moduleData in _frameUpdateObservers) {
101+
id<RCTFrameUpdateObserver> observer = (id<RCTFrameUpdateObserver>)moduleData.instance;
102+
[observer setPauseCallback:nil];
103+
}
104+
[_frameUpdateObservers removeAllObjects]; // just to be explicit
105+
// TODO: GH#858]
106+
98107
[_jsDisplayLink invalidate];
99108
}
100109

0 commit comments

Comments
 (0)