Prevent Fusebox infra crash if RCTBridge is dealloc'ed off the main queue (#44877)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/44877

Changelog: [Internal]

We're seeing a sporadic iOS crash that suggests `[RCTBridge dealloc]` is being called off the main queue (despite a comment suggesting it shouldn't be). This exposes a race condition between destroying the `HostTarget` and attempting to unregister the instance+runtime from it . Here we use `RCTExecuteOnMainQueue` to make sure the `HostTarget` destruction is always sequenced after the `unregisterFromInspector()` call.

Reviewed By: huntie

Differential Revision: D58415684

fbshipit-source-id: a22e239c80c3204fe32b9e73719ffaa131feaffb
This commit is contained in:
Moti Zilberman
2024-06-12 11:31:56 -07:00
committed by Facebook GitHub Bot
parent 11e5394796
commit df35e258b2
+13 -3
View File
@@ -313,10 +313,20 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init)
// NOTE: RCTCxxBridge will use _inspectorTarget during [self invalidate], so we must
// keep it alive until after the call returns.
[self invalidate];
// `invalidate` is asynchronous if we aren't on the main queue. Unregister
// the HostTarget on the main queue so that `invalidate` can complete safely
// in that case.
if (_inspectorPageId.has_value()) {
facebook::react::jsinspector_modern::getInspectorInstance().removePage(*_inspectorPageId);
_inspectorPageId.reset();
_inspectorTarget.reset();
// Since we can't keep using `self` after dealloc, steal its inspector
// state into block-mutable variables
__block auto inspectorPageId = std::move(_inspectorPageId);
__block auto inspectorTarget = std::move(_inspectorTarget);
RCTExecuteOnMainQueue(^{
facebook::react::jsinspector_modern::getInspectorInstance().removePage(*inspectorPageId);
inspectorPageId.reset();
inspectorTarget.reset();
});
}
}