summaryrefslogtreecommitdiffhomepage
path: root/ios
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2019-12-03 17:04:16 +0100
committerAndrej Mihajlov <and@mullvad.net>2019-12-04 11:50:55 +0100
commitbe52f38567de1680025fffbc8a5b023c440a201e (patch)
tree3d8242e2e5ea243a1cad05f76adc89b8ae5cc5ad /ios
parent1cee8ea368e6b25bac96c9ceac36b6b8ada3df8b (diff)
downloadmullvadvpn-be52f38567de1680025fffbc8a5b023c440a201e.tar.xz
mullvadvpn-be52f38567de1680025fffbc8a5b023c440a201e.zip
Add MutuallyExclusive publisher
Diffstat (limited to 'ios')
-rw-r--r--ios/MullvadVPN/MutuallyExclusive.swift58
1 files changed, 58 insertions, 0 deletions
diff --git a/ios/MullvadVPN/MutuallyExclusive.swift b/ios/MullvadVPN/MutuallyExclusive.swift
new file mode 100644
index 0000000000..cb3803805a
--- /dev/null
+++ b/ios/MullvadVPN/MutuallyExclusive.swift
@@ -0,0 +1,58 @@
+//
+// MutuallyExclusive.swift
+// MullvadVPN
+//
+// Created by pronebird on 24/10/2019.
+// Copyright © 2019 Amagicom AB. All rights reserved.
+//
+
+import Combine
+import Foundation
+
+extension Publishers {
+
+ /// A publisher that blocks the given DispatchQueue until the produced publisher reported the
+ /// completion.
+ final class MutuallyExclusive<PublisherType, Context>: Publisher where PublisherType: Publisher, Context: Scheduler {
+
+ typealias Output = PublisherType.Output
+ typealias Failure = PublisherType.Failure
+
+ typealias MakePublisherBlock = () -> PublisherType
+
+ private let exclusivityQueue: Context
+ private let executionQueue: Context
+
+ private let createPublisher: MakePublisherBlock
+
+ init(exclusivityQueue: Context, executionQueue: Context, createPublisher: @escaping MakePublisherBlock) {
+ self.exclusivityQueue = exclusivityQueue
+ self.executionQueue = executionQueue
+ self.createPublisher = createPublisher
+ }
+
+ func receive<S>(subscriber: S) where S : Subscriber, S.Failure == Failure, S.Input == Output {
+ exclusivityQueue.schedule {
+ let sema = DispatchSemaphore(value: 0)
+ let releaseLock = {
+ _ = sema.signal()
+ }
+
+ self.executionQueue.schedule {
+ self.createPublisher()
+ .handleEvents(receiveCompletion: { _ in
+ releaseLock()
+ }, receiveCancel: {
+ releaseLock()
+ })
+ .subscribe(subscriber)
+ }
+
+ sema.wait()
+ }
+ }
+ }
+
+}
+
+typealias MutuallyExclusive = Publishers.MutuallyExclusive