Skip to content

Commit

Permalink
Fabric: Support for interleaving/followup transactions in RCTMounting…
Browse files Browse the repository at this point in the history
…Manager (iOS)

Summary:
Imagine a case where we initiate a synchronous state update right in the middle of the mount transaction. With the current implementation, the mount transaction caused by the change will be mounted right inside the in-flight transaction, which will probably cause a crash or incorrect mounting side-effects (which will cause a crash later).
Instead of executing all mounting instructions cased by the state change, we actually need to execute them right after the end of the current transaction (synchronously, inside the same main run loop tick).
This diff implements exactly this.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: mdvacca

Differential Revision: D18444730

fbshipit-source-id: 3e777a7aa70ff28205d40588970c7478869b6899
  • Loading branch information
shergin authored and facebook-github-bot committed Nov 18, 2019
1 parent 9349ee2 commit 5f0435f
Showing 1 changed file with 25 additions and 5 deletions.
30 changes: 25 additions & 5 deletions React/Fabric/Mounting/RCTMountingManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ static void RNPerformMountInstructions(

@implementation RCTMountingManager {
RCTMountingTransactionObserverCoordinator _observerCoordinator;
BOOL _transactionInFlight;
BOOL _followUpTransactionRequired;
}

- (instancetype)init
Expand All @@ -225,14 +227,14 @@ - (void)scheduleTransaction:(MountingCoordinator::Shared const &)mountingCoordin
// * No need to do a thread jump;
// * No need to do expensive copy of all mutations;
// * No need to allocate a block.
[self mountMutations:mountingCoordinator];
[self initiateTransaction:mountingCoordinator];
return;
}

auto mountingCoordinatorCopy = mountingCoordinator;
RCTExecuteOnMainQueue(^{
RCTAssertMainQueue();
[self mountMutations:mountingCoordinatorCopy];
[self initiateTransaction:mountingCoordinatorCopy];
});
}

Expand All @@ -252,9 +254,28 @@ - (void)dispatchCommand:(ReactTag)reactTag commandName:(NSString *)commandName a
});
}

- (void)mountMutations:(MountingCoordinator::Shared const &)mountingCoordinator
- (void)initiateTransaction:(MountingCoordinator::Shared const &)mountingCoordinator
{
SystraceSection s("-[RCTMountingManager mountMutations:]");
SystraceSection s("-[RCTMountingManager initiateTransaction:]");
RCTAssertMainQueue();

if (_transactionInFlight) {
_followUpTransactionRequired = YES;
return;
}

do {
_followUpTransactionRequired = NO;
_transactionInFlight = YES;
[self performTransaction:mountingCoordinator];
_transactionInFlight = NO;
} while (_followUpTransactionRequired);
}

- (void)performTransaction:(MountingCoordinator::Shared const &)mountingCoordinator
{
SystraceSection s("-[RCTMountingManager performTransaction:]");
RCTAssertMainQueue();

auto transaction = mountingCoordinator->pullTransaction();
if (!transaction.has_value()) {
Expand All @@ -268,7 +289,6 @@ - (void)mountMutations:(MountingCoordinator::Shared const &)mountingCoordinator
return;
}

RCTAssertMainQueue();
auto telemetry = transaction->getTelemetry();
auto number = transaction->getNumber();

Expand Down

0 comments on commit 5f0435f

Please sign in to comment.