From 22334407d3551e4a1d9426a77c410adb65a73848 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Mon, 9 Apr 2018 16:32:38 -0700 Subject: Fixing concurrent modification when we cancel transaction --- Firebase/Database/Core/FPersistentConnection.m | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'Firebase/Database') diff --git a/Firebase/Database/Core/FPersistentConnection.m b/Firebase/Database/Core/FPersistentConnection.m index 870727c..c32d18c 100644 --- a/Firebase/Database/Core/FPersistentConnection.m +++ b/Firebase/Database/Core/FPersistentConnection.m @@ -735,18 +735,22 @@ static void reachabilityCallback(SCNetworkReachabilityRef ref, SCNetworkReachabi } - (void) cancelSentTransactions { - NSMutableArray* toPrune = [[NSMutableArray alloc] init]; + NSMutableDictionary* cancelledOutstandingPuts = [[NSMutableDictionary alloc] init]; + for (NSNumber* index in self.outstandingPuts) { FOutstandingPut* put = self.outstandingPuts[index]; if (put.request[kFWPRequestHash] && put.sent) { - // This is a sent transaction put - put.onCompleteBlock(kFTransactionDisconnect, @"Client was disconnected while running a transaction"); - [toPrune addObject:index]; + // This is a sent transaction put. + cancelledOutstandingPuts[index] = put; } } - for (NSNumber* index in toPrune) { + + [cancelledOutstandingPuts enumerateKeysAndObjectsUsingBlock:^(NSNumber *index, FOutstandingPut *outstandingPut, BOOL *stop) { + // `onCompleteBlock:` may invoke `rerunTransactionsForPath:` and enqueue new writes. We defer calling + // it until we have finished enumerating all existing writes. + outstandingPut.onCompleteBlock(kFTransactionDisconnect, @"Client was disconnected while running a transaction"); [self.outstandingPuts removeObjectForKey:index]; - } + }]; } - (void) onDataPushWithAction:(NSString *)action andBody:(NSDictionary *)body { -- cgit v1.2.3