aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Sebastian Schmidt <mrschmidt@google.com>2017-11-29 17:00:03 -0800
committerGravatar Sebastian Schmidt <mrschmidt@google.com>2017-11-29 17:23:07 -0800
commit5db88f16617e2ef4c313dba4d5a7f91d31e66c8d (patch)
tree7f0a932addcc180f9e0a7ecae0e6e6b5c45cf73c
parent65d47c73b32fc2ccfd1a437a44b020c2b33a9ae3 (diff)
Fixing race in FSTWriteStream
-rw-r--r--Firestore/Source/Remote/FSTStream.m12
-rw-r--r--Firestore/Source/Util/FSTDispatchQueue.m5
2 files changed, 10 insertions, 7 deletions
diff --git a/Firestore/Source/Remote/FSTStream.m b/Firestore/Source/Remote/FSTStream.m
index 6cce921..bf54a6b 100644
--- a/Firestore/Source/Remote/FSTStream.m
+++ b/Firestore/Source/Remote/FSTStream.m
@@ -381,17 +381,17 @@ static const NSTimeInterval kIdleTimeout = 60.0;
_messageReceived = NO;
_rpc = nil;
- // If the caller explicitly requested a stream stop, don't notify them of a closing stream (it
- // could trigger undesirable recovery logic, etc.).
- if (finalState != FSTStreamStateStopped) {
- [self notifyStreamInterruptedWithError:error];
- }
-
// Clear the delegates to avoid any possible bleed through of events from GRPC.
FSTAssert(_delegate,
@"closeWithFinalState should only be called for a started stream that has an active "
@"delegate.");
_delegate = nil;
+
+ // If the caller explicitly requested a stream stop, don't notify them of a closing stream (it
+ // could trigger undesirable recovery logic, etc.).
+ if (finalState != FSTStreamStateStopped) {
+ [self notifyStreamInterruptedWithError:error];
+ }
}
- (void)stop {
diff --git a/Firestore/Source/Util/FSTDispatchQueue.m b/Firestore/Source/Util/FSTDispatchQueue.m
index 8c953fe..2c8ee55 100644
--- a/Firestore/Source/Util/FSTDispatchQueue.m
+++ b/Firestore/Source/Util/FSTDispatchQueue.m
@@ -58,7 +58,10 @@ NS_ASSUME_NONNULL_BEGIN
- (void)dispatchAfterDelay:(NSTimeInterval)delay block:(void (^)(void))block {
dispatch_time_t delayNs = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC));
- dispatch_after(delayNs, self.queue, block);
+ dispatch_after(delayNs, self.queue, ^() {
+ // Make sure that we prioritize tasks that are already queued for immediate execution.
+ [self dispatchAsyncAllowingSameQueue:block];
+ });
}
#pragma mark - Private Methods