mirror of
https://github.com/react/react-native.git
synced 2026-09-28 13:23:09 +08:00
Summary: Pull Request resolved: https://github.com/react/react-native/pull/57376 AnimatedPropsRegistry::update() runs on the UI thread every animation frame and created a surface's entry via operator[]. clearOnSurfaceStop() (run on the JS thread when a surface stops) erases that entry, but an in-flight animation frame landing after the stop re-created it via operator[] -- and since the surface is gone, nothing ever cleans it up again. The resurrected entry leaks its PropsSnapshot and ShadowNodeFamily for the lifetime of the registry. A surface's entry is legitimately created by getMap(), which AnimationBackendCommitHook calls on every React commit. stopSurface drains in-flight commits before unregistering the ShadowTree (ShadowTreeRegistry::remove takes the registry's unique lock, which excludes the shared-locked commit visits), so getMap() can never run for a stopped surface. That leaves update()'s operator[] as the only thing that can resurrect one. Fix: update() now only refines surfaces that already exist (find instead of operator[]) and never creates an entry; getMap() remains the sole creator. A stopped surface can no longer be resurrected, and there is no extra bookkeeping that could grow over time. Changelog: [General][Fixed] - Fix a surface-stop race in the C++ Animated shared backend that could permanently leak per-surface animated state Reviewed By: javache Differential Revision: D109156094 fbshipit-source-id: 4684ca51d372023e3b082427a225de7d84d14889