Skip to content

Commit 68fd1e5

Browse files
fix: deadlock when sending events (#33490)
Summary: In short, if an RCTEventDispatcher observer sends an event on the same thread that the observer was initially on, there will be a deadlock due to `sendEvent` already having the lock active on the `_observers` NSHashTable. An example where this occurred was when we had react-native-gesture-handler trigger an animated event, which then triggered an event on the underlying component being animated as a result of it being an observer on the animation event. Since this all occurred on the main thread, we ended up with a deadlock and the app froze. To prevent this scenario, I used a `NSRecursiveLock` for _observersLock to be able to dispatch events on the same thread from observers. joebernard ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> [iOS] [Fix] - Prevent deadlock when dispatching events from observers on the same thread. Pull Request resolved: #33490 Test Plan: Not sure if there are any tests present for sending events with RCTEventDispatcher already in place, but In regular app usage this solution has proved to be a viable and stable option so far and has prevented the deadlock from occurring. This would still be thread-safe since we are now allowing the event to be sent through observers on the same thread the initial event was dispatched on. The only issue I could see here is the behavior of sending an event could be changed. Reviewed By: RSNara Differential Revision: D35118752 Pulled By: charlesbdudley fbshipit-source-id: 7e93a8d49841e001b235a437ccca1e072dcc7ab1
1 parent 7b5b114 commit 68fd1e5

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

React/CoreModules/RCTEventDispatcher.mm

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ @implementation RCTEventDispatcher {
3737
NSMutableArray<NSNumber *> *_eventQueue;
3838
BOOL _eventsDispatchScheduled;
3939
NSHashTable<id<RCTEventDispatcherObserver>> *_observers;
40-
NSLock *_observersLock;
40+
NSRecursiveLock *_observersLock;
4141
}
4242

4343
@synthesize bridge = _bridge;
@@ -53,7 +53,7 @@ - (void)initialize
5353
_eventQueueLock = [NSLock new];
5454
_eventsDispatchScheduled = NO;
5555
_observers = [NSHashTable weakObjectsHashTable];
56-
_observersLock = [NSLock new];
56+
_observersLock = [NSRecursiveLock new];
5757
}
5858

5959
- (void)sendViewEventWithName:(NSString *)name reactTag:(NSNumber *)reactTag

0 commit comments

Comments
 (0)