Commit 22d3275
Fix deadlock in AnimationBackendChoreographer
Summary:
scheduleCallback() and pause() held synchronized(paused) while calling
ReactChoreographer.postFrameCallback/removeFrameCallback, which acquire
synchronized(callbackQueues). ReactChoreographer dispatches frame
callbacks inside synchronized(callbackQueues), invoking
executeFrameCallback -> scheduleCallback -> synchronized(paused).
This is a lock ordering inversion: background thread acquires paused
then callbackQueues, main thread acquires callbackQueues then paused.
Fix: move postFrameCallback/removeFrameCallback calls outside the
synchronized(paused) block. The atomic state check (paused +
callbackPosted) stays inside the lock, only the ReactChoreographer
interaction moves outside.
Why this is safe:
- callbackPosted.getAndSet(true) inside the lock guarantees at most one
thread proceeds to post. A concurrent scheduleCallback will see
callbackPosted=true and bail out.
- If pause() runs between the lock release and postFrameCallback:
pause sets paused=true and callbackPosted=false, then calls
removeFrameCallback. Two outcomes depending on ordering inside
callbackQueues (which serializes both calls):
(a) post runs first, then remove cancels it — clean.
(b) remove runs first (nothing to remove), then post adds a callback.
That callback fires once, executeFrameCallback sees paused=true
via scheduleCallback and does not re-post. Net effect: one extra
no-op frame, then the loop stops.
- resume() already operated without synchronized(paused) before this
change, so no new races are introduced on that path.
## Changelog:
[Android] [Changed] - AnimationBackendChoreographer doesn't guard the ReactChoreographer post/remove with synchronized(paused)
Reviewed By: zeyap
Differential Revision: D99099455
fbshipit-source-id: 5c5e9e76ec23fd300a0a67c98b70a9c5bdb08f301 parent bf277cb commit 22d3275
File tree
1 file changed
+15
-13
lines changed- packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric
1 file changed
+15
-13
lines changedLines changed: 15 additions & 13 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
| 49 | + | |
49 | 50 | | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
56 | 58 | | |
57 | 59 | | |
58 | 60 | | |
59 | 61 | | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
67 | 69 | | |
68 | 70 | | |
69 | 71 | | |
| |||
0 commit comments