Skip to content

Commit

Permalink
Fix invalidation for modules with infra-generated method queues
Browse files Browse the repository at this point in the history
Summary:
When invalidating TurboModules, the TurboModule infra looks for a methodQueue method on the TurboModule (line 871 below). If it finds one, the TurboModuleManager dispatches module invalidate on that method queue:

https://www.internalfb.com/code/fbsource/[c91dc16f4b63abd05c7c9a038e88ca692a453c69]/xplat/js/react-native-github/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModuleManager.mm?lines=847-848%2C870-883

## The Problem

TurboModules that neither provide a method queue, nor request a method queue won't respond to selector(methodQueue). For those modules, the TurboModule system won't dispatch invalidate to their method queue

## The Fix
Calling selector(methodQueue) is an unreliable way of getting the module's method queue. The TurboModuleManager attaches a method queue to every TurboModule as an associated object:

https://www.internalfb.com/code/fbsource/[c91dc16f4b63]/xplat/js/react-native-github/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModuleManager.mm?lines=636

In this diff, in the TurboModule invalidate method, we retrieve the method queue using ObjC's associated object API. This guarantees that all TurboModules will be invalidated on their method queues.

Changelog: [iOS][Fixed] - Invalidate TurboModules with infra-generated method queues on their method queues

Reviewed By: appden

Differential Revision: D27954644

fbshipit-source-id: af4408e444d03a15d8d8e154b3980511b81d5fb1
  • Loading branch information
RSNara authored and facebook-github-bot committed Apr 23, 2021
1 parent f34a289 commit 497eb57
Showing 1 changed file with 23 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -884,31 +884,31 @@ - (void)_invalidateModules
shouldPerfLog:NO];

if ([module respondsToSelector:@selector(invalidate)]) {
if ([module respondsToSelector:@selector(methodQueue)]) {
dispatch_queue_t methodQueue = [module performSelector:@selector(methodQueue)];

if (methodQueue) {
dispatch_group_enter(moduleInvalidationGroup);
dispatch_block_t invalidateModule = ^{
[((id<RCTInvalidating>)module) invalidate];
dispatch_group_leave(moduleInvalidationGroup);
};

if (_bridge) {
[_bridge dispatchBlock:invalidateModule queue:methodQueue];
} else {
// Bridgeless mode
if (methodQueue == RCTJSThread) {
invalidateModule();
} else {
dispatch_async(methodQueue, invalidateModule);
}
}
continue;
}
dispatch_queue_t methodQueue = (dispatch_queue_t)objc_getAssociatedObject(module, &kAssociatedMethodQueueKey);

if (methodQueue == nil) {
RCTLogError(
@"TurboModuleManager: Couldn't invalidate TurboModule \"%@\", because its method queue is nil.",
[module class]);
continue;
}

[((id<RCTInvalidating>)module) invalidate];
dispatch_group_enter(moduleInvalidationGroup);
dispatch_block_t invalidateModule = ^{
[((id<RCTInvalidating>)module) invalidate];
dispatch_group_leave(moduleInvalidationGroup);
};

if (_bridge) {
[_bridge dispatchBlock:invalidateModule queue:methodQueue];
} else {
// Bridgeless mode
if (methodQueue == RCTJSThread) {
invalidateModule();
} else {
dispatch_async(methodQueue, invalidateModule);
}
}
}
}

Expand Down

0 comments on commit 497eb57

Please sign in to comment.