From 10181f31bdb3e8fef47c968ca563290854c15ed5 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Fri, 7 Sep 2018 23:38:49 -0700 Subject: [PATCH] Fabric: Fixed possible crash due race condition during Surface unmounting Summary: @public Now we simply skip `uiManagerDidFinishTransaction` calls if they refer to unregister surfaces. In the future, after we have proper asynchronous scheduling and sync unmounting (and if we chose to have sync unmounting), we can avoid this situation (and assert in this cases). Reviewed By: sahrens Differential Revision: D9652731 fbshipit-source-id: e376ea1ae4f93960a903e6397d843bd7c4b72400 --- ReactCommon/fabric/uimanager/Scheduler.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ReactCommon/fabric/uimanager/Scheduler.cpp b/ReactCommon/fabric/uimanager/Scheduler.cpp index c5bfe919340..40660ab91c0 100644 --- a/ReactCommon/fabric/uimanager/Scheduler.cpp +++ b/ReactCommon/fabric/uimanager/Scheduler.cpp @@ -91,10 +91,14 @@ void Scheduler::shadowTreeDidCommit(const ShadowTree &shadowTree, const ShadowVi #pragma mark - UIManagerDelegate void Scheduler::uiManagerDidFinishTransaction(Tag rootTag, const SharedShadowNodeUnsharedList &rootChildNodes) { - const auto &iterator = shadowTreeRegistry_.find(rootTag); - const auto &shadowTree = iterator->second; - assert(shadowTree); - return shadowTree->complete(rootChildNodes); + const auto iterator = shadowTreeRegistry_.find(rootTag); + if (iterator == shadowTreeRegistry_.end()) { + // This might happen during surface unmounting/deallocation process + // due to the asynchronous nature of JS calls. + return; + } + + return iterator->second->complete(rootChildNodes); } void Scheduler::uiManagerDidCreateShadowNode(const SharedShadowNode &shadowNode) {