Skip to content

Commit f34a289

Browse files
RSNarafacebook-github-bot
authored andcommitted
Invalidate TurboModules on their method queues
Summary: ## Rationale With the bridge, the invalidate method of every TurboModule gets called on the TurboModule's method queue. This ensures that we can safely clean up resources accessed in the TurboModule's async methods. In bridgeless mode, we don't invalidate each module on its method queue. After this diff, we will clean up every TurboModule on its own method queue. ## Changes - Make RCTInstance dealloc itself on the JavaScript thread. - Terminate the JavaScript thread on the JavaScript thread. This ensures that no work executes on the JavaScript thread after we clean up RCTInstance. - Make [RCTTurboModuleManager invalidate] execute right before RCTInstance terminates the JavaScript thread. - **Fix:** Make [RCTTurboModuleManger invalidate] synchronously invalidate modules on their own method queues. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D27933587 fbshipit-source-id: 7630e7fc074df2f5a3293192431105c747b8588f
1 parent 090196f commit f34a289

File tree

1 file changed

+39
-34
lines changed

1 file changed

+39
-34
lines changed

ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModuleManager.mm

+39-34
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,27 @@ - (void)bridgeWillInvalidateModules:(NSNotification *)notification
834834
return;
835835
}
836836

837+
[self _enterInvalidatingState];
838+
}
839+
840+
- (void)bridgeDidInvalidateModules:(NSNotification *)notification
841+
{
842+
RCTBridge *bridge = notification.userInfo[@"bridge"];
843+
if (bridge != _bridge) {
844+
return;
845+
}
846+
847+
[self _invalidateModules];
848+
}
849+
850+
- (void)invalidate
851+
{
852+
[self _enterInvalidatingState];
853+
[self _invalidateModules];
854+
}
855+
856+
- (void)_enterInvalidatingState
857+
{
837858
// This should halt all insertions into _turboModuleHolders
838859
if (RCTTurboModuleSharedMutexInitEnabled()) {
839860
std::unique_lock<std::shared_timed_mutex> guard(_turboModuleHoldersSharedMutex);
@@ -844,13 +865,8 @@ - (void)bridgeWillInvalidateModules:(NSNotification *)notification
844865
}
845866
}
846867

847-
- (void)bridgeDidInvalidateModules:(NSNotification *)notification
868+
- (void)_invalidateModules
848869
{
849-
RCTBridge *bridge = notification.userInfo[@"bridge"];
850-
if (bridge != _bridge) {
851-
return;
852-
}
853-
854870
// Backward-compatibility: RCTInvalidating handling.
855871
dispatch_group_t moduleInvalidationGroup = dispatch_group_create();
856872

@@ -870,17 +886,28 @@ - (void)bridgeDidInvalidateModules:(NSNotification *)notification
870886
if ([module respondsToSelector:@selector(invalidate)]) {
871887
if ([module respondsToSelector:@selector(methodQueue)]) {
872888
dispatch_queue_t methodQueue = [module performSelector:@selector(methodQueue)];
889+
873890
if (methodQueue) {
874891
dispatch_group_enter(moduleInvalidationGroup);
875-
[bridge
876-
dispatchBlock:^{
877-
[((id<RCTInvalidating>)module) invalidate];
878-
dispatch_group_leave(moduleInvalidationGroup);
879-
}
880-
queue:methodQueue];
892+
dispatch_block_t invalidateModule = ^{
893+
[((id<RCTInvalidating>)module) invalidate];
894+
dispatch_group_leave(moduleInvalidationGroup);
895+
};
896+
897+
if (_bridge) {
898+
[_bridge dispatchBlock:invalidateModule queue:methodQueue];
899+
} else {
900+
// Bridgeless mode
901+
if (methodQueue == RCTJSThread) {
902+
invalidateModule();
903+
} else {
904+
dispatch_async(methodQueue, invalidateModule);
905+
}
906+
}
881907
continue;
882908
}
883909
}
910+
884911
[((id<RCTInvalidating>)module) invalidate];
885912
}
886913
}
@@ -893,26 +920,4 @@ - (void)bridgeDidInvalidateModules:(NSNotification *)notification
893920
_turboModuleCache.clear();
894921
}
895922

896-
- (void)invalidate
897-
{
898-
if (RCTTurboModuleSharedMutexInitEnabled()) {
899-
std::unique_lock<std::shared_timed_mutex> guard(_turboModuleHoldersSharedMutex);
900-
_invalidating = true;
901-
} else {
902-
std::lock_guard<std::mutex> guard(_turboModuleHoldersMutex);
903-
_invalidating = true;
904-
}
905-
906-
// Backward-compatibility: RCTInvalidating handling, but not adhering to desired methodQueue.
907-
for (const auto &p : _turboModuleHolders) {
908-
id<RCTTurboModule> module = p.second.getModule();
909-
if ([module respondsToSelector:@selector(invalidate)]) {
910-
[((id<RCTInvalidating>)module) invalidate];
911-
}
912-
}
913-
914-
_turboModuleHolders.clear();
915-
_turboModuleCache.clear();
916-
}
917-
918923
@end

0 commit comments

Comments
 (0)