From c64084f47ee704b2bc401e4e1d8bf35fe8f24e7b Mon Sep 17 00:00:00 2001 From: Sergey Bykov Date: Wed, 10 May 2017 09:09:03 +0200 Subject: [PATCH] Make erros aggregation in GroupOperation thread-safe This solves crashes when operationDidFinish delegate in GorupOperation is called at the same time for multiple child operations. --- PSOperations/GroupOperation.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/PSOperations/GroupOperation.swift b/PSOperations/GroupOperation.swift index bc38362..e43aa28 100644 --- a/PSOperations/GroupOperation.swift +++ b/PSOperations/GroupOperation.swift @@ -25,6 +25,7 @@ open class GroupOperation: Operation { fileprivate let internalQueue = OperationQueue() fileprivate let startingOperation = Foundation.BlockOperation(block: {}) fileprivate let finishingOperation = Foundation.BlockOperation(block: {}) + fileprivate let errorsLock = NSLock() fileprivate var aggregatedErrors = [NSError]() @@ -65,7 +66,9 @@ open class GroupOperation: Operation { of errors reported to observers and to the `finished(_:)` method. */ public final func aggregateError(_ error: NSError) { + errorsLock.lock() aggregatedErrors.append(error) + errorsLock.unlock() } open func operationDidFinish(_ operation: Foundation.Operation, withErrors errors: [NSError]) { @@ -100,7 +103,9 @@ extension GroupOperation: OperationQueueDelegate { } final public func operationQueue(_ operationQueue: OperationQueue, operationDidFinish operation: Foundation.Operation, withErrors errors: [NSError]) { + errorsLock.lock() aggregatedErrors.append(contentsOf: errors) + errorsLock.unlock() if operation === finishingOperation { internalQueue.isSuspended = true