summaryrefslogtreecommitdiff
path: root/StoneIsland/platforms/ios/Pods/FirebaseCrashlytics/Crashlytics/Shared/FIRCLSOperation/FIRCLSCompoundOperation.m
diff options
context:
space:
mode:
Diffstat (limited to 'StoneIsland/platforms/ios/Pods/FirebaseCrashlytics/Crashlytics/Shared/FIRCLSOperation/FIRCLSCompoundOperation.m')
-rw-r--r--StoneIsland/platforms/ios/Pods/FirebaseCrashlytics/Crashlytics/Shared/FIRCLSOperation/FIRCLSCompoundOperation.m165
1 files changed, 165 insertions, 0 deletions
diff --git a/StoneIsland/platforms/ios/Pods/FirebaseCrashlytics/Crashlytics/Shared/FIRCLSOperation/FIRCLSCompoundOperation.m b/StoneIsland/platforms/ios/Pods/FirebaseCrashlytics/Crashlytics/Shared/FIRCLSOperation/FIRCLSCompoundOperation.m
new file mode 100644
index 00000000..92bd06b1
--- /dev/null
+++ b/StoneIsland/platforms/ios/Pods/FirebaseCrashlytics/Crashlytics/Shared/FIRCLSOperation/FIRCLSCompoundOperation.m
@@ -0,0 +1,165 @@
+// Copyright 2019 Google
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#import "Crashlytics/Shared/FIRCLSOperation/FIRCLSCompoundOperation.h"
+
+#import "Crashlytics/Shared/FIRCLSOperation/FIRCLSFABAsyncOperation_Private.h"
+
+#define FIRCLS_DISPATCH_QUEUES_AS_OBJECTS OS_OBJECT_USE_OBJC_RETAIN_RELEASE
+
+const NSUInteger FIRCLSCompoundOperationErrorCodeCancelled = UINT_MAX - 1;
+const NSUInteger FIRCLSCompoundOperationErrorCodeSuboperationFailed = UINT_MAX - 2;
+
+NSString *const FIRCLSCompoundOperationErrorUserInfoKeyUnderlyingErrors =
+ @"com.google.firebase.crashlytics.FIRCLSCompoundOperation.error.user-info-key.underlying-"
+ @"errors";
+
+static NSString *const FIRCLSCompoundOperationErrorDomain =
+ @"com.google.firebase.crashlytics.FIRCLSCompoundOperation.error";
+static char *const FIRCLSCompoundOperationCountingQueueLabel =
+ "com.google.firebase.crashlytics.FIRCLSCompoundOperation.dispatch-queue.counting-queue";
+
+@interface FIRCLSCompoundOperation ()
+
+@property(strong, nonatomic, readwrite) NSOperationQueue *compoundQueue;
+@property(assign, nonatomic) NSUInteger completedOperations;
+@property(strong, nonatomic) NSMutableArray *errors;
+#if FIRCLS_DISPATCH_QUEUES_AS_OBJECTS
+@property(strong, nonatomic) dispatch_queue_t countingQueue;
+#else
+@property(assign, nonatomic) dispatch_queue_t countingQueue;
+#endif
+
+@end
+
+@implementation FIRCLSCompoundOperation
+
+- (instancetype)init {
+ self = [super init];
+ if (!self) {
+ return nil;
+ }
+
+ _compoundQueue = [[NSOperationQueue alloc] init];
+ _completedOperations = 0;
+ _errors = [NSMutableArray array];
+ _countingQueue =
+ dispatch_queue_create(FIRCLSCompoundOperationCountingQueueLabel, DISPATCH_QUEUE_SERIAL);
+
+ return self;
+}
+
+#if !FIRCLS_DISPATCH_QUEUES_AS_OBJECTS
+- (void)dealloc {
+ if (_countingQueue) {
+ dispatch_release(_countingQueue);
+ }
+}
+#endif
+
+- (void)main {
+ for (FIRCLSFABAsyncOperation *operation in self.operations) {
+ [self injectCompoundAsyncCompletionInOperation:operation];
+ [self injectCompoundSyncCompletionInOperation:operation];
+
+ [self.compoundQueue addOperation:operation];
+ }
+}
+
+- (void)cancel {
+ if (self.compoundQueue.operations.count > 0) {
+ [self.compoundQueue cancelAllOperations];
+ dispatch_sync(self.countingQueue, ^{
+ [self attemptCompoundCompletion];
+ });
+ } else {
+ for (NSOperation *operation in self.operations) {
+ [operation cancel];
+ }
+
+ // we have to add the operations to the queue in order for their isFinished property to be set
+ // to true.
+ [self.compoundQueue addOperations:self.operations waitUntilFinished:NO];
+ }
+ [super cancel];
+}
+
+- (void)injectCompoundAsyncCompletionInOperation:(FIRCLSFABAsyncOperation *)operation {
+ __weak FIRCLSCompoundOperation *weakSelf = self;
+ FIRCLSFABAsyncOperationCompletionBlock originalAsyncCompletion = [operation.asyncCompletion copy];
+ FIRCLSFABAsyncOperationCompletionBlock completion = ^(NSError *error) {
+ __strong FIRCLSCompoundOperation *strongSelf = weakSelf;
+
+ if (originalAsyncCompletion) {
+ dispatch_sync(strongSelf.countingQueue, ^{
+ originalAsyncCompletion(error);
+ });
+ }
+
+ [strongSelf updateCompletionCountsWithError:error];
+ };
+ operation.asyncCompletion = completion;
+}
+
+- (void)injectCompoundSyncCompletionInOperation:(FIRCLSFABAsyncOperation *)operation {
+ __weak FIRCLSCompoundOperation *weakSelf = self;
+ void (^originalSyncCompletion)(void) = [operation.completionBlock copy];
+ void (^completion)(void) = ^{
+ __strong FIRCLSCompoundOperation *strongSelf = weakSelf;
+
+ if (originalSyncCompletion) {
+ dispatch_sync(strongSelf.countingQueue, ^{
+ originalSyncCompletion();
+ });
+ }
+
+ dispatch_sync(strongSelf.countingQueue, ^{
+ [strongSelf attemptCompoundCompletion];
+ });
+ };
+ operation.completionBlock = completion;
+}
+
+- (void)updateCompletionCountsWithError:(NSError *)error {
+ dispatch_sync(self.countingQueue, ^{
+ if (!error) {
+ self.completedOperations += 1;
+ } else {
+ [self.errors addObject:error];
+ }
+ });
+}
+
+- (void)attemptCompoundCompletion {
+ if (self.isCancelled) {
+ [self finishWithError:[NSError errorWithDomain:FIRCLSCompoundOperationErrorDomain
+ code:FIRCLSCompoundOperationErrorCodeCancelled
+ userInfo:@{
+ NSLocalizedDescriptionKey : [NSString
+ stringWithFormat:@"%@ cancelled", self.name]
+ }]];
+ self.asyncCompletion = nil;
+ } else if (self.completedOperations + self.errors.count == self.operations.count) {
+ NSError *error = nil;
+ if (self.errors.count > 0) {
+ error = [NSError
+ errorWithDomain:FIRCLSCompoundOperationErrorDomain
+ code:FIRCLSCompoundOperationErrorCodeSuboperationFailed
+ userInfo:@{FIRCLSCompoundOperationErrorUserInfoKeyUnderlyingErrors : self.errors}];
+ }
+ [self finishWithError:error];
+ }
+}
+
+@end