From c19b3ffae96ec57ae0aa143ce66e93f48c4e5301 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Fri, 11 Sep 2020 09:19:44 -0700 Subject: [PATCH] Fabric: Communicating a reason why a commit was unsuccessful via ShadowTree::CommitStatus Summary: We need it to stop repeating to commit new shadow tree in `ShadowTree::commit` when a transaction cancels the commit. Changelog: [Internal] Fabric-specific internal change. Reviewed By: JoshuaGross, sammy-SC Differential Revision: D23603959 fbshipit-source-id: d279fb3bf4190e860740a6450595d6f2fc3117f7 --- .../react/renderer/mounting/ShadowTree.cpp | 18 +++++++++++------- .../react/renderer/mounting/ShadowTree.h | 13 +++++++++---- .../react/renderer/uimanager/UIManager.cpp | 13 +++++++------ 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/ReactCommon/react/renderer/mounting/ShadowTree.cpp b/ReactCommon/react/renderer/mounting/ShadowTree.cpp index 1c5cef2ecf9..59896ad7b1e 100644 --- a/ReactCommon/react/renderer/mounting/ShadowTree.cpp +++ b/ReactCommon/react/renderer/mounting/ShadowTree.cpp @@ -21,6 +21,8 @@ namespace facebook { namespace react { +using CommitStatus = ShadowTree::CommitStatus; + /* * Generates (possibly) a new tree where all nodes with non-obsolete `State` * objects. If all `State` objects in the tree are not obsolete for the moment @@ -260,7 +262,7 @@ MountingCoordinator::Shared ShadowTree::getMountingCoordinator() const { return mountingCoordinator_; } -void ShadowTree::commit( +CommitStatus ShadowTree::commit( ShadowTreeCommitTransaction transaction, bool enableStateReconciliation) const { SystraceSection s("ShadowTree::commit"); @@ -269,8 +271,10 @@ void ShadowTree::commit( while (true) { attempts++; - if (tryCommit(transaction, enableStateReconciliation)) { - return; + + auto status = tryCommit(transaction, enableStateReconciliation); + if (status != CommitStatus::Failed) { + return status; } // After multiple attempts, we failed to commit the transaction. @@ -279,7 +283,7 @@ void ShadowTree::commit( } } -bool ShadowTree::tryCommit( +CommitStatus ShadowTree::tryCommit( ShadowTreeCommitTransaction transaction, bool enableStateReconciliation) const { SystraceSection s("ShadowTree::tryCommit"); @@ -298,7 +302,7 @@ bool ShadowTree::tryCommit( RootShadowNode::Unshared newRootShadowNode = transaction(oldRootShadowNode); if (!newRootShadowNode) { - return false; + return CommitStatus::Cancelled; } if (enableStateReconciliation) { @@ -330,7 +334,7 @@ bool ShadowTree::tryCommit( std::unique_lock lock(commitMutex_); if (rootShadowNode_ != oldRootShadowNode) { - return false; + return CommitStatus::Failed; } rootShadowNode_ = newRootShadowNode; @@ -356,7 +360,7 @@ bool ShadowTree::tryCommit( notifyDelegatesOfUpdates(); - return true; + return CommitStatus::Succeeded; } void ShadowTree::commitEmptyTree() const { diff --git a/ReactCommon/react/renderer/mounting/ShadowTree.h b/ReactCommon/react/renderer/mounting/ShadowTree.h index c4f6314b5b7..7b216a654a0 100644 --- a/ReactCommon/react/renderer/mounting/ShadowTree.h +++ b/ReactCommon/react/renderer/mounting/ShadowTree.h @@ -31,6 +31,12 @@ using ShadowTreeCommitTransaction = std::functiongetSurfaceId(), [&](ShadowTree const &shadowTree) { - bool updateSucceeded = shadowTree.tryCommit( - [&](RootShadowNode::Shared const &oldRootShadowNode) { - return std::static_pointer_cast< - RootShadowNode>(oldRootShadowNode->cloneTree( + auto status = shadowTree.tryCommit([&](RootShadowNode::Shared const + &oldRootShadowNode) { + return std::static_pointer_cast( + oldRootShadowNode->cloneTree( *family, [&](ShadowNode const &oldShadowNode) { auto newData = callback(oldShadowNode.getState()->getDataPointer()); @@ -256,8 +256,9 @@ void UIManager::updateState(StateUpdate const &stateUpdate) const { /* .state = */ newState, }); })); - }); - if (!updateSucceeded && stateUpdate.failureCallback) { + }); + if (status != ShadowTree::CommitStatus::Succeeded && + stateUpdate.failureCallback) { stateUpdate.failureCallback(); } });