Skip to content

Commit

Permalink
Refactor RCT_handleKeyCommand to avoid concurrency issues (#42708)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #42708

When pressing `r` on simulator in Bridgeless mode, we have a race condition between:
- RCTKeyCommands evaluating the blocks to be invoked
- ReactNative invalidating the DevMenu with the list of RCTKeyCommands (on which ReactNative is iterating).

The fix checks which commands need to be executed, stores them in an array and then iterates on the array, which is local to the function call, avoiding any concurrency issue.

## Changelog:
[iOS][Fixed] - Refactored RCT_handleKeyCommand to avoid concurrency issues

Reviewed By: motiz88

Differential Revision: D53186262

fbshipit-source-id: 60ae8974a9df7289395c8a9e9abe2e34e4c40309
  • Loading branch information
cipolleschi authored and facebook-github-bot committed Jan 30, 2024
1 parent 8a8f74b commit 8d710bf
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion packages/react-native/React/Base/RCTKeyCommands.m
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,24 @@ - (void)handleKeyUIEventSwizzle:(UIEvent *)event

- (void)RCT_handleKeyCommand:(NSString *)input flags:(UIKeyModifierFlags)modifierFlags
{
// In Bridgeless mode we might incur in some concurrency issues
// where the React Native instance is invalidated while iterating on the
// list of available commands.
// That will cleanup the set while iterating, which is a not allowed mutation.
// To work around that, we store the commands that we need to execute in a separate
// array, local to this function call, so we don't incur in concurrency issues
NSMutableArray<RCTKeyCommand *> *commandsToExecute = [NSMutableArray new];
for (RCTKeyCommand *command in [RCTKeyCommands sharedInstance].commands) {
if ([command matchesInput:input flags:modifierFlags]) {
if (command.block) {
command.block(nil);
[commandsToExecute addObject:command];
}
}
}

for (RCTKeyCommand *command in commandsToExecute) {
command.block(nil);
}
}

+ (instancetype)sharedInstance
Expand Down

0 comments on commit 8d710bf

Please sign in to comment.