diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2022-05-31 14:16:30 +0200 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2022-06-08 12:31:16 +0200 |
| commit | 8a3bc95854654a1c3758ca9dd1d8f85ea4ba3775 (patch) | |
| tree | 724d7d8875738ff4b502b846c81421fa0f32d837 | |
| parent | 1cdc1610be9cd4e2f7913345955568bda0d67cd9 (diff) | |
| download | mullvadvpn-8a3bc95854654a1c3758ca9dd1d8f85ea4ba3775.tar.xz mullvadvpn-8a3bc95854654a1c3758ca9dd1d8f85ea4ba3775.zip | |
Switch to mutually exclusive condition
4 files changed, 45 insertions, 169 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj index 4056bbb17f..813d27349b 100644 --- a/ios/MullvadVPN.xcodeproj/project.pbxproj +++ b/ios/MullvadVPN.xcodeproj/project.pbxproj @@ -21,7 +21,6 @@ 58095C552760F02500890776 /* UpdateAddressCacheOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58095C542760F02500890776 /* UpdateAddressCacheOperation.swift */; }; 58095C572760F47900890776 /* api-ip-address.json in Resources */ = {isa = PBXBuildFile; fileRef = 58095C562760F47900890776 /* api-ip-address.json */; }; 58095C592762155700890776 /* RESTRetryStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58095C582762155700890776 /* RESTRetryStrategy.swift */; }; - 580EE20624B3222200F9D8A1 /* ExclusivityController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 580EE20524B3222200F9D8A1 /* ExclusivityController.swift */; }; 580EE22424B3243100F9D8A1 /* AsyncBlockOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 580EE22324B3243100F9D8A1 /* AsyncBlockOperation.swift */; }; 580F8B8328197881002E0998 /* TunnelSettingsV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 580F8B8228197881002E0998 /* TunnelSettingsV2.swift */; }; 580F8B8428197884002E0998 /* TunnelSettingsV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 580F8B8228197881002E0998 /* TunnelSettingsV2.swift */; }; @@ -86,7 +85,6 @@ 5846227126E229F20035F7C2 /* AppStoreSubscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5846227026E229F20035F7C2 /* AppStoreSubscription.swift */; }; 5846227326E22A160035F7C2 /* AppStorePaymentObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5846227226E22A160035F7C2 /* AppStorePaymentObserver.swift */; }; 5846227726E22A7C0035F7C2 /* AppStorePaymentManagerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5846227626E22A7C0035F7C2 /* AppStorePaymentManagerDelegate.swift */; }; - 5846227A26E24F1F0035F7C2 /* ExclusivityController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 580EE20524B3222200F9D8A1 /* ExclusivityController.swift */; }; 584789BE264D4A2A000E45FB /* le_root_cert.cer in Resources */ = {isa = PBXBuildFile; fileRef = 584789B7264D4A2A000E45FB /* le_root_cert.cer */; }; 584789E026529D72000E45FB /* SSLPinningURLSessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 584789DF26529D72000E45FB /* SSLPinningURLSessionDelegate.swift */; }; 584789EC2652A1A2000E45FB /* Logging in Frameworks */ = {isa = PBXBuildFile; productRef = 584789EB2652A1A2000E45FB /* Logging */; }; @@ -346,7 +344,6 @@ 58095C542760F02500890776 /* UpdateAddressCacheOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateAddressCacheOperation.swift; sourceTree = "<group>"; }; 58095C562760F47900890776 /* api-ip-address.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "api-ip-address.json"; sourceTree = "<group>"; }; 58095C582762155700890776 /* RESTRetryStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RESTRetryStrategy.swift; sourceTree = "<group>"; }; - 580EE20524B3222200F9D8A1 /* ExclusivityController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExclusivityController.swift; sourceTree = "<group>"; }; 580EE22324B3243100F9D8A1 /* AsyncBlockOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncBlockOperation.swift; sourceTree = "<group>"; }; 580F8B8228197881002E0998 /* TunnelSettingsV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelSettingsV2.swift; sourceTree = "<group>"; }; 580F8B8528197958002E0998 /* DNSSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DNSSettings.swift; sourceTree = "<group>"; }; @@ -618,7 +615,6 @@ children = ( 580EE22324B3243100F9D8A1 /* AsyncBlockOperation.swift */, 58E973DD24850EB600096F90 /* AsyncOperation.swift */, - 580EE20524B3222200F9D8A1 /* ExclusivityController.swift */, 589D28782846250500F9A7B3 /* AsyncOperationQueue.swift */, 589D28812846306C00F9A7B3 /* GroupOperation.swift */, 5840BE34279EDB16002836BA /* OperationCompletion.swift */, @@ -1227,7 +1223,6 @@ 583E1E1B2848DE1C004838B3 /* ResultOperation+Fallible.swift in Sources */, 5857F23024C843ED00CF6F47 /* ChainedError.swift in Sources */, 58A8BE81239FBE62006B74AC /* IPEndpoint.swift in Sources */, - 5846227A26E24F1F0035F7C2 /* ExclusivityController.swift in Sources */, 58871D2325D535D2002297FA /* IPAddressRange+Codable.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1353,7 +1348,6 @@ 584D26BF270C550B004EA533 /* AnyIPAddress.swift in Sources */, 5862805422428EF100F5A6E1 /* TranslucentButtonBlurView.swift in Sources */, 587EB66A270EFACB00123C75 /* CharacterSet+IPAddress.swift in Sources */, - 580EE20624B3222200F9D8A1 /* ExclusivityController.swift in Sources */, 5888AD83227B11080051EB06 /* SelectLocationCell.swift in Sources */, 585DA89326B0323E00B8C587 /* TunnelIPCRequest.swift in Sources */, 5891BF1C25E3E3EB006D6FB0 /* Bundle+ProductVersion.swift in Sources */, diff --git a/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManager.swift b/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManager.swift index d035332eef..a8b56a8921 100644 --- a/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManager.swift +++ b/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManager.swift @@ -31,8 +31,6 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver { private let apiProxy = REST.ProxyFactory.shared.createAPIProxy() private let accountsProxy = REST.ProxyFactory.shared.createAccountsProxy() - private let exclusivityController = ExclusivityController() - private let paymentQueue: SKPaymentQueue private var observerList = ObserverList<AppStorePaymentObserver>() @@ -102,9 +100,11 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver { func requestProducts(with productIdentifiers: Set<AppStoreSubscription>, completionHandler: @escaping (OperationCompletion<SKProductsResponse, Swift.Error>) -> Void) -> Cancellable { let productIdentifiers = productIdentifiers.productIdentifiersSet - let operation = ProductsRequestOperation(productIdentifiers: productIdentifiers, completionHandler: completionHandler) - - exclusivityController.addOperation(operation, categories: [OperationCategory.productsRequest]) + let operation = ProductsRequestOperation( + productIdentifiers: productIdentifiers, + completionHandler: completionHandler + ) + operation.addCondition(MutuallyExclusive(category: OperationCategory.productsRequest)) operationQueue.addOperation(operation) @@ -197,7 +197,9 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver { UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier) } - exclusivityController.addOperation(operation, categories: [OperationCategory.sendAppStoreReceipt]) + operation.addCondition( + MutuallyExclusive(category: OperationCategory.sendAppStoreReceipt) + ) operationQueue.addOperation(operation) diff --git a/ios/MullvadVPN/Operations/ExclusivityController.swift b/ios/MullvadVPN/Operations/ExclusivityController.swift deleted file mode 100644 index 5e8fdaf97f..0000000000 --- a/ios/MullvadVPN/Operations/ExclusivityController.swift +++ /dev/null @@ -1,117 +0,0 @@ -// -// ExclusivityController.swift -// MullvadVPN -// -// Created by pronebird on 06/07/2020. -// Copyright © 2020 Mullvad VPN AB. All rights reserved. -// - -import Foundation - -class ExclusivityController: NSObject { - private let lock = NSLock() - private var operations: [String: [Operation]] = [:] - private var categoriesByOperation: [Operation: [String]] = [:] - - func addOperation(_ operation: Operation, categories: [String]) { - lock.lock() - - categories.forEach { category in - addOperation(operation, category: category) - } - - addObserverIfNeeded(operation: operation, categories: categories) - - lock.unlock() - } - - func removeOperation(_ operation: Operation, categories: [String]) { - lock.lock() - - categories.forEach { category in - removeOperation(operation, category: category) - } - - removeObserverIfNeeded(operation: operation, categories: categories) - - lock.unlock() - } - - override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { - if let operation = object as? Operation, keyPath == "isFinished" { - operationDidFinish(operation) - } else { - super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) - } - } - - // MARK: - Private - - private func addOperation(_ operation: Operation, category: String) { - var operationsWithThisCategory = operations[category] ?? [] - - if let last = operationsWithThisCategory.last { - operation.addDependency(last) - } - - operationsWithThisCategory.append(operation) - - operations[category] = operationsWithThisCategory - } - - private func removeOperation(_ operation: Operation, category: String) { - guard var operationsWithThisCategory = operations[category], - let index = operationsWithThisCategory.firstIndex(of: operation) else { return } - - operationsWithThisCategory.remove(at: index) - - if operationsWithThisCategory.isEmpty { - operations.removeValue(forKey: category) - } else { - operations[category] = operationsWithThisCategory - } - } - - private func addObserverIfNeeded(operation: Operation, categories: [String]) { - let existingCategories = categoriesByOperation[operation] ?? [] - let newCategories = existingCategories + categories - - if existingCategories.isEmpty && !newCategories.isEmpty { - operation.addObserver(self, forKeyPath: "isFinished", options: .new, context: nil) - } - - if !newCategories.isEmpty { - categoriesByOperation[operation] = newCategories - } - } - - private func removeObserverIfNeeded(operation: Operation, categories: [String]) { - guard var newCategories = categoriesByOperation[operation] else { return } - - newCategories.removeAll { s in - categories.contains(s) - } - - if newCategories.isEmpty { - operation.removeObserver(self, forKeyPath: "isFinished", context: nil) - - categoriesByOperation.removeValue(forKey: operation) - } else { - categoriesByOperation[operation] = newCategories - } - } - - private func operationDidFinish(_ operation: Operation) { - lock.lock() - - let operationCategories = categoriesByOperation[operation] ?? [] - - removeObserverIfNeeded(operation: operation, categories: operationCategories) - - operationCategories.forEach { category in - removeOperation(operation, category: category) - } - - lock.unlock() - } -} diff --git a/ios/MullvadVPN/TunnelManager/TunnelManager.swift b/ios/MullvadVPN/TunnelManager/TunnelManager.swift index a0996867aa..f97c8da036 100644 --- a/ios/MullvadVPN/TunnelManager/TunnelManager.swift +++ b/ios/MullvadVPN/TunnelManager/TunnelManager.swift @@ -61,7 +61,6 @@ final class TunnelManager: TunnelManagerStateDelegate { private let logger = Logger(label: "TunnelManager") private let stateQueue = DispatchQueue(label: "TunnelManager.stateQueue") - private let exclusivityController = ExclusivityController() private let operationQueue = AsyncOperationQueue() private var statusObserver: Tunnel.StatusBlockObserver? @@ -223,32 +222,21 @@ final class TunnelManager: TunnelManagerStateDelegate { completionHandler(completion.error) } } + loadTunnelOperation.addDependency(migrateSettingsOperation) - let backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask( - withName: "Load tunnel configuration" - ) { - // no-op - } - - loadTunnelOperation.completionBlock = { - UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier) - } - - exclusivityController.addOperation(migrateSettingsOperation, categories: [ - OperationCategory.changeTunnelSettings + let groupOperation = GroupOperation(operations: [ + migrateSettingsOperation, loadTunnelOperation ]) - exclusivityController.addOperation(loadTunnelOperation, categories: [ - OperationCategory.manageTunnelProvider, - OperationCategory.changeTunnelSettings - ]) - loadTunnelOperation.addDependency(migrateSettingsOperation) + groupOperation.addCondition( + MutuallyExclusive(category: OperationCategory.manageTunnelProvider) + ) + groupOperation.addCondition( + MutuallyExclusive(category: OperationCategory.changeTunnelSettings) + ) - operationQueue.addOperations([ - migrateSettingsOperation, - loadTunnelOperation - ], waitUntilFinished: false) + operationQueue.addOperation(groupOperation) } func startTunnel() { @@ -280,8 +268,7 @@ final class TunnelManager: TunnelManagerStateDelegate { operation.completionBlock = { UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier) } - - exclusivityController.addOperation(operation, categories: [OperationCategory.manageTunnelProvider]) + operation.addCondition(MutuallyExclusive(category: OperationCategory.manageTunnelProvider)) operationQueue.addOperation(operation) } @@ -313,7 +300,7 @@ final class TunnelManager: TunnelManagerStateDelegate { UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier) } - exclusivityController.addOperation(operation, categories: [OperationCategory.manageTunnelProvider]) + operation.addCondition(MutuallyExclusive(category: OperationCategory.manageTunnelProvider)) operationQueue.addOperation(operation) } @@ -353,7 +340,9 @@ final class TunnelManager: TunnelManagerStateDelegate { UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier) } - exclusivityController.addOperation(operation, categories: [OperationCategory.manageTunnelProvider]) + operation.addCondition( + MutuallyExclusive(category: OperationCategory.manageTunnelProvider) + ) operationQueue.addOperation(operation) } @@ -397,10 +386,12 @@ final class TunnelManager: TunnelManagerStateDelegate { UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier) } - exclusivityController.addOperation(operation, categories: [ - OperationCategory.manageTunnelProvider, - OperationCategory.changeTunnelSettings - ]) + operation.addCondition( + MutuallyExclusive(category: OperationCategory.manageTunnelProvider) + ) + operation.addCondition( + MutuallyExclusive(category: OperationCategory.changeTunnelSettings) + ) operationQueue.addOperation(operation) } @@ -431,9 +422,9 @@ final class TunnelManager: TunnelManagerStateDelegate { UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier) } - exclusivityController.addOperation(operation, categories: [ - OperationCategory.changeTunnelSettings - ]) + operation.addCondition( + MutuallyExclusive(category: OperationCategory.changeTunnelSettings) + ) operationQueue.addOperation(operation) } @@ -456,9 +447,9 @@ final class TunnelManager: TunnelManagerStateDelegate { UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier) } - exclusivityController.addOperation(operation, categories: [ - OperationCategory.changeTunnelSettings - ]) + operation.addCondition( + MutuallyExclusive(category: OperationCategory.changeTunnelSettings) + ) operationQueue.addOperation(operation) @@ -501,7 +492,9 @@ final class TunnelManager: TunnelManagerStateDelegate { UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier) } - exclusivityController.addOperation(operation, categories: [OperationCategory.changeTunnelSettings]) + operation.addCondition( + MutuallyExclusive(category: OperationCategory.changeTunnelSettings) + ) operationQueue.addOperation(operation) } @@ -545,7 +538,9 @@ final class TunnelManager: TunnelManagerStateDelegate { UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier) } - exclusivityController.addOperation(operation, categories: [OperationCategory.changeTunnelSettings]) + operation.addCondition( + MutuallyExclusive(category: OperationCategory.changeTunnelSettings) + ) operationQueue.addOperation(operation) @@ -678,7 +673,9 @@ final class TunnelManager: TunnelManagerStateDelegate { self.startTunnel() } - exclusivityController.addOperation(operation, categories: [OperationCategory.tunnelStateUpdate]) + operation.addCondition( + MutuallyExclusive(category: OperationCategory.tunnelStateUpdate) + ) // Cancel last VPN status mapping operation lastMapConnectionStatusOperation?.cancel() @@ -735,7 +732,7 @@ final class TunnelManager: TunnelManagerStateDelegate { UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier) } - exclusivityController.addOperation(operation, categories: [OperationCategory.changeTunnelSettings]) + operation.addCondition(MutuallyExclusive(category: OperationCategory.changeTunnelSettings)) operationQueue.addOperation(operation) } |
