mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Avoid errors when dispatching mount operations within mount hooks (#50091)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/50091 Changelog: [internal] If a library uses mount hooks to perform mount operations, it's possible to get concurrent modifications of the list of pending surface IDs to report. This fixes that potential error by making a copy of the list before dispatching the mount notifications. Fixes https://github.com/facebook/react-native/issues/49783. Reviewed By: javache Differential Revision: D71387739 fbshipit-source-id: 96c723ef2d6bcc659c4452434b7a4d5af26117ef
This commit is contained in:
committed by
Facebook GitHub Bot
parent
e4d51cd866
commit
17da3cbbf4
+11
-8
@@ -173,7 +173,7 @@ public class FabricUIManager
|
|||||||
private final CopyOnWriteArrayList<UIManagerListener> mListeners = new CopyOnWriteArrayList<>();
|
private final CopyOnWriteArrayList<UIManagerListener> mListeners = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
private boolean mMountNotificationScheduled = false;
|
private boolean mMountNotificationScheduled = false;
|
||||||
private final List<Integer> mMountedSurfaceIds = new ArrayList<>();
|
private List<Integer> mSurfaceIdsWithPendingMountNotification = new ArrayList<>();
|
||||||
|
|
||||||
@ThreadConfined(UI)
|
@ThreadConfined(UI)
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -1254,12 +1254,13 @@ public class FabricUIManager
|
|||||||
|
|
||||||
// Collect surface IDs for all the mount items
|
// Collect surface IDs for all the mount items
|
||||||
for (MountItem mountItem : mountItems) {
|
for (MountItem mountItem : mountItems) {
|
||||||
if (mountItem != null && !mMountedSurfaceIds.contains(mountItem.getSurfaceId())) {
|
if (mountItem != null
|
||||||
mMountedSurfaceIds.add(mountItem.getSurfaceId());
|
&& !mSurfaceIdsWithPendingMountNotification.contains(mountItem.getSurfaceId())) {
|
||||||
|
mSurfaceIdsWithPendingMountNotification.add(mountItem.getSurfaceId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mMountNotificationScheduled && !mMountedSurfaceIds.isEmpty()) {
|
if (!mMountNotificationScheduled && !mSurfaceIdsWithPendingMountNotification.isEmpty()) {
|
||||||
mMountNotificationScheduled = true;
|
mMountNotificationScheduled = true;
|
||||||
|
|
||||||
// Notify mount when the effects are visible and prevent mount hooks to
|
// Notify mount when the effects are visible and prevent mount hooks to
|
||||||
@@ -1271,17 +1272,19 @@ public class FabricUIManager
|
|||||||
public void run() {
|
public void run() {
|
||||||
mMountNotificationScheduled = false;
|
mMountNotificationScheduled = false;
|
||||||
|
|
||||||
|
// Create a copy in case mount hooks trigger more mutations
|
||||||
|
final List<Integer> surfaceIdsToReportMount =
|
||||||
|
mSurfaceIdsWithPendingMountNotification;
|
||||||
|
mSurfaceIdsWithPendingMountNotification = new ArrayList<>();
|
||||||
|
|
||||||
final @Nullable FabricUIManagerBinding binding = mBinding;
|
final @Nullable FabricUIManagerBinding binding = mBinding;
|
||||||
if (binding == null || mDestroyed) {
|
if (binding == null || mDestroyed) {
|
||||||
mMountedSurfaceIds.clear();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int surfaceId : mMountedSurfaceIds) {
|
for (int surfaceId : surfaceIdsToReportMount) {
|
||||||
binding.reportMount(surfaceId);
|
binding.reportMount(surfaceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
mMountedSurfaceIds.clear();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user