Fix ConcurrentModificationException while registering events

Summary:
This diff fixes a ConcurrentModificationException that is thrown when registering events in React Native.
This bug was introduced by D22483508 (https://github.com/facebook/react-native/commit/80f13412e548c8666b6ad770e6d3d5c54a717bc2), before event listeners were registered in the NativeModule Thread, now they are registered in the UI Thread.

As part of this diff I change the type of mListeners variable to use CopyOnWriteArrayList instead of ArrayList because this variable is accessed from different threads. This will prevent the exception to happen, but additionally we need to verify if the change of threading made in D22483508 (https://github.com/facebook/react-native/commit/80f13412e548c8666b6ad770e6d3d5c54a717bc2) will cause any other issue (e.g. events not being delivered becuase the listeners are registered too late in the UI Thread)

changelog:[Internal]

Reviewed By: JoshuaGross

Differential Revision: D22599747

fbshipit-source-id: 5c5e46710c4a559badbd713f536e6e6e464fda23
This commit is contained in:
David Vacca
2020-07-17 11:49:15 -07:00
committed by Facebook GitHub Bot
parent 980900c634
commit ee8a0cfa5a
@@ -22,6 +22,7 @@ import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -88,7 +89,8 @@ public class EventDispatcherImpl implements EventDispatcher, LifecycleEventListe
private final Map<String, Short> mEventNameToEventId = MapBuilder.newHashMap();
private final DispatchEventsRunnable mDispatchEventsRunnable = new DispatchEventsRunnable();
private final ArrayList<Event> mEventStaging = new ArrayList<>();
private final ArrayList<EventDispatcherListener> mListeners = new ArrayList<>();
private final CopyOnWriteArrayList<EventDispatcherListener> mListeners =
new CopyOnWriteArrayList<>();
private final List<BatchEventDispatchedListener> mPostEventDispatchListeners = new ArrayList<>();
private final ScheduleDispatchFrameCallback mCurrentFrameCallback =
new ScheduleDispatchFrameCallback();