From af1c3892cfa5501be590db996531e99872f04549 Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Thu, 1 Nov 2018 13:46:29 -0700 Subject: [PATCH 01/17] Allow tracking task ID to support reporting timeout error details When a timeout occurs while waiting for a sequence of tasks to finish execution, it is useful to understand which task was executing when the timeout occurred. Using an `Int` as task ID so the `SynchronizedSequenceExecutionHandle` can track it using the efficient lock-free `AtomicInt`, in order to minimize performance cost when tracking is enabled. --- Concurrency.xcodeproj/project.pbxproj | 59 +++++++++++++++++-- ...-Package.xcscheme => Concurrency.xcscheme} | 21 ++++--- .../xcschemes/ConcurrencyTests.xcscheme | 56 ++++++++++++++++++ .../Executor/ConcurrentSequenceExecutor.swift | 21 ++++++- .../Executor/SequenceExecutor.swift | 8 ++- Sources/Concurrency/Executor/Task.swift | 15 ++++- .../ConcurrentSequenceExecutorTests.swift | 12 ++-- 7 files changed, 167 insertions(+), 25 deletions(-) rename Concurrency.xcodeproj/xcshareddata/xcschemes/{Concurrency-Package.xcscheme => Concurrency.xcscheme} (83%) create mode 100644 Concurrency.xcodeproj/xcshareddata/xcschemes/ConcurrencyTests.xcscheme diff --git a/Concurrency.xcodeproj/project.pbxproj b/Concurrency.xcodeproj/project.pbxproj index 793f5e2..000cdc9 100644 --- a/Concurrency.xcodeproj/project.pbxproj +++ b/Concurrency.xcodeproj/project.pbxproj @@ -40,7 +40,7 @@ 41B94842210A4744007E59C8 /* Task.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Task.swift; sourceTree = ""; }; 41B94848210A4756007E59C8 /* ConcurrentSequenceExecutorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConcurrentSequenceExecutorTests.swift; sourceTree = ""; }; "Concurrency::Concurrency::Product" /* Concurrency.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Concurrency.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - "Concurrency::ConcurrencyTests::Product" /* ConcurrencyTests.xctest */ = {isa = PBXFileReference; lastKnownFileType = file; path = ConcurrencyTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + "Concurrency::ConcurrencyTests::Product" /* ConcurrencyTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = ConcurrencyTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; OBJ_10 /* AtomicInt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicInt.swift; sourceTree = ""; }; OBJ_11 /* AtomicReference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicReference.swift; sourceTree = ""; }; OBJ_12 /* CountDownLatch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CountDownLatch.swift; sourceTree = ""; }; @@ -193,7 +193,7 @@ OBJ_1 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 9999; + LastUpgradeCheck = 1000; }; buildConfigurationList = OBJ_2 /* Build configuration list for PBXProject "Concurrency" */; compatibilityVersion = "Xcode 3.2"; @@ -302,12 +302,38 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_NS_ASSERTIONS = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MACOSX_DEPLOYMENT_TARGET = 10.10; ONLY_ACTIVE_ARCH = YES; @@ -325,11 +351,36 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = s; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MACOSX_DEPLOYMENT_TARGET = 10.10; OTHER_SWIFT_FLAGS = "-DXcode"; @@ -345,7 +396,7 @@ OBJ_45 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PLATFORM_DIR)/Developer/Library/Frameworks", @@ -364,7 +415,7 @@ OBJ_46 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PLATFORM_DIR)/Developer/Library/Frameworks", diff --git a/Concurrency.xcodeproj/xcshareddata/xcschemes/Concurrency-Package.xcscheme b/Concurrency.xcodeproj/xcshareddata/xcschemes/Concurrency.xcscheme similarity index 83% rename from Concurrency.xcodeproj/xcshareddata/xcschemes/Concurrency-Package.xcscheme rename to Concurrency.xcodeproj/xcshareddata/xcschemes/Concurrency.xcscheme index f080dd8..61aba12 100644 --- a/Concurrency.xcodeproj/xcshareddata/xcschemes/Concurrency-Package.xcscheme +++ b/Concurrency.xcodeproj/xcshareddata/xcschemes/Concurrency.xcscheme @@ -1,6 +1,6 @@ - - - - @@ -70,6 +60,15 @@ savedToolIdentifier = "" useCustomWorkingDirectory = "NO" debugDocumentVersioning = "YES"> + + + + diff --git a/Concurrency.xcodeproj/xcshareddata/xcschemes/ConcurrencyTests.xcscheme b/Concurrency.xcodeproj/xcshareddata/xcschemes/ConcurrencyTests.xcscheme new file mode 100644 index 0000000..3aace45 --- /dev/null +++ b/Concurrency.xcodeproj/xcshareddata/xcschemes/ConcurrencyTests.xcscheme @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift b/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift index d20be3c..132dbae 100644 --- a/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift +++ b/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift @@ -27,8 +27,15 @@ public class ConcurrentSequenceExecutor: SequenceExecutor { /// - parameter name: The name of the executor. /// - parameter qos: The quality of service of this executor. This /// defaults to `userInitiated`. - public init(name: String, qos: DispatchQoS = .userInitiated) { + /// - parameter shouldTackTaskId: `true` if task IDs should be tracked + /// as tasks are executed. `false` otherwise. By tracking the task IDs, + /// if waiting on the completion of a task sequence times out, the + /// reported error contains the ID of the task that was being executed + /// when the timeout occurred. The tracking does incur a minor + /// performance cost. This value defaults to `false`. + public init(name: String, qos: DispatchQoS = .userInitiated, shouldTackTaskId: Bool = false) { taskQueue = DispatchQueue(label: "Executor.taskQueue-\(name)", qos: qos, attributes: .concurrent) + self.shouldTackTaskId = shouldTackTaskId } /// Execute a sequence of tasks concurrently from the given initial task. @@ -51,6 +58,7 @@ public class ConcurrentSequenceExecutor: SequenceExecutor { // MARK: - Private private let taskQueue: DispatchQueue + private let shouldTackTaskId: Bool private func execute(_ task: Task, with sequenceHandle: SynchronizedSequenceExecutionHandle, _ execution: @escaping (Task, Any) -> SequenceExecution) { taskQueue.async { @@ -58,6 +66,10 @@ public class ConcurrentSequenceExecutor: SequenceExecutor { return } + if self.shouldTackTaskId { + sequenceHandle.willBeginExecuting(taskId: task.id) + } + let result = task.typeErasedExecute() let nextExecution = execution(task, result) switch nextExecution { @@ -74,6 +86,7 @@ private class SynchronizedSequenceExecutionHandle: SequenceE private let latch = CountDownLatch(count: 1) private let didCancel = AtomicBool(initialValue: false) + private let currentTaskId = AtomicInt(initialValue: nonTrackingDefaultTaskId) // Use a lock to ensure result is properly accessed, since the read // `await` method may be invoked on a different thread than the write @@ -85,10 +98,14 @@ private class SynchronizedSequenceExecutionHandle: SequenceE return didCancel.value } + fileprivate func willBeginExecuting(taskId: Int) { + currentTaskId.value = taskId + } + fileprivate override func await(withTimeout timeout: TimeInterval?) throws -> SequenceResultType { let didComplete = latch.await(timeout: timeout) if !didComplete { - throw SequenceExecutionError.awaitTimeout + throw SequenceExecutionError.awaitTimeout(currentTaskId.value) } resultLock.lock() diff --git a/Sources/Concurrency/Executor/SequenceExecutor.swift b/Sources/Concurrency/Executor/SequenceExecutor.swift index 03c9568..d87e3f8 100644 --- a/Sources/Concurrency/Executor/SequenceExecutor.swift +++ b/Sources/Concurrency/Executor/SequenceExecutor.swift @@ -18,8 +18,12 @@ import Foundation /// Errors that can occur during a sequence execution. public enum SequenceExecutionError: Error { - /// The waiting on sequence completion timed out. - case awaitTimeout + /// The waiting on sequence completion timed out. The `Int` value + /// indicates the ID of the task that was being executed when the + /// timeout occurred. If the value is `nonTrackingDefaultTaskId`, + /// then the executor was not configured to track task IDs during + /// initialization. + case awaitTimeout(Int) } /// The handle of the execution of a sequence of tasks, that allows control diff --git a/Sources/Concurrency/Executor/Task.swift b/Sources/Concurrency/Executor/Task.swift index 46dea90..a969e75 100644 --- a/Sources/Concurrency/Executor/Task.swift +++ b/Sources/Concurrency/Executor/Task.swift @@ -16,12 +16,17 @@ import Foundation +public let nonTrackingDefaultTaskId = Int.min + /// An individual unit of work that can be executed in a concurrent /// environment by an executor. // Task cannot be generic since it needs to be referenced by the executor // class which cannot provide type information for specific tasks. public protocol Task { + /// A unique ID number identifying the task. + var id: Int { get } + /// Execute this task without any type information. /// /// - note: This method should only be used by internal executor @@ -41,8 +46,16 @@ public protocol Task { // wildcard generics. open class AbstractTask: Task { + /// A unique ID number identifying the task. + public let id: Int + /// Initializer. - public init() {} + /// + /// - parameter id: A unique ID number identifying the task. This value + /// defaults to `nonTrackingDefaultTaskId`. + public init(id: Int = nonTrackingDefaultTaskId) { + self.id = id + } /// Execute this task without any type information. /// diff --git a/Tests/ConcurrencyTests/Executor/ConcurrentSequenceExecutorTests.swift b/Tests/ConcurrencyTests/Executor/ConcurrentSequenceExecutorTests.swift index 3cd953c..866ddc8 100644 --- a/Tests/ConcurrencyTests/Executor/ConcurrentSequenceExecutorTests.swift +++ b/Tests/ConcurrencyTests/Executor/ConcurrentSequenceExecutorTests.swift @@ -122,14 +122,14 @@ class ConcurrentSequenceExecutorTests: XCTestCase { } func test_executeSequence_withNonTerminatingSequence_withTimeout_verifyAwaitTimeout() { - let executor = ConcurrentSequenceExecutor(name: "test_executeSequence_withNonTerminatingSequence_withTimeout_verifyAwaitTimeout") + let executor = ConcurrentSequenceExecutor(name: "test_executeSequence_withNonTerminatingSequence_withTimeout_verifyAwaitTimeout", shouldTackTaskId: true) - let sequencedTask = MockSelfRepeatingTask { + let sequencedTask = MockSelfRepeatingTask(id: 123) { return 0 } let handle = executor.executeSequence(from: sequencedTask) { _, _ -> SequenceExecution in - return .continueSequence(MockSelfRepeatingTask { + return .continueSequence(MockSelfRepeatingTask(id: 123) { return 0 }) } @@ -138,10 +138,11 @@ class ConcurrentSequenceExecutorTests: XCTestCase { let startTime = CACurrentMediaTime() do { _ = try handle.await(withTimeout: 0.5) - } catch SequenceExecutionError.awaitTimeout { + } catch SequenceExecutionError.awaitTimeout(let id) { didThrowError = true let endTime = CACurrentMediaTime() XCTAssertTrue((endTime - startTime) >= 0.5) + XCTAssertEqual(id, 123) } catch { XCTFail("Incorrect error thrown: \(error)") } @@ -154,8 +155,9 @@ class MockSelfRepeatingTask: AbstractTask { private let execution: () -> Int - init(execution: @escaping () -> Int) { + init(id: Int = nonTrackingDefaultTaskId, execution: @escaping () -> Int) { self.execution = execution + super.init(id: id) } override func execute() -> Int { From 5e595a8ebd803bd4bc6de742d90b57d7d2a3026e Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Fri, 2 Nov 2018 18:18:02 -0700 Subject: [PATCH 02/17] Fix typo in task ID tracking parameter --- .../Executor/ConcurrentSequenceExecutor.swift | 10 +++++----- .../Executor/ConcurrentSequenceExecutorTests.swift | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift b/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift index 132dbae..5a7be21 100644 --- a/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift +++ b/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift @@ -27,15 +27,15 @@ public class ConcurrentSequenceExecutor: SequenceExecutor { /// - parameter name: The name of the executor. /// - parameter qos: The quality of service of this executor. This /// defaults to `userInitiated`. - /// - parameter shouldTackTaskId: `true` if task IDs should be tracked + /// - parameter shouldTrackTaskId: `true` if task IDs should be tracked /// as tasks are executed. `false` otherwise. By tracking the task IDs, /// if waiting on the completion of a task sequence times out, the /// reported error contains the ID of the task that was being executed /// when the timeout occurred. The tracking does incur a minor /// performance cost. This value defaults to `false`. - public init(name: String, qos: DispatchQoS = .userInitiated, shouldTackTaskId: Bool = false) { + public init(name: String, qos: DispatchQoS = .userInitiated, shouldTrackTaskId: Bool = false) { taskQueue = DispatchQueue(label: "Executor.taskQueue-\(name)", qos: qos, attributes: .concurrent) - self.shouldTackTaskId = shouldTackTaskId + self.shouldTrackTaskId = shouldTrackTaskId } /// Execute a sequence of tasks concurrently from the given initial task. @@ -58,7 +58,7 @@ public class ConcurrentSequenceExecutor: SequenceExecutor { // MARK: - Private private let taskQueue: DispatchQueue - private let shouldTackTaskId: Bool + private let shouldTrackTaskId: Bool private func execute(_ task: Task, with sequenceHandle: SynchronizedSequenceExecutionHandle, _ execution: @escaping (Task, Any) -> SequenceExecution) { taskQueue.async { @@ -66,7 +66,7 @@ public class ConcurrentSequenceExecutor: SequenceExecutor { return } - if self.shouldTackTaskId { + if self.shouldTrackTaskId { sequenceHandle.willBeginExecuting(taskId: task.id) } diff --git a/Tests/ConcurrencyTests/Executor/ConcurrentSequenceExecutorTests.swift b/Tests/ConcurrencyTests/Executor/ConcurrentSequenceExecutorTests.swift index 866ddc8..7936e36 100644 --- a/Tests/ConcurrencyTests/Executor/ConcurrentSequenceExecutorTests.swift +++ b/Tests/ConcurrencyTests/Executor/ConcurrentSequenceExecutorTests.swift @@ -122,7 +122,7 @@ class ConcurrentSequenceExecutorTests: XCTestCase { } func test_executeSequence_withNonTerminatingSequence_withTimeout_verifyAwaitTimeout() { - let executor = ConcurrentSequenceExecutor(name: "test_executeSequence_withNonTerminatingSequence_withTimeout_verifyAwaitTimeout", shouldTackTaskId: true) + let executor = ConcurrentSequenceExecutor(name: "test_executeSequence_withNonTerminatingSequence_withTimeout_verifyAwaitTimeout", shouldTrackTaskId: true) let sequencedTask = MockSelfRepeatingTask(id: 123) { return 0 From ff403944d1fd6ee4e360f9af00717f242142f457 Mon Sep 17 00:00:00 2001 From: Cameron Mc Gorian Date: Tue, 13 Nov 2018 19:25:24 +0100 Subject: [PATCH 03/17] Set bundle version (#18) * Set bundle version to 1.0 * Update to 0.6.1 * Update * Revert change to CFBundleShortVersionString * Change version number --- Concurrency.xcodeproj/Concurrency_Info.plist | 41 ++++++++++---------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/Concurrency.xcodeproj/Concurrency_Info.plist b/Concurrency.xcodeproj/Concurrency_Info.plist index 57ada9f..2426d46 100644 --- a/Concurrency.xcodeproj/Concurrency_Info.plist +++ b/Concurrency.xcodeproj/Concurrency_Info.plist @@ -1,25 +1,26 @@ + - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSPrincipalClass - + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 0.6.1 + CFBundleSignature + ???? + CFBundleVersion + 0.6.1 + NSPrincipalClass + From 5911d0150114a095f8b906af635c6f7e0999279b Mon Sep 17 00:00:00 2001 From: Richard Howell Date: Fri, 30 Nov 2018 14:54:31 -0800 Subject: [PATCH 04/17] add an option to limit max concurrency (#21) * add an option to limit max concurrency * default to Int.max concurrent tasks --- .../Executor/ConcurrentSequenceExecutor.swift | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift b/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift index 5a7be21..2409976 100644 --- a/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift +++ b/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift @@ -33,8 +33,11 @@ public class ConcurrentSequenceExecutor: SequenceExecutor { /// reported error contains the ID of the task that was being executed /// when the timeout occurred. The tracking does incur a minor /// performance cost. This value defaults to `false`. - public init(name: String, qos: DispatchQoS = .userInitiated, shouldTrackTaskId: Bool = false) { + /// - parameter maxConcurrentTasks: limits the maximum number of tasks + /// run concurrently. Defaults to Int.max. + public init(name: String, qos: DispatchQoS = .userInitiated, shouldTrackTaskId: Bool = false, maxConcurrentTasks: Int = Int.max) { taskQueue = DispatchQueue(label: "Executor.taskQueue-\(name)", qos: qos, attributes: .concurrent) + taskSemaphore = DispatchSemaphore(value: maxConcurrentTasks) self.shouldTrackTaskId = shouldTrackTaskId } @@ -58,10 +61,16 @@ public class ConcurrentSequenceExecutor: SequenceExecutor { // MARK: - Private private let taskQueue: DispatchQueue + private let taskSemaphore: DispatchSemaphore private let shouldTrackTaskId: Bool private func execute(_ task: Task, with sequenceHandle: SynchronizedSequenceExecutionHandle, _ execution: @escaping (Task, Any) -> SequenceExecution) { + taskSemaphore.wait() taskQueue.async { + defer { + self.taskSemaphore.signal() + } + guard !sequenceHandle.isCancelled else { return } From 4c210141f542b33b5238d05c98c06e212e5ffc50 Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Mon, 3 Dec 2018 14:27:47 -0800 Subject: [PATCH 05/17] Avoid using semaphore if there is no concurrency limit (#22) Avoid paying the cost of calling the semaphore if no limit is set. --- .../Executor/ConcurrentSequenceExecutor.swift | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift b/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift index 2409976..2517174 100644 --- a/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift +++ b/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift @@ -33,11 +33,16 @@ public class ConcurrentSequenceExecutor: SequenceExecutor { /// reported error contains the ID of the task that was being executed /// when the timeout occurred. The tracking does incur a minor /// performance cost. This value defaults to `false`. - /// - parameter maxConcurrentTasks: limits the maximum number of tasks - /// run concurrently. Defaults to Int.max. - public init(name: String, qos: DispatchQoS = .userInitiated, shouldTrackTaskId: Bool = false, maxConcurrentTasks: Int = Int.max) { + /// - parameter maxConcurrentTasks: The optional maximum number of tasks + /// the executor can execute concurrently. `nil` if the executor should + /// not limit the maximum number of concurrent tasks. Defaults to `nil`. + public init(name: String, qos: DispatchQoS = .userInitiated, shouldTrackTaskId: Bool = false, maxConcurrentTasks: Int? = nil) { taskQueue = DispatchQueue(label: "Executor.taskQueue-\(name)", qos: qos, attributes: .concurrent) - taskSemaphore = DispatchSemaphore(value: maxConcurrentTasks) + if let maxConcurrentTasks = maxConcurrentTasks { + taskSemaphore = DispatchSemaphore(value: maxConcurrentTasks) + } else { + taskSemaphore = nil + } self.shouldTrackTaskId = shouldTrackTaskId } @@ -61,16 +66,18 @@ public class ConcurrentSequenceExecutor: SequenceExecutor { // MARK: - Private private let taskQueue: DispatchQueue - private let taskSemaphore: DispatchSemaphore + private let taskSemaphore: DispatchSemaphore? private let shouldTrackTaskId: Bool private func execute(_ task: Task, with sequenceHandle: SynchronizedSequenceExecutionHandle, _ execution: @escaping (Task, Any) -> SequenceExecution) { - taskSemaphore.wait() + taskSemaphore?.wait() taskQueue.async { - defer { - self.taskSemaphore.signal() + if let taskSemaphore = self.taskSemaphore { + defer { + taskSemaphore.signal() + } } - + guard !sequenceHandle.isCancelled else { return } From 9d7fd4b747248743d37d2b4c9fc8467be2ff328a Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Mon, 3 Dec 2018 14:40:08 -0800 Subject: [PATCH 06/17] Add build status, Carthage and license pills --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0eec186..8f95362 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # Swift Concurrency -[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fuber%2Fswift-concurrency.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fuber%2Fswift-concurrency?ref=badge_shield) + +[![Build Status](https://travis-ci.com/uber/swift-concurrency.svg?branch=master)](https://travis-ci.com/uber/swift-concurrency?branch=master) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) ## Contents From 08455688fc3528812c3fd60c9ebc83e22591fff5 Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Tue, 4 Dec 2018 12:07:40 -0800 Subject: [PATCH 07/17] Rename SerialSequenceExecutor (#23) Renames `SerialSequenceExecutor` to `ImmediateSerialSequenceExecutor` to better represent the execution is done immediately on the caller thread, since a `ConcurrentSequenceExecutor` limited to a maximum concurrency level of 1 would also be serial. --- Concurrency.xcodeproj/project.pbxproj | 8 ++++---- ...ecutor.swift => ImmediateSerialSequenceExecutor.swift} | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) rename Sources/Concurrency/Executor/{SerialSequenceExecutor.swift => ImmediateSerialSequenceExecutor.swift} (95%) diff --git a/Concurrency.xcodeproj/project.pbxproj b/Concurrency.xcodeproj/project.pbxproj index 000cdc9..ce49a40 100644 --- a/Concurrency.xcodeproj/project.pbxproj +++ b/Concurrency.xcodeproj/project.pbxproj @@ -7,7 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - 41B94843210A4744007E59C8 /* SerialSequenceExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41B9483F210A4744007E59C8 /* SerialSequenceExecutor.swift */; }; + 41B94843210A4744007E59C8 /* ImmediateSerialSequenceExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41B9483F210A4744007E59C8 /* ImmediateSerialSequenceExecutor.swift */; }; 41B94844210A4744007E59C8 /* SequenceExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41B94840210A4744007E59C8 /* SequenceExecutor.swift */; }; 41B94845210A4744007E59C8 /* ConcurrentSequenceExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41B94841210A4744007E59C8 /* ConcurrentSequenceExecutor.swift */; }; 41B94846210A4744007E59C8 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41B94842210A4744007E59C8 /* Task.swift */; }; @@ -34,7 +34,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 41B9483F210A4744007E59C8 /* SerialSequenceExecutor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SerialSequenceExecutor.swift; sourceTree = ""; }; + 41B9483F210A4744007E59C8 /* ImmediateSerialSequenceExecutor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImmediateSerialSequenceExecutor.swift; sourceTree = ""; }; 41B94840210A4744007E59C8 /* SequenceExecutor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SequenceExecutor.swift; sourceTree = ""; }; 41B94841210A4744007E59C8 /* ConcurrentSequenceExecutor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConcurrentSequenceExecutor.swift; sourceTree = ""; }; 41B94842210A4744007E59C8 /* Task.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Task.swift; sourceTree = ""; }; @@ -74,7 +74,7 @@ 41B9483E210A4744007E59C8 /* Executor */ = { isa = PBXGroup; children = ( - 41B9483F210A4744007E59C8 /* SerialSequenceExecutor.swift */, + 41B9483F210A4744007E59C8 /* ImmediateSerialSequenceExecutor.swift */, 41B94840210A4744007E59C8 /* SequenceExecutor.swift */, 41B94841210A4744007E59C8 /* ConcurrentSequenceExecutor.swift */, 41B94842210A4744007E59C8 /* Task.swift */, @@ -224,7 +224,7 @@ 41B94845210A4744007E59C8 /* ConcurrentSequenceExecutor.swift in Sources */, OBJ_28 /* AtomicInt.swift in Sources */, OBJ_29 /* AtomicReference.swift in Sources */, - 41B94843210A4744007E59C8 /* SerialSequenceExecutor.swift in Sources */, + 41B94843210A4744007E59C8 /* ImmediateSerialSequenceExecutor.swift in Sources */, OBJ_30 /* CountDownLatch.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Sources/Concurrency/Executor/SerialSequenceExecutor.swift b/Sources/Concurrency/Executor/ImmediateSerialSequenceExecutor.swift similarity index 95% rename from Sources/Concurrency/Executor/SerialSequenceExecutor.swift rename to Sources/Concurrency/Executor/ImmediateSerialSequenceExecutor.swift index 1245e65..667fc78 100644 --- a/Sources/Concurrency/Executor/SerialSequenceExecutor.swift +++ b/Sources/Concurrency/Executor/ImmediateSerialSequenceExecutor.swift @@ -17,20 +17,20 @@ import Foundation /// An executor that executes sequences of tasks serially from the -/// caller thread. +/// caller thread as soon as the execute method is invoked. /// /// - note: Generally this implementation should only be used for debugging /// purposes, as debugging highly concurrent task executions can be very /// challenging. Production code should use `ConcurrentSequenceExecutor`. /// - seeAlso: `SequenceExecutor`. /// - seeAlso: `Task`. -public class SerialSequenceExecutor: SequenceExecutor { +public class ImmediateSerialSequenceExecutor: SequenceExecutor { /// Initializer. public init() {} /// Execute a sequence of tasks serially from the given initial task - /// on the caller thread. + /// on the caller thread, immediately. /// /// - parameter initialTask: The root task of the sequence of tasks /// to be executed. From 7ead5bcc8ae4795809ab7cf5dd31537e0ea6fa50 Mon Sep 17 00:00:00 2001 From: Richard Howell Date: Mon, 10 Dec 2018 13:14:31 -0800 Subject: [PATCH 08/17] signal before recursion (#25) --- .../Executor/ConcurrentSequenceExecutor.swift | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift b/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift index 2517174..997c1a6 100644 --- a/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift +++ b/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift @@ -72,13 +72,8 @@ public class ConcurrentSequenceExecutor: SequenceExecutor { private func execute(_ task: Task, with sequenceHandle: SynchronizedSequenceExecutionHandle, _ execution: @escaping (Task, Any) -> SequenceExecution) { taskSemaphore?.wait() taskQueue.async { - if let taskSemaphore = self.taskSemaphore { - defer { - taskSemaphore.signal() - } - } - guard !sequenceHandle.isCancelled else { + self.taskSemaphore?.signal() return } @@ -88,6 +83,8 @@ public class ConcurrentSequenceExecutor: SequenceExecutor { let result = task.typeErasedExecute() let nextExecution = execution(task, result) + self.taskSemaphore?.signal() + switch nextExecution { case .continueSequence(let nextTask): self.execute(nextTask, with: sequenceHandle, execution) From 9c2d8fbdb7899acc3dc614510356684c01cc268b Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Thu, 13 Dec 2018 13:22:43 -0800 Subject: [PATCH 09/17] Fix AtomicInt usages of deprecated atomic APIs (#26) * Fix AtomicInt usages of deprecated atomic APIs As of iOS 10.0 and MacOS 10.12 the old `OSMemoryBarrier`, `OSAtomicCompareAndSwap64Barrier`, `OSAtomicIncrement64Barrier`, and `OSAtomicDecrement64Barrier, APIs are deprecated. The warnings suggested new APIs are C++ and are not accessible from Swift. `OSMemoryBarrier` can be directly replaced with `atomic_thread_fence(memory_order_seq_cst)` which is accessible from Swift. The rest of the suggested C++ APIs `atomic_fetch_add`, `atomic_fetch_sub`, and `atomic_compare_exchange_strong` are not accessible from Swift. This change creates a Objective-C wrapper for these C++ APIs, so Swift code can access them. * Update TravisCI to use Xcode 10.1 --- .gitignore | 1 + .travis.yml | 6 +- Concurrency.xcodeproj/Concurrency_Info.plist | 41 +- .../ObjCBridges/module.modulemap | 4 + Concurrency.xcodeproj/ObjCBridges_Info.plist | 25 + Concurrency.xcodeproj/project.pbxproj | 466 ++++++++++++------ .../contents.xcworkspacedata | 2 +- .../xcshareddata/WorkspaceSettings.xcsettings | 8 + .../xcschemes/Concurrency.xcscheme | 2 +- .../xcschemes/ConcurrencyTests.xcscheme | 2 +- Package.swift | 5 +- Sources/Concurrency/AtomicInt.swift | 50 +- Sources/ObjCBridges/AtomicBridges.m | 33 ++ .../ObjCBridges/include/AtomicBridges.h | 26 +- 14 files changed, 470 insertions(+), 201 deletions(-) create mode 100644 Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap create mode 100644 Concurrency.xcodeproj/ObjCBridges_Info.plist create mode 100644 Concurrency.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 Sources/ObjCBridges/AtomicBridges.m rename Tests/LinuxMain.swift => Sources/ObjCBridges/include/AtomicBridges.h (63%) diff --git a/.gitignore b/.gitignore index e944e9f..ca9af23 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ Packages/ Package.pins Package.resolved .build/ +.DS_Store diff --git a/.travis.yml b/.travis.yml index c1b3470..52fe3e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,10 @@ language: objective-c -osx_image: xcode9 +osx_image: xcode10.1 env: - ACTION=test PLATFORM=Mac DESTINATION='platform=OS X' - - ACTION=test PLATFORM=iOS DESTINATION='platform=iOS Simulator,name=iPhone 7' - - ACTION=test PLATFORM=tvOS DESTINATION='platform=tvOS Simulator,name=Apple TV 1080p' + - ACTION=test PLATFORM=iOS DESTINATION='platform=iOS Simulator,name=iPhone XS' + - ACTION=test PLATFORM=tvOS DESTINATION='platform=tvOS Simulator,name=Apple TV 4K' script: - swift test diff --git a/Concurrency.xcodeproj/Concurrency_Info.plist b/Concurrency.xcodeproj/Concurrency_Info.plist index 2426d46..57ada9f 100644 --- a/Concurrency.xcodeproj/Concurrency_Info.plist +++ b/Concurrency.xcodeproj/Concurrency_Info.plist @@ -1,26 +1,25 @@ - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - 0.6.1 - CFBundleSignature - ???? - CFBundleVersion - 0.6.1 - NSPrincipalClass - + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + diff --git a/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap b/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap new file mode 100644 index 0000000..b341525 --- /dev/null +++ b/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap @@ -0,0 +1,4 @@ +module ObjCBridges { + umbrella "/Users/yiw/Uber/GitHub/swift-concurrency/Sources/ObjCBridges/include" + export * +} diff --git a/Concurrency.xcodeproj/ObjCBridges_Info.plist b/Concurrency.xcodeproj/ObjCBridges_Info.plist new file mode 100644 index 0000000..57ada9f --- /dev/null +++ b/Concurrency.xcodeproj/ObjCBridges_Info.plist @@ -0,0 +1,25 @@ + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Concurrency.xcodeproj/project.pbxproj b/Concurrency.xcodeproj/project.pbxproj index ce49a40..21dd01d 100644 --- a/Concurrency.xcodeproj/project.pbxproj +++ b/Concurrency.xcodeproj/project.pbxproj @@ -7,133 +7,185 @@ objects = { /* Begin PBXBuildFile section */ - 41B94843210A4744007E59C8 /* ImmediateSerialSequenceExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41B9483F210A4744007E59C8 /* ImmediateSerialSequenceExecutor.swift */; }; - 41B94844210A4744007E59C8 /* SequenceExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41B94840210A4744007E59C8 /* SequenceExecutor.swift */; }; - 41B94845210A4744007E59C8 /* ConcurrentSequenceExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41B94841210A4744007E59C8 /* ConcurrentSequenceExecutor.swift */; }; - 41B94846210A4744007E59C8 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41B94842210A4744007E59C8 /* Task.swift */; }; - 41B94849210A4756007E59C8 /* ConcurrentSequenceExecutorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41B94848210A4756007E59C8 /* ConcurrentSequenceExecutorTests.swift */; }; - OBJ_27 /* AtomicBool.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* AtomicBool.swift */; }; - OBJ_28 /* AtomicInt.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_10 /* AtomicInt.swift */; }; - OBJ_29 /* AtomicReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_11 /* AtomicReference.swift */; }; - OBJ_30 /* CountDownLatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* CountDownLatch.swift */; }; - OBJ_48 /* AtomicBoolTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_15 /* AtomicBoolTests.swift */; }; - OBJ_49 /* AtomicIntTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_16 /* AtomicIntTests.swift */; }; - OBJ_50 /* AtomicReferenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_17 /* AtomicReferenceTests.swift */; }; - OBJ_51 /* CountDownLatchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_18 /* CountDownLatchTests.swift */; }; - OBJ_53 /* Concurrency.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "Concurrency::Concurrency::Product" /* Concurrency.framework */; }; + OBJ_40 /* AtomicBool.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* AtomicBool.swift */; }; + OBJ_41 /* AtomicInt.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_10 /* AtomicInt.swift */; }; + OBJ_42 /* AtomicReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_11 /* AtomicReference.swift */; }; + OBJ_43 /* CountDownLatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* CountDownLatch.swift */; }; + OBJ_44 /* ConcurrentSequenceExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_14 /* ConcurrentSequenceExecutor.swift */; }; + OBJ_45 /* ImmediateSerialSequenceExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_15 /* ImmediateSerialSequenceExecutor.swift */; }; + OBJ_46 /* SequenceExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_16 /* SequenceExecutor.swift */; }; + OBJ_47 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_17 /* Task.swift */; }; + OBJ_49 /* ObjCBridges.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "Concurrency::ObjCBridges::Product" /* ObjCBridges.framework */; }; + OBJ_68 /* AtomicBoolTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_25 /* AtomicBoolTests.swift */; }; + OBJ_69 /* AtomicIntTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_26 /* AtomicIntTests.swift */; }; + OBJ_70 /* AtomicReferenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_27 /* AtomicReferenceTests.swift */; }; + OBJ_71 /* CountDownLatchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_28 /* CountDownLatchTests.swift */; }; + OBJ_72 /* ConcurrentSequenceExecutorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_30 /* ConcurrentSequenceExecutorTests.swift */; }; + OBJ_74 /* Concurrency.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "Concurrency::Concurrency::Product" /* Concurrency.framework */; }; + OBJ_75 /* ObjCBridges.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "Concurrency::ObjCBridges::Product" /* ObjCBridges.framework */; }; + OBJ_82 /* AtomicBridges.m in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_19 /* AtomicBridges.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 412CDD2D20B88EAB00AF5890 /* PBXContainerItemProxy */ = { + 41B04ADA21C1E84C00328020 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = OBJ_1 /* Project object */; + proxyType = 1; + remoteGlobalIDString = "Concurrency::ObjCBridges"; + remoteInfo = ObjCBridges; + }; + 41B04ADB21C1E84C00328020 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = OBJ_1 /* Project object */; proxyType = 1; remoteGlobalIDString = "Concurrency::Concurrency"; remoteInfo = Concurrency; }; + 41B04ADC21C1E84C00328020 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = OBJ_1 /* Project object */; + proxyType = 1; + remoteGlobalIDString = "Concurrency::ObjCBridges"; + remoteInfo = ObjCBridges; + }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 41B9483F210A4744007E59C8 /* ImmediateSerialSequenceExecutor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImmediateSerialSequenceExecutor.swift; sourceTree = ""; }; - 41B94840210A4744007E59C8 /* SequenceExecutor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SequenceExecutor.swift; sourceTree = ""; }; - 41B94841210A4744007E59C8 /* ConcurrentSequenceExecutor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConcurrentSequenceExecutor.swift; sourceTree = ""; }; - 41B94842210A4744007E59C8 /* Task.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Task.swift; sourceTree = ""; }; - 41B94848210A4756007E59C8 /* ConcurrentSequenceExecutorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConcurrentSequenceExecutorTests.swift; sourceTree = ""; }; "Concurrency::Concurrency::Product" /* Concurrency.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Concurrency.framework; sourceTree = BUILT_PRODUCTS_DIR; }; "Concurrency::ConcurrencyTests::Product" /* ConcurrencyTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = ConcurrencyTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + "Concurrency::ObjCBridges::Product" /* ObjCBridges.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = ObjCBridges.framework; sourceTree = BUILT_PRODUCTS_DIR; }; OBJ_10 /* AtomicInt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicInt.swift; sourceTree = ""; }; OBJ_11 /* AtomicReference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicReference.swift; sourceTree = ""; }; OBJ_12 /* CountDownLatch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CountDownLatch.swift; sourceTree = ""; }; - OBJ_15 /* AtomicBoolTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicBoolTests.swift; sourceTree = ""; }; - OBJ_16 /* AtomicIntTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicIntTests.swift; sourceTree = ""; }; - OBJ_17 /* AtomicReferenceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicReferenceTests.swift; sourceTree = ""; }; - OBJ_18 /* CountDownLatchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CountDownLatchTests.swift; sourceTree = ""; }; + OBJ_14 /* ConcurrentSequenceExecutor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConcurrentSequenceExecutor.swift; sourceTree = ""; }; + OBJ_15 /* ImmediateSerialSequenceExecutor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImmediateSerialSequenceExecutor.swift; sourceTree = ""; }; + OBJ_16 /* SequenceExecutor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SequenceExecutor.swift; sourceTree = ""; }; + OBJ_17 /* Task.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Task.swift; sourceTree = ""; }; + OBJ_19 /* AtomicBridges.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AtomicBridges.m; sourceTree = ""; }; + OBJ_21 /* AtomicBridges.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AtomicBridges.h; sourceTree = ""; }; + OBJ_22 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; name = module.modulemap; path = "/Users/yiw/Uber/GitHub/swift-concurrency/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap"; sourceTree = ""; }; + OBJ_25 /* AtomicBoolTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicBoolTests.swift; sourceTree = ""; }; + OBJ_26 /* AtomicIntTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicIntTests.swift; sourceTree = ""; }; + OBJ_27 /* AtomicReferenceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicReferenceTests.swift; sourceTree = ""; }; + OBJ_28 /* CountDownLatchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CountDownLatchTests.swift; sourceTree = ""; }; + OBJ_30 /* ConcurrentSequenceExecutorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConcurrentSequenceExecutorTests.swift; sourceTree = ""; }; OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; OBJ_9 /* AtomicBool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicBool.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - OBJ_31 /* Frameworks */ = { + OBJ_48 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 0; files = ( + OBJ_49 /* ObjCBridges.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - OBJ_52 /* Frameworks */ = { + OBJ_73 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 0; + files = ( + OBJ_74 /* Concurrency.framework in Frameworks */, + OBJ_75 /* ObjCBridges.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + OBJ_83 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 0; files = ( - OBJ_53 /* Concurrency.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 41B9483E210A4744007E59C8 /* Executor */ = { + OBJ_13 /* Executor */ = { isa = PBXGroup; children = ( - 41B9483F210A4744007E59C8 /* ImmediateSerialSequenceExecutor.swift */, - 41B94840210A4744007E59C8 /* SequenceExecutor.swift */, - 41B94841210A4744007E59C8 /* ConcurrentSequenceExecutor.swift */, - 41B94842210A4744007E59C8 /* Task.swift */, + OBJ_14 /* ConcurrentSequenceExecutor.swift */, + OBJ_15 /* ImmediateSerialSequenceExecutor.swift */, + OBJ_16 /* SequenceExecutor.swift */, + OBJ_17 /* Task.swift */, ); path = Executor; sourceTree = ""; }; - 41B94847210A4756007E59C8 /* Executor */ = { + OBJ_18 /* ObjCBridges */ = { isa = PBXGroup; children = ( - 41B94848210A4756007E59C8 /* ConcurrentSequenceExecutorTests.swift */, + OBJ_19 /* AtomicBridges.m */, + OBJ_20 /* include */, ); - path = Executor; + name = ObjCBridges; + path = Sources/ObjCBridges; + sourceTree = SOURCE_ROOT; + }; + OBJ_20 /* include */ = { + isa = PBXGroup; + children = ( + OBJ_21 /* AtomicBridges.h */, + OBJ_22 /* module.modulemap */, + ); + path = include; sourceTree = ""; }; - OBJ_13 /* Tests */ = { + OBJ_23 /* Tests */ = { isa = PBXGroup; children = ( - OBJ_14 /* ConcurrencyTests */, + OBJ_24 /* ConcurrencyTests */, ); name = Tests; sourceTree = SOURCE_ROOT; }; - OBJ_14 /* ConcurrencyTests */ = { + OBJ_24 /* ConcurrencyTests */ = { isa = PBXGroup; children = ( - 41B94847210A4756007E59C8 /* Executor */, - OBJ_15 /* AtomicBoolTests.swift */, - OBJ_16 /* AtomicIntTests.swift */, - OBJ_17 /* AtomicReferenceTests.swift */, - OBJ_18 /* CountDownLatchTests.swift */, + OBJ_25 /* AtomicBoolTests.swift */, + OBJ_26 /* AtomicIntTests.swift */, + OBJ_27 /* AtomicReferenceTests.swift */, + OBJ_28 /* CountDownLatchTests.swift */, + OBJ_29 /* Executor */, ); name = ConcurrencyTests; path = Tests/ConcurrencyTests; sourceTree = SOURCE_ROOT; }; - OBJ_19 /* Products */ = { + OBJ_29 /* Executor */ = { + isa = PBXGroup; + children = ( + OBJ_30 /* ConcurrentSequenceExecutorTests.swift */, + ); + path = Executor; + sourceTree = ""; + }; + OBJ_31 /* Products */ = { isa = PBXGroup; children = ( "Concurrency::ConcurrencyTests::Product" /* ConcurrencyTests.xctest */, + "Concurrency::ObjCBridges::Product" /* ObjCBridges.framework */, "Concurrency::Concurrency::Product" /* Concurrency.framework */, ); name = Products; sourceTree = BUILT_PRODUCTS_DIR; }; - OBJ_5 = { + OBJ_5 /* */ = { isa = PBXGroup; children = ( OBJ_6 /* Package.swift */, OBJ_7 /* Sources */, - OBJ_13 /* Tests */, - OBJ_19 /* Products */, + OBJ_23 /* Tests */, + OBJ_31 /* Products */, ); + name = ""; sourceTree = ""; }; OBJ_7 /* Sources */ = { isa = PBXGroup; children = ( OBJ_8 /* Concurrency */, + OBJ_18 /* ObjCBridges */, ); name = Sources; sourceTree = SOURCE_ROOT; @@ -141,11 +193,11 @@ OBJ_8 /* Concurrency */ = { isa = PBXGroup; children = ( - 41B9483E210A4744007E59C8 /* Executor */, OBJ_9 /* AtomicBool.swift */, OBJ_10 /* AtomicInt.swift */, OBJ_11 /* AtomicReference.swift */, OBJ_12 /* CountDownLatch.swift */, + OBJ_13 /* Executor */, ); name = Concurrency; path = Sources/Concurrency; @@ -156,14 +208,15 @@ /* Begin PBXNativeTarget section */ "Concurrency::Concurrency" /* Concurrency */ = { isa = PBXNativeTarget; - buildConfigurationList = OBJ_23 /* Build configuration list for PBXNativeTarget "Concurrency" */; + buildConfigurationList = OBJ_36 /* Build configuration list for PBXNativeTarget "Concurrency" */; buildPhases = ( - OBJ_26 /* Sources */, - OBJ_31 /* Frameworks */, + OBJ_39 /* Sources */, + OBJ_48 /* Frameworks */, ); buildRules = ( ); dependencies = ( + OBJ_50 /* PBXTargetDependency */, ); name = Concurrency; productName = Concurrency; @@ -172,28 +225,53 @@ }; "Concurrency::ConcurrencyTests" /* ConcurrencyTests */ = { isa = PBXNativeTarget; - buildConfigurationList = OBJ_44 /* Build configuration list for PBXNativeTarget "ConcurrencyTests" */; + buildConfigurationList = OBJ_64 /* Build configuration list for PBXNativeTarget "ConcurrencyTests" */; buildPhases = ( - OBJ_47 /* Sources */, - OBJ_52 /* Frameworks */, + OBJ_67 /* Sources */, + OBJ_73 /* Frameworks */, ); buildRules = ( ); dependencies = ( - OBJ_54 /* PBXTargetDependency */, + OBJ_76 /* PBXTargetDependency */, + OBJ_77 /* PBXTargetDependency */, ); name = ConcurrencyTests; productName = ConcurrencyTests; productReference = "Concurrency::ConcurrencyTests::Product" /* ConcurrencyTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + "Concurrency::ObjCBridges" /* ObjCBridges */ = { + isa = PBXNativeTarget; + buildConfigurationList = OBJ_78 /* Build configuration list for PBXNativeTarget "ObjCBridges" */; + buildPhases = ( + OBJ_81 /* Sources */, + OBJ_83 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ObjCBridges; + productName = ObjCBridges; + productReference = "Concurrency::ObjCBridges::Product" /* ObjCBridges.framework */; + productType = "com.apple.product-type.framework"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ OBJ_1 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1000; + LastUpgradeCheck = 1010; + TargetAttributes = { + "Concurrency::Concurrency" = { + LastSwiftMigration = 1010; + }; + "Concurrency::ConcurrencyTests" = { + LastSwiftMigration = 1010; + }; + }; }; buildConfigurationList = OBJ_2 /* Build configuration list for PBXProject "Concurrency" */; compatibilityVersion = "Xcode 3.2"; @@ -202,102 +280,75 @@ knownRegions = ( en, ); - mainGroup = OBJ_5; - productRefGroup = OBJ_19 /* Products */; + mainGroup = OBJ_5 /* */; + productRefGroup = OBJ_31 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( "Concurrency::Concurrency" /* Concurrency */, "Concurrency::ConcurrencyTests" /* ConcurrencyTests */, + "Concurrency::ObjCBridges" /* ObjCBridges */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ - OBJ_26 /* Sources */ = { + OBJ_39 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 0; files = ( - 41B94846210A4744007E59C8 /* Task.swift in Sources */, - OBJ_27 /* AtomicBool.swift in Sources */, - 41B94844210A4744007E59C8 /* SequenceExecutor.swift in Sources */, - 41B94845210A4744007E59C8 /* ConcurrentSequenceExecutor.swift in Sources */, - OBJ_28 /* AtomicInt.swift in Sources */, - OBJ_29 /* AtomicReference.swift in Sources */, - 41B94843210A4744007E59C8 /* ImmediateSerialSequenceExecutor.swift in Sources */, - OBJ_30 /* CountDownLatch.swift in Sources */, + OBJ_40 /* AtomicBool.swift in Sources */, + OBJ_41 /* AtomicInt.swift in Sources */, + OBJ_42 /* AtomicReference.swift in Sources */, + OBJ_43 /* CountDownLatch.swift in Sources */, + OBJ_44 /* ConcurrentSequenceExecutor.swift in Sources */, + OBJ_45 /* ImmediateSerialSequenceExecutor.swift in Sources */, + OBJ_46 /* SequenceExecutor.swift in Sources */, + OBJ_47 /* Task.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - OBJ_47 /* Sources */ = { + OBJ_67 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 0; files = ( - OBJ_48 /* AtomicBoolTests.swift in Sources */, - OBJ_49 /* AtomicIntTests.swift in Sources */, - 41B94849210A4756007E59C8 /* ConcurrentSequenceExecutorTests.swift in Sources */, - OBJ_50 /* AtomicReferenceTests.swift in Sources */, - OBJ_51 /* CountDownLatchTests.swift in Sources */, + OBJ_68 /* AtomicBoolTests.swift in Sources */, + OBJ_69 /* AtomicIntTests.swift in Sources */, + OBJ_70 /* AtomicReferenceTests.swift in Sources */, + OBJ_71 /* CountDownLatchTests.swift in Sources */, + OBJ_72 /* ConcurrentSequenceExecutorTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + OBJ_81 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 0; + files = ( + OBJ_82 /* AtomicBridges.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - OBJ_54 /* PBXTargetDependency */ = { + OBJ_50 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = "Concurrency::ObjCBridges" /* ObjCBridges */; + targetProxy = 41B04ADA21C1E84C00328020 /* PBXContainerItemProxy */; + }; + OBJ_76 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = "Concurrency::Concurrency" /* Concurrency */; - targetProxy = 412CDD2D20B88EAB00AF5890 /* PBXContainerItemProxy */; + targetProxy = 41B04ADB21C1E84C00328020 /* PBXContainerItemProxy */; + }; + OBJ_77 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = "Concurrency::ObjCBridges" /* ObjCBridges */; + targetProxy = 41B04ADC21C1E84C00328020 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - OBJ_24 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ENABLE_TESTABILITY = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PLATFORM_DIR)/Developer/Library/Frameworks", - ); - HEADER_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = Concurrency.xcodeproj/Concurrency_Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; - OTHER_CFLAGS = "$(inherited)"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited)"; - PRODUCT_BUNDLE_IDENTIFIER = Concurrency; - PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SKIP_INSTALL = YES; - SWIFT_VERSION = 4.0; - TARGET_NAME = Concurrency; - }; - name = Debug; - }; - OBJ_25 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ENABLE_TESTABILITY = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PLATFORM_DIR)/Developer/Library/Frameworks", - ); - HEADER_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = Concurrency.xcodeproj/Concurrency_Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; - OTHER_CFLAGS = "$(inherited)"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited)"; - PRODUCT_BUNDLE_IDENTIFIER = Concurrency; - PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SKIP_INSTALL = YES; - SWIFT_VERSION = 4.0; - TARGET_NAME = Concurrency; - }; - name = Release; - }; OBJ_3 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -328,25 +379,85 @@ ENABLE_TESTABILITY = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MACOSX_DEPLOYMENT_TARGET = 10.10; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MACOSX_DEPLOYMENT_TARGET = 10.12; ONLY_ACTIVE_ARCH = YES; OTHER_SWIFT_FLAGS = "-DXcode"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "SWIFT_PACKAGE DEBUG"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; USE_HEADERMAP = NO; }; name = Debug; }; + OBJ_37 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ENABLE_TESTABILITY = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/Sources/ObjCBridges/include", + "$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges", + ); + INFOPLIST_FILE = Concurrency.xcodeproj/Concurrency_Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; + OTHER_CFLAGS = "$(inherited)"; + OTHER_LDFLAGS = "$(inherited)"; + OTHER_SWIFT_FLAGS = "$(inherited) -Xcc -fmodule-map-file=$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap"; + PRODUCT_BUNDLE_IDENTIFIER = Concurrency; + PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; + SWIFT_VERSION = 4.2; + TARGET_NAME = Concurrency; + }; + name = Debug; + }; + OBJ_38 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ENABLE_TESTABILITY = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/Sources/ObjCBridges/include", + "$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges", + ); + INFOPLIST_FILE = Concurrency.xcodeproj/Concurrency_Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; + OTHER_CFLAGS = "$(inherited)"; + OTHER_LDFLAGS = "$(inherited)"; + OTHER_SWIFT_FLAGS = "$(inherited) -Xcc -fmodule-map-file=$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap"; + PRODUCT_BUNDLE_IDENTIFIER = Concurrency; + PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; + SWIFT_VERSION = 4.2; + TARGET_NAME = Concurrency; + }; + name = Release; + }; OBJ_4 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -381,8 +492,8 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MACOSX_DEPLOYMENT_TARGET = 10.10; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MACOSX_DEPLOYMENT_TARGET = 10.12; OTHER_SWIFT_FLAGS = "-DXcode"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; @@ -393,44 +504,110 @@ }; name = Release; }; - OBJ_45 /* Debug */ = { + OBJ_65 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ENABLE_MODULES = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PLATFORM_DIR)/Developer/Library/Frameworks", ); - HEADER_SEARCH_PATHS = "$(inherited)"; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/Sources/ObjCBridges/include", + "$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges", + ); INFOPLIST_FILE = Concurrency.xcodeproj/ConcurrencyTests_Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks @loader_path/Frameworks"; OTHER_CFLAGS = "$(inherited)"; OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited)"; - SWIFT_VERSION = 4.0; + OTHER_SWIFT_FLAGS = "$(inherited) -Xcc -fmodule-map-file=$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; + SWIFT_VERSION = 4.2; TARGET_NAME = ConcurrencyTests; }; name = Debug; }; - OBJ_46 /* Release */ = { + OBJ_66 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ENABLE_MODULES = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PLATFORM_DIR)/Developer/Library/Frameworks", ); - HEADER_SEARCH_PATHS = "$(inherited)"; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/Sources/ObjCBridges/include", + "$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges", + ); INFOPLIST_FILE = Concurrency.xcodeproj/ConcurrencyTests_Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks @loader_path/Frameworks"; OTHER_CFLAGS = "$(inherited)"; OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited)"; - SWIFT_VERSION = 4.0; + OTHER_SWIFT_FLAGS = "$(inherited) -Xcc -fmodule-map-file=$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; + SWIFT_VERSION = 4.2; TARGET_NAME = ConcurrencyTests; }; name = Release; }; + OBJ_79 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEFINES_MODULE = NO; + ENABLE_TESTABILITY = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/Sources/ObjCBridges/include", + ); + INFOPLIST_FILE = Concurrency.xcodeproj/ObjCBridges_Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; + OTHER_CFLAGS = "$(inherited)"; + OTHER_LDFLAGS = "$(inherited)"; + OTHER_SWIFT_FLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = ObjCBridges; + PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; + TARGET_NAME = ObjCBridges; + }; + name = Debug; + }; + OBJ_80 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEFINES_MODULE = NO; + ENABLE_TESTABILITY = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/Sources/ObjCBridges/include", + ); + INFOPLIST_FILE = Concurrency.xcodeproj/ObjCBridges_Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; + OTHER_CFLAGS = "$(inherited)"; + OTHER_LDFLAGS = "$(inherited)"; + OTHER_SWIFT_FLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = ObjCBridges; + PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; + TARGET_NAME = ObjCBridges; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -443,20 +620,29 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - OBJ_23 /* Build configuration list for PBXNativeTarget "Concurrency" */ = { + OBJ_36 /* Build configuration list for PBXNativeTarget "Concurrency" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + OBJ_37 /* Debug */, + OBJ_38 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + OBJ_64 /* Build configuration list for PBXNativeTarget "ConcurrencyTests" */ = { isa = XCConfigurationList; buildConfigurations = ( - OBJ_24 /* Debug */, - OBJ_25 /* Release */, + OBJ_65 /* Debug */, + OBJ_66 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - OBJ_44 /* Build configuration list for PBXNativeTarget "ConcurrencyTests" */ = { + OBJ_78 /* Build configuration list for PBXNativeTarget "ObjCBridges" */ = { isa = XCConfigurationList; buildConfigurations = ( - OBJ_45 /* Debug */, - OBJ_46 /* Release */, + OBJ_79 /* Debug */, + OBJ_80 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Concurrency.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Concurrency.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 919434a..fe1aa71 100644 --- a/Concurrency.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/Concurrency.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,4 @@ - + \ No newline at end of file diff --git a/Concurrency.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Concurrency.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..a72dc2b --- /dev/null +++ b/Concurrency.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded + + + \ No newline at end of file diff --git a/Concurrency.xcodeproj/xcshareddata/xcschemes/Concurrency.xcscheme b/Concurrency.xcodeproj/xcshareddata/xcschemes/Concurrency.xcscheme index 61aba12..5c25636 100644 --- a/Concurrency.xcodeproj/xcshareddata/xcschemes/Concurrency.xcscheme +++ b/Concurrency.xcodeproj/xcshareddata/xcschemes/Concurrency.xcscheme @@ -1,6 +1,6 @@ Bool { - return OSAtomicCompareAndSwap64Barrier(Int64(expect), Int64(newValue), &wrappedValue) + var mutableExpected = expect + return AtomicBridges.compare(wrappedValueOpaquePointer, withExpected: UnsafeMutablePointer(&mutableExpected), andSwap: newValue) } /// Atomically increment the value and retrieve the new value. @@ -63,8 +65,13 @@ public class AtomicInt { /// - returns: The new value after incrementing. @discardableResult public func incrementAndGet() -> Int { - let result = OSAtomicIncrement64Barrier(&wrappedValue) - return Int(result) + while true { + let oldValue = self.value + let newValue = oldValue + 1 + if self.compareAndSet(expect: oldValue, newValue: newValue) { + return newValue + } + } } /// Atomically decrement the value and retrieve the new value. @@ -72,8 +79,13 @@ public class AtomicInt { /// - returns: The new value after decrementing. @discardableResult public func decrementAndGet() -> Int { - let result = OSAtomicDecrement64Barrier(&wrappedValue) - return Int(result) + while true { + let oldValue = self.value + let newValue = oldValue - 1 + if self.compareAndSet(expect: oldValue, newValue: newValue) { + return newValue + } + } } /// Atomically increment the value and retrieve the old value. @@ -81,13 +93,7 @@ public class AtomicInt { /// - returns: The old value before incrementing. @discardableResult public func getAndIncrement() -> Int { - while true { - let oldValue = self.value - let newValue = oldValue + 1 - if self.compareAndSet(expect: oldValue, newValue: newValue) { - return oldValue - } - } + return AtomicBridges.fetchAndIncrementBarrier(wrappedValueOpaquePointer) } /// Atomically decrement the value and retrieve the old value. @@ -95,13 +101,7 @@ public class AtomicInt { /// - returns: The old value before decrementing. @discardableResult public func getAndDecrement() -> Int { - while true { - let oldValue = self.value - let newValue = oldValue - 1 - if self.compareAndSet(expect: oldValue, newValue: newValue) { - return oldValue - } - } + return AtomicBridges.fetchAndDecrementBarrier(wrappedValueOpaquePointer) } /// Atomically sets to the given new value and returns the old value. @@ -120,5 +120,9 @@ public class AtomicInt { // MARK: - Private - private var wrappedValue: Int64 + private var wrappedValue: Int + + private var wrappedValueOpaquePointer: OpaquePointer { + return OpaquePointer(UnsafeMutablePointer(&wrappedValue)) + } } diff --git a/Sources/ObjCBridges/AtomicBridges.m b/Sources/ObjCBridges/AtomicBridges.m new file mode 100644 index 0000000..e5a74e6 --- /dev/null +++ b/Sources/ObjCBridges/AtomicBridges.m @@ -0,0 +1,33 @@ +// +// Copyright (c) 2018. Uber Technologies +// +// 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 "AtomicBridges.h" + +@implementation AtomicBridges + ++ (long)fetchAndIncrementBarrier:(_Atomic(long) *)value { + return atomic_fetch_add(value, 1); +} + ++ (long)fetchAndDecrementBarrier:(_Atomic(long) *)value { + return atomic_fetch_sub(value, 1); +} + ++ (bool)compare:(_Atomic(long) *)value withExpected:(long *)expected andSwap:(long)desired { + return atomic_compare_exchange_strong(value, expected, desired); +} + +@end diff --git a/Tests/LinuxMain.swift b/Sources/ObjCBridges/include/AtomicBridges.h similarity index 63% rename from Tests/LinuxMain.swift rename to Sources/ObjCBridges/include/AtomicBridges.h index c38bb51..0cd77fe 100644 --- a/Tests/LinuxMain.swift +++ b/Sources/ObjCBridges/include/AtomicBridges.h @@ -14,13 +14,19 @@ // limitations under the License. // -import XCTest -@testable import ConcurrencyTests - -XCTMain([ - testCase(AtomicBoolTests.allTests), - testCase(AtomicIntTests.allTests), - testCase(AtomicReferenceTests.allTests), - testCase(CountDownLatchTests.allTests), - testCase(ConcurrentSequenceExecutorTests.allTests), -]) +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface AtomicBridges: NSObject + ++ (long)fetchAndIncrementBarrier:(_Atomic(long) *)value; + ++ (long)fetchAndDecrementBarrier:(_Atomic(long) *)value; + ++ (bool)compare:(_Atomic(long) *)value withExpected:(long *)expected andSwap:(long)desired; + +@end + +NS_ASSUME_NONNULL_END From efbd273f45022bad43cf3e97c1d9523f57756ef3 Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Thu, 13 Dec 2018 20:59:43 -0800 Subject: [PATCH 10/17] Fix deprecated atomic APIs used in AtomicReference (#27) --- Sources/Concurrency/AtomicReference.swift | 5 +++-- Sources/ObjCBridges/AtomicBridges.m | 4 ++++ Sources/ObjCBridges/include/AtomicBridges.h | 2 ++ Tests/ConcurrencyTests/AtomicIntTests.swift | 12 ------------ Tests/ConcurrencyTests/AtomicReferenceTests.swift | 10 ---------- Tests/ConcurrencyTests/CountDownLatchTests.swift | 8 -------- 6 files changed, 9 insertions(+), 32 deletions(-) diff --git a/Sources/Concurrency/AtomicReference.swift b/Sources/Concurrency/AtomicReference.swift index c857386..8a1856e 100644 --- a/Sources/Concurrency/AtomicReference.swift +++ b/Sources/Concurrency/AtomicReference.swift @@ -16,6 +16,7 @@ import Foundation import libkern +import ObjCBridges /// A concurrency utility class that supports locking-free synchronization on mutating an object /// reference. Unlike using a lock, concurrent read and write accesses to this class is allowed. At @@ -28,7 +29,7 @@ public class AtomicReference { get { // Create a memory barrier to ensure the entire memory stack is in sync so we // can safely retrieve the value. This guarantees the initial value is in sync. - OSMemoryBarrier() + atomic_thread_fence(memory_order_seq_cst) return wrappedValue } set { @@ -59,7 +60,7 @@ public class AtomicReference { let expectPointer = unsafePassUnretainedPointer(value: expect) let newValuePointer = unsafePassUnretainedPointer(value: newValue) - if OSAtomicCompareAndSwapPtrBarrier(expectPointer, newValuePointer, pointer) { + if AtomicBridges.comparePointer(pointer, withExpectedPointer: expectPointer, andSwapPointer: newValuePointer) { // If pointer swap succeeded, a memory berrier is created, so we can safely write the new // value. wrappedValue = newValue diff --git a/Sources/ObjCBridges/AtomicBridges.m b/Sources/ObjCBridges/AtomicBridges.m index e5a74e6..cc25ddd 100644 --- a/Sources/ObjCBridges/AtomicBridges.m +++ b/Sources/ObjCBridges/AtomicBridges.m @@ -30,4 +30,8 @@ + (bool)compare:(_Atomic(long) *)value withExpected:(long *)expected andSwap:(lo return atomic_compare_exchange_strong(value, expected, desired); } ++ (bool)comparePointer:(void * volatile *)value withExpectedPointer:(void *)expected andSwapPointer:(void *)desired { + return __sync_bool_compare_and_swap(value, expected, desired); +} + @end diff --git a/Sources/ObjCBridges/include/AtomicBridges.h b/Sources/ObjCBridges/include/AtomicBridges.h index 0cd77fe..3b2fc71 100644 --- a/Sources/ObjCBridges/include/AtomicBridges.h +++ b/Sources/ObjCBridges/include/AtomicBridges.h @@ -27,6 +27,8 @@ NS_ASSUME_NONNULL_BEGIN + (bool)compare:(_Atomic(long) *)value withExpected:(long *)expected andSwap:(long)desired; ++ (bool)comparePointer:(void * _Nullable volatile * _Nonnull)value withExpectedPointer:(void *)expected andSwapPointer:(void *)desired; + @end NS_ASSUME_NONNULL_END diff --git a/Tests/ConcurrencyTests/AtomicIntTests.swift b/Tests/ConcurrencyTests/AtomicIntTests.swift index fc4b5bd..60f8877 100644 --- a/Tests/ConcurrencyTests/AtomicIntTests.swift +++ b/Tests/ConcurrencyTests/AtomicIntTests.swift @@ -19,18 +19,6 @@ import XCTest class AtomicIntTests: XCTestCase { - static var allTests = [ - ("test_init_verifyInitialValue", test_init_verifyInitialValue), - ("test_initGetSet_verifySetToNewValue", test_initGetSet_verifySetToNewValue), - ("test_compareAndSet_verifySettingNewValue", test_compareAndSet_verifySettingNewValue), - ("test_compareAndSet_withFalseExpectValue_verifyNotSettingNewValue", test_compareAndSet_withFalseExpectValue_verifyNotSettingNewValue), - ("test_getAndSet_verifySettingNewValueReturningOldValue", test_getAndSet_verifySettingNewValueReturningOldValue), - ("test_incrementAndGet_verifyNewValue", test_incrementAndGet_verifyNewValue), - ("test_decrementAndGet_verifyNewValue", test_decrementAndGet_verifyNewValue), - ("test_getAndIncrement_verifyNewValue", test_getAndIncrement_verifyNewValue), - ("test_getAndDecrement_verifyNewValue", test_getAndDecrement_verifyNewValue), - ] - func test_init_verifyInitialValue() { let initialValue = 123 let atomicInt = AtomicInt(initialValue: initialValue) diff --git a/Tests/ConcurrencyTests/AtomicReferenceTests.swift b/Tests/ConcurrencyTests/AtomicReferenceTests.swift index c589ba1..8dc540b 100644 --- a/Tests/ConcurrencyTests/AtomicReferenceTests.swift +++ b/Tests/ConcurrencyTests/AtomicReferenceTests.swift @@ -19,16 +19,6 @@ import XCTest class AtomicReferenceTests: XCTestCase { - static var allTests = [ - ("test_init_verifyInitialValue", test_init_verifyInitialValue), - ("test_initGetSet_verifySetToNewValue", test_initGetSet_verifySetToNewValue), - ("test_compareAndSet_verifySettingNewValue", test_compareAndSet_verifySettingNewValue), - ("test_compareAndSet_withFalseExpectValue_verifyNotSettingNewValue", test_compareAndSet_withFalseExpectValue_verifyNotSettingNewValue), - ("test_compareAndSet_withNil_verifySettingNewValue", test_compareAndSet_withNil_verifySettingNewValue), - ("test_getAndSet_verifySettingNewValueReturningOldValue", test_getAndSet_verifySettingNewValueReturningOldValue), - ("test_compareAndSet_initialNilThenResetToNil_verifySuccess", test_compareAndSet_initialNilThenResetToNil_verifySuccess), - ] - func test_init_verifyInitialValue() { let initialValue = NSObject() let atomicRef = AtomicReference(initialValue: initialValue) diff --git a/Tests/ConcurrencyTests/CountDownLatchTests.swift b/Tests/ConcurrencyTests/CountDownLatchTests.swift index b0a0457..ee24609 100644 --- a/Tests/ConcurrencyTests/CountDownLatchTests.swift +++ b/Tests/ConcurrencyTests/CountDownLatchTests.swift @@ -19,14 +19,6 @@ import XCTest class CountDownLatchTests: XCTestCase { - static var allTests = [ - ("test_countDown_await_verifyCompletionWithTrue", test_countDown_await_verifyCompletionWithTrue), - ("test_countDown_await_withTimeout_verifyCompletionWithFalse", test_countDown_await_withTimeout_verifyCompletionWithFalse), - ("test_countDown_await_verifyDuplicateCountDown_verifyDuplicateAwaitCompletesWithTrue", test_countDown_await_verifyDuplicateCountDown_verifyDuplicateAwaitCompletesWithTrue), - ("test_multipleAwaitBeforeCountDown_verifyCompletesWithTrue", test_multipleAwaitBeforeCountDown_verifyCompletesWithTrue), - ("test_multipleAsyncAwaitBeforeCountDown_verifyCompletesWithTrue", test_multipleAsyncAwaitBeforeCountDown_verifyCompletesWithTrue), - ] - func test_countDown_await_verifyCompletionWithTrue() { let latch = CountDownLatch(count: 3) From d132096336d6640ff62ce71654354e09ee940af8 Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Thu, 24 Jan 2019 13:26:04 -0800 Subject: [PATCH 11/17] Allow task execution to throw errors (#28) * Allow task execution to throw errors Adds support to allow task execution to throw errors. The error is then reported back via the `SequenceExecutionHandle.await` method when results are being retrieved. * Ignore SPM generated scheme * Xcode project changes --- .gitignore | 1 + Concurrency.xcodeproj/project.pbxproj | 1506 ++++++++++------- .../Executor/ConcurrentSequenceExecutor.swift | 45 +- .../ImmediateSerialSequenceExecutor.swift | 29 +- .../Executor/SequenceExecutor.swift | 1 + Sources/Concurrency/Executor/Task.swift | 11 +- .../ConcurrentSequenceExecutorTests.swift | 36 +- 7 files changed, 949 insertions(+), 680 deletions(-) diff --git a/.gitignore b/.gitignore index ca9af23..e777a46 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Xcode Add Xcode project to allow Carthage. #*.xcodeproj #*.xcworkspace +Concurrency.xcodeproj/xcshareddata/xcschemes/Concurrency-Package.xcscheme ## Build generated build/ diff --git a/Concurrency.xcodeproj/project.pbxproj b/Concurrency.xcodeproj/project.pbxproj index 21dd01d..70936a0 100644 --- a/Concurrency.xcodeproj/project.pbxproj +++ b/Concurrency.xcodeproj/project.pbxproj @@ -1,653 +1,859 @@ // !$*UTF8*$! { - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - OBJ_40 /* AtomicBool.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* AtomicBool.swift */; }; - OBJ_41 /* AtomicInt.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_10 /* AtomicInt.swift */; }; - OBJ_42 /* AtomicReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_11 /* AtomicReference.swift */; }; - OBJ_43 /* CountDownLatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* CountDownLatch.swift */; }; - OBJ_44 /* ConcurrentSequenceExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_14 /* ConcurrentSequenceExecutor.swift */; }; - OBJ_45 /* ImmediateSerialSequenceExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_15 /* ImmediateSerialSequenceExecutor.swift */; }; - OBJ_46 /* SequenceExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_16 /* SequenceExecutor.swift */; }; - OBJ_47 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_17 /* Task.swift */; }; - OBJ_49 /* ObjCBridges.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "Concurrency::ObjCBridges::Product" /* ObjCBridges.framework */; }; - OBJ_68 /* AtomicBoolTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_25 /* AtomicBoolTests.swift */; }; - OBJ_69 /* AtomicIntTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_26 /* AtomicIntTests.swift */; }; - OBJ_70 /* AtomicReferenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_27 /* AtomicReferenceTests.swift */; }; - OBJ_71 /* CountDownLatchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_28 /* CountDownLatchTests.swift */; }; - OBJ_72 /* ConcurrentSequenceExecutorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_30 /* ConcurrentSequenceExecutorTests.swift */; }; - OBJ_74 /* Concurrency.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "Concurrency::Concurrency::Product" /* Concurrency.framework */; }; - OBJ_75 /* ObjCBridges.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "Concurrency::ObjCBridges::Product" /* ObjCBridges.framework */; }; - OBJ_82 /* AtomicBridges.m in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_19 /* AtomicBridges.m */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 41B04ADA21C1E84C00328020 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = OBJ_1 /* Project object */; - proxyType = 1; - remoteGlobalIDString = "Concurrency::ObjCBridges"; - remoteInfo = ObjCBridges; - }; - 41B04ADB21C1E84C00328020 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = OBJ_1 /* Project object */; - proxyType = 1; - remoteGlobalIDString = "Concurrency::Concurrency"; - remoteInfo = Concurrency; - }; - 41B04ADC21C1E84C00328020 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = OBJ_1 /* Project object */; - proxyType = 1; - remoteGlobalIDString = "Concurrency::ObjCBridges"; - remoteInfo = ObjCBridges; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - "Concurrency::Concurrency::Product" /* Concurrency.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Concurrency.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - "Concurrency::ConcurrencyTests::Product" /* ConcurrencyTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = ConcurrencyTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - "Concurrency::ObjCBridges::Product" /* ObjCBridges.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = ObjCBridges.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - OBJ_10 /* AtomicInt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicInt.swift; sourceTree = ""; }; - OBJ_11 /* AtomicReference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicReference.swift; sourceTree = ""; }; - OBJ_12 /* CountDownLatch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CountDownLatch.swift; sourceTree = ""; }; - OBJ_14 /* ConcurrentSequenceExecutor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConcurrentSequenceExecutor.swift; sourceTree = ""; }; - OBJ_15 /* ImmediateSerialSequenceExecutor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImmediateSerialSequenceExecutor.swift; sourceTree = ""; }; - OBJ_16 /* SequenceExecutor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SequenceExecutor.swift; sourceTree = ""; }; - OBJ_17 /* Task.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Task.swift; sourceTree = ""; }; - OBJ_19 /* AtomicBridges.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AtomicBridges.m; sourceTree = ""; }; - OBJ_21 /* AtomicBridges.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AtomicBridges.h; sourceTree = ""; }; - OBJ_22 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; name = module.modulemap; path = "/Users/yiw/Uber/GitHub/swift-concurrency/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap"; sourceTree = ""; }; - OBJ_25 /* AtomicBoolTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicBoolTests.swift; sourceTree = ""; }; - OBJ_26 /* AtomicIntTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicIntTests.swift; sourceTree = ""; }; - OBJ_27 /* AtomicReferenceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicReferenceTests.swift; sourceTree = ""; }; - OBJ_28 /* CountDownLatchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CountDownLatchTests.swift; sourceTree = ""; }; - OBJ_30 /* ConcurrentSequenceExecutorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConcurrentSequenceExecutorTests.swift; sourceTree = ""; }; - OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; - OBJ_9 /* AtomicBool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicBool.swift; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - OBJ_48 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 0; - files = ( - OBJ_49 /* ObjCBridges.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - OBJ_73 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 0; - files = ( - OBJ_74 /* Concurrency.framework in Frameworks */, - OBJ_75 /* ObjCBridges.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - OBJ_83 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - OBJ_13 /* Executor */ = { - isa = PBXGroup; - children = ( - OBJ_14 /* ConcurrentSequenceExecutor.swift */, - OBJ_15 /* ImmediateSerialSequenceExecutor.swift */, - OBJ_16 /* SequenceExecutor.swift */, - OBJ_17 /* Task.swift */, - ); - path = Executor; - sourceTree = ""; - }; - OBJ_18 /* ObjCBridges */ = { - isa = PBXGroup; - children = ( - OBJ_19 /* AtomicBridges.m */, - OBJ_20 /* include */, - ); - name = ObjCBridges; - path = Sources/ObjCBridges; - sourceTree = SOURCE_ROOT; - }; - OBJ_20 /* include */ = { - isa = PBXGroup; - children = ( - OBJ_21 /* AtomicBridges.h */, - OBJ_22 /* module.modulemap */, - ); - path = include; - sourceTree = ""; - }; - OBJ_23 /* Tests */ = { - isa = PBXGroup; - children = ( - OBJ_24 /* ConcurrencyTests */, - ); - name = Tests; - sourceTree = SOURCE_ROOT; - }; - OBJ_24 /* ConcurrencyTests */ = { - isa = PBXGroup; - children = ( - OBJ_25 /* AtomicBoolTests.swift */, - OBJ_26 /* AtomicIntTests.swift */, - OBJ_27 /* AtomicReferenceTests.swift */, - OBJ_28 /* CountDownLatchTests.swift */, - OBJ_29 /* Executor */, - ); - name = ConcurrencyTests; - path = Tests/ConcurrencyTests; - sourceTree = SOURCE_ROOT; - }; - OBJ_29 /* Executor */ = { - isa = PBXGroup; - children = ( - OBJ_30 /* ConcurrentSequenceExecutorTests.swift */, - ); - path = Executor; - sourceTree = ""; - }; - OBJ_31 /* Products */ = { - isa = PBXGroup; - children = ( - "Concurrency::ConcurrencyTests::Product" /* ConcurrencyTests.xctest */, - "Concurrency::ObjCBridges::Product" /* ObjCBridges.framework */, - "Concurrency::Concurrency::Product" /* Concurrency.framework */, - ); - name = Products; - sourceTree = BUILT_PRODUCTS_DIR; - }; - OBJ_5 /* */ = { - isa = PBXGroup; - children = ( - OBJ_6 /* Package.swift */, - OBJ_7 /* Sources */, - OBJ_23 /* Tests */, - OBJ_31 /* Products */, - ); - name = ""; - sourceTree = ""; - }; - OBJ_7 /* Sources */ = { - isa = PBXGroup; - children = ( - OBJ_8 /* Concurrency */, - OBJ_18 /* ObjCBridges */, - ); - name = Sources; - sourceTree = SOURCE_ROOT; - }; - OBJ_8 /* Concurrency */ = { - isa = PBXGroup; - children = ( - OBJ_9 /* AtomicBool.swift */, - OBJ_10 /* AtomicInt.swift */, - OBJ_11 /* AtomicReference.swift */, - OBJ_12 /* CountDownLatch.swift */, - OBJ_13 /* Executor */, - ); - name = Concurrency; - path = Sources/Concurrency; - sourceTree = SOURCE_ROOT; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - "Concurrency::Concurrency" /* Concurrency */ = { - isa = PBXNativeTarget; - buildConfigurationList = OBJ_36 /* Build configuration list for PBXNativeTarget "Concurrency" */; - buildPhases = ( - OBJ_39 /* Sources */, - OBJ_48 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - OBJ_50 /* PBXTargetDependency */, - ); - name = Concurrency; - productName = Concurrency; - productReference = "Concurrency::Concurrency::Product" /* Concurrency.framework */; - productType = "com.apple.product-type.framework"; - }; - "Concurrency::ConcurrencyTests" /* ConcurrencyTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = OBJ_64 /* Build configuration list for PBXNativeTarget "ConcurrencyTests" */; - buildPhases = ( - OBJ_67 /* Sources */, - OBJ_73 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - OBJ_76 /* PBXTargetDependency */, - OBJ_77 /* PBXTargetDependency */, - ); - name = ConcurrencyTests; - productName = ConcurrencyTests; - productReference = "Concurrency::ConcurrencyTests::Product" /* ConcurrencyTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - "Concurrency::ObjCBridges" /* ObjCBridges */ = { - isa = PBXNativeTarget; - buildConfigurationList = OBJ_78 /* Build configuration list for PBXNativeTarget "ObjCBridges" */; - buildPhases = ( - OBJ_81 /* Sources */, - OBJ_83 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = ObjCBridges; - productName = ObjCBridges; - productReference = "Concurrency::ObjCBridges::Product" /* ObjCBridges.framework */; - productType = "com.apple.product-type.framework"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - OBJ_1 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1010; - TargetAttributes = { - "Concurrency::Concurrency" = { - LastSwiftMigration = 1010; - }; - "Concurrency::ConcurrencyTests" = { - LastSwiftMigration = 1010; - }; - }; - }; - buildConfigurationList = OBJ_2 /* Build configuration list for PBXProject "Concurrency" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = OBJ_5 /* */; - productRefGroup = OBJ_31 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - "Concurrency::Concurrency" /* Concurrency */, - "Concurrency::ConcurrencyTests" /* ConcurrencyTests */, - "Concurrency::ObjCBridges" /* ObjCBridges */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - OBJ_39 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 0; - files = ( - OBJ_40 /* AtomicBool.swift in Sources */, - OBJ_41 /* AtomicInt.swift in Sources */, - OBJ_42 /* AtomicReference.swift in Sources */, - OBJ_43 /* CountDownLatch.swift in Sources */, - OBJ_44 /* ConcurrentSequenceExecutor.swift in Sources */, - OBJ_45 /* ImmediateSerialSequenceExecutor.swift in Sources */, - OBJ_46 /* SequenceExecutor.swift in Sources */, - OBJ_47 /* Task.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - OBJ_67 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 0; - files = ( - OBJ_68 /* AtomicBoolTests.swift in Sources */, - OBJ_69 /* AtomicIntTests.swift in Sources */, - OBJ_70 /* AtomicReferenceTests.swift in Sources */, - OBJ_71 /* CountDownLatchTests.swift in Sources */, - OBJ_72 /* ConcurrentSequenceExecutorTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - OBJ_81 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 0; - files = ( - OBJ_82 /* AtomicBridges.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - OBJ_50 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = "Concurrency::ObjCBridges" /* ObjCBridges */; - targetProxy = 41B04ADA21C1E84C00328020 /* PBXContainerItemProxy */; - }; - OBJ_76 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = "Concurrency::Concurrency" /* Concurrency */; - targetProxy = 41B04ADB21C1E84C00328020 /* PBXContainerItemProxy */; - }; - OBJ_77 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = "Concurrency::ObjCBridges" /* ObjCBridges */; - targetProxy = 41B04ADC21C1E84C00328020 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - OBJ_3 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_NS_ASSERTIONS = YES; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MACOSX_DEPLOYMENT_TARGET = 10.12; - ONLY_ACTIVE_ARCH = YES; - OTHER_SWIFT_FLAGS = "-DXcode"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "SWIFT_PACKAGE DEBUG"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - USE_HEADERMAP = NO; - }; - name = Debug; - }; - OBJ_37 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ENABLE_TESTABILITY = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PLATFORM_DIR)/Developer/Library/Frameworks", - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(SRCROOT)/Sources/ObjCBridges/include", - "$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges", - ); - INFOPLIST_FILE = Concurrency.xcodeproj/Concurrency_Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; - OTHER_CFLAGS = "$(inherited)"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited) -Xcc -fmodule-map-file=$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap"; - PRODUCT_BUNDLE_IDENTIFIER = Concurrency; - PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; - SWIFT_VERSION = 4.2; - TARGET_NAME = Concurrency; - }; - name = Debug; - }; - OBJ_38 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ENABLE_TESTABILITY = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PLATFORM_DIR)/Developer/Library/Frameworks", - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(SRCROOT)/Sources/ObjCBridges/include", - "$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges", - ); - INFOPLIST_FILE = Concurrency.xcodeproj/Concurrency_Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; - OTHER_CFLAGS = "$(inherited)"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited) -Xcc -fmodule-map-file=$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap"; - PRODUCT_BUNDLE_IDENTIFIER = Concurrency; - PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; - SWIFT_VERSION = 4.2; - TARGET_NAME = Concurrency; - }; - name = Release; - }; - OBJ_4 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = s; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MACOSX_DEPLOYMENT_TARGET = 10.12; - OTHER_SWIFT_FLAGS = "-DXcode"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - USE_HEADERMAP = NO; - }; - name = Release; - }; - OBJ_65 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CLANG_ENABLE_MODULES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PLATFORM_DIR)/Developer/Library/Frameworks", - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(SRCROOT)/Sources/ObjCBridges/include", - "$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges", - ); - INFOPLIST_FILE = Concurrency.xcodeproj/ConcurrencyTests_Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks @loader_path/Frameworks"; - OTHER_CFLAGS = "$(inherited)"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited) -Xcc -fmodule-map-file=$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; - SWIFT_VERSION = 4.2; - TARGET_NAME = ConcurrencyTests; - }; - name = Debug; - }; - OBJ_66 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CLANG_ENABLE_MODULES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PLATFORM_DIR)/Developer/Library/Frameworks", - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(SRCROOT)/Sources/ObjCBridges/include", - "$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges", - ); - INFOPLIST_FILE = Concurrency.xcodeproj/ConcurrencyTests_Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks @loader_path/Frameworks"; - OTHER_CFLAGS = "$(inherited)"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited) -Xcc -fmodule-map-file=$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; - SWIFT_VERSION = 4.2; - TARGET_NAME = ConcurrencyTests; - }; - name = Release; - }; - OBJ_79 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEFINES_MODULE = NO; - ENABLE_TESTABILITY = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PLATFORM_DIR)/Developer/Library/Frameworks", - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(SRCROOT)/Sources/ObjCBridges/include", - ); - INFOPLIST_FILE = Concurrency.xcodeproj/ObjCBridges_Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; - OTHER_CFLAGS = "$(inherited)"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited)"; - PRODUCT_BUNDLE_IDENTIFIER = ObjCBridges; - PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; - TARGET_NAME = ObjCBridges; - }; - name = Debug; - }; - OBJ_80 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEFINES_MODULE = NO; - ENABLE_TESTABILITY = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PLATFORM_DIR)/Developer/Library/Frameworks", - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(SRCROOT)/Sources/ObjCBridges/include", - ); - INFOPLIST_FILE = Concurrency.xcodeproj/ObjCBridges_Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; - OTHER_CFLAGS = "$(inherited)"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited)"; - PRODUCT_BUNDLE_IDENTIFIER = ObjCBridges; - PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; - TARGET_NAME = ObjCBridges; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - OBJ_2 /* Build configuration list for PBXProject "Concurrency" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - OBJ_3 /* Debug */, - OBJ_4 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - OBJ_36 /* Build configuration list for PBXNativeTarget "Concurrency" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - OBJ_37 /* Debug */, - OBJ_38 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - OBJ_64 /* Build configuration list for PBXNativeTarget "ConcurrencyTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - OBJ_65 /* Debug */, - OBJ_66 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - OBJ_78 /* Build configuration list for PBXNativeTarget "ObjCBridges" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - OBJ_79 /* Debug */, - OBJ_80 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = OBJ_1 /* Project object */; + archiveVersion = "1"; + objectVersion = "46"; + objects = { + "Concurrency::Concurrency" = { + isa = "PBXNativeTarget"; + buildConfigurationList = "OBJ_36"; + buildPhases = ( + "OBJ_39", + "OBJ_48" + ); + dependencies = ( + "OBJ_50" + ); + name = "Concurrency"; + productName = "Concurrency"; + productReference = "Concurrency::Concurrency::Product"; + productType = "com.apple.product-type.framework"; + }; + "Concurrency::Concurrency::Product" = { + isa = "PBXFileReference"; + path = "Concurrency.framework"; + sourceTree = "BUILT_PRODUCTS_DIR"; + }; + "Concurrency::ConcurrencyPackageTests::ProductTarget" = { + isa = "PBXAggregateTarget"; + buildConfigurationList = "OBJ_59"; + buildPhases = ( + ); + dependencies = ( + "OBJ_62" + ); + name = "ConcurrencyPackageTests"; + productName = "ConcurrencyPackageTests"; + }; + "Concurrency::ConcurrencyTests" = { + isa = "PBXNativeTarget"; + buildConfigurationList = "OBJ_64"; + buildPhases = ( + "OBJ_67", + "OBJ_73" + ); + dependencies = ( + "OBJ_76", + "OBJ_77" + ); + name = "ConcurrencyTests"; + productName = "ConcurrencyTests"; + productReference = "Concurrency::ConcurrencyTests::Product"; + productType = "com.apple.product-type.bundle.unit-test"; + }; + "Concurrency::ConcurrencyTests::Product" = { + isa = "PBXFileReference"; + path = "ConcurrencyTests.xctest"; + sourceTree = "BUILT_PRODUCTS_DIR"; + }; + "Concurrency::ObjCBridges" = { + isa = "PBXNativeTarget"; + buildConfigurationList = "OBJ_78"; + buildPhases = ( + "OBJ_81", + "OBJ_83" + ); + dependencies = ( + ); + name = "ObjCBridges"; + productName = "ObjCBridges"; + productReference = "Concurrency::ObjCBridges::Product"; + productType = "com.apple.product-type.framework"; + }; + "Concurrency::ObjCBridges::Product" = { + isa = "PBXFileReference"; + path = "ObjCBridges.framework"; + sourceTree = "BUILT_PRODUCTS_DIR"; + }; + "Concurrency::SwiftPMPackageDescription" = { + isa = "PBXNativeTarget"; + buildConfigurationList = "OBJ_53"; + buildPhases = ( + "OBJ_56" + ); + dependencies = ( + ); + name = "ConcurrencyPackageDescription"; + productName = "ConcurrencyPackageDescription"; + productType = "com.apple.product-type.framework"; + }; + "OBJ_1" = { + isa = "PBXProject"; + attributes = { + LastUpgradeCheck = "9999"; + }; + buildConfigurationList = "OBJ_2"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = "English"; + hasScannedForEncodings = "0"; + knownRegions = ( + "en" + ); + mainGroup = "OBJ_5"; + productRefGroup = "OBJ_31"; + projectDirPath = "."; + targets = ( + "Concurrency::Concurrency", + "Concurrency::SwiftPMPackageDescription", + "Concurrency::ConcurrencyPackageTests::ProductTarget", + "Concurrency::ConcurrencyTests", + "Concurrency::ObjCBridges" + ); + }; + "OBJ_10" = { + isa = "PBXGroup"; + children = ( + "OBJ_11", + "OBJ_12" + ); + name = "include"; + path = "include"; + sourceTree = ""; + }; + "OBJ_11" = { + isa = "PBXFileReference"; + path = "AtomicBridges.h"; + sourceTree = ""; + }; + "OBJ_12" = { + isa = "PBXFileReference"; + name = "module.modulemap"; + path = "/Users/yiw/Uber/GitHub/swift-concurrency/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap"; + sourceTree = ""; + }; + "OBJ_13" = { + isa = "PBXGroup"; + children = ( + "OBJ_14", + "OBJ_15", + "OBJ_16", + "OBJ_17", + "OBJ_18" + ); + name = "Concurrency"; + path = "Sources/Concurrency"; + sourceTree = "SOURCE_ROOT"; + }; + "OBJ_14" = { + isa = "PBXFileReference"; + path = "AtomicBool.swift"; + sourceTree = ""; + }; + "OBJ_15" = { + isa = "PBXFileReference"; + path = "AtomicInt.swift"; + sourceTree = ""; + }; + "OBJ_16" = { + isa = "PBXFileReference"; + path = "AtomicReference.swift"; + sourceTree = ""; + }; + "OBJ_17" = { + isa = "PBXFileReference"; + path = "CountDownLatch.swift"; + sourceTree = ""; + }; + "OBJ_18" = { + isa = "PBXGroup"; + children = ( + "OBJ_19", + "OBJ_20", + "OBJ_21", + "OBJ_22" + ); + name = "Executor"; + path = "Executor"; + sourceTree = ""; + }; + "OBJ_19" = { + isa = "PBXFileReference"; + path = "ConcurrentSequenceExecutor.swift"; + sourceTree = ""; + }; + "OBJ_2" = { + isa = "XCConfigurationList"; + buildConfigurations = ( + "OBJ_3", + "OBJ_4" + ); + defaultConfigurationIsVisible = "0"; + defaultConfigurationName = "Release"; + }; + "OBJ_20" = { + isa = "PBXFileReference"; + path = "ImmediateSerialSequenceExecutor.swift"; + sourceTree = ""; + }; + "OBJ_21" = { + isa = "PBXFileReference"; + path = "SequenceExecutor.swift"; + sourceTree = ""; + }; + "OBJ_22" = { + isa = "PBXFileReference"; + path = "Task.swift"; + sourceTree = ""; + }; + "OBJ_23" = { + isa = "PBXGroup"; + children = ( + "OBJ_24" + ); + name = "Tests"; + path = ""; + sourceTree = "SOURCE_ROOT"; + }; + "OBJ_24" = { + isa = "PBXGroup"; + children = ( + "OBJ_25", + "OBJ_26", + "OBJ_27", + "OBJ_28", + "OBJ_29" + ); + name = "ConcurrencyTests"; + path = "Tests/ConcurrencyTests"; + sourceTree = "SOURCE_ROOT"; + }; + "OBJ_25" = { + isa = "PBXFileReference"; + path = "AtomicBoolTests.swift"; + sourceTree = ""; + }; + "OBJ_26" = { + isa = "PBXFileReference"; + path = "AtomicIntTests.swift"; + sourceTree = ""; + }; + "OBJ_27" = { + isa = "PBXFileReference"; + path = "AtomicReferenceTests.swift"; + sourceTree = ""; + }; + "OBJ_28" = { + isa = "PBXFileReference"; + path = "CountDownLatchTests.swift"; + sourceTree = ""; + }; + "OBJ_29" = { + isa = "PBXGroup"; + children = ( + "OBJ_30" + ); + name = "Executor"; + path = "Executor"; + sourceTree = ""; + }; + "OBJ_3" = { + isa = "XCBuildConfiguration"; + buildSettings = { + CLANG_ENABLE_OBJC_ARC = "YES"; + COMBINE_HIDPI_IMAGES = "YES"; + COPY_PHASE_STRIP = "NO"; + DEBUG_INFORMATION_FORMAT = "dwarf"; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_NS_ASSERTIONS = "YES"; + GCC_OPTIMIZATION_LEVEL = "0"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)" + ); + MACOSX_DEPLOYMENT_TARGET = "10.10"; + ONLY_ACTIVE_ARCH = "YES"; + OTHER_SWIFT_FLAGS = ( + "-DXcode" + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = "macosx"; + SUPPORTED_PLATFORMS = ( + "macosx", + "iphoneos", + "iphonesimulator", + "appletvos", + "appletvsimulator", + "watchos", + "watchsimulator" + ); + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( + "SWIFT_PACKAGE", + "DEBUG" + ); + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + USE_HEADERMAP = "NO"; + }; + name = "Debug"; + }; + "OBJ_30" = { + isa = "PBXFileReference"; + path = "ConcurrentSequenceExecutorTests.swift"; + sourceTree = ""; + }; + "OBJ_31" = { + isa = "PBXGroup"; + children = ( + "Concurrency::Concurrency::Product", + "Concurrency::ObjCBridges::Product", + "Concurrency::ConcurrencyTests::Product" + ); + name = "Products"; + path = ""; + sourceTree = "BUILT_PRODUCTS_DIR"; + }; + "OBJ_36" = { + isa = "XCConfigurationList"; + buildConfigurations = ( + "OBJ_37", + "OBJ_38" + ); + defaultConfigurationIsVisible = "0"; + defaultConfigurationName = "Release"; + }; + "OBJ_37" = { + isa = "XCBuildConfiguration"; + buildSettings = { + ENABLE_TESTABILITY = "YES"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks" + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/Sources/ObjCBridges/include", + "$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges" + ); + INFOPLIST_FILE = "Concurrency.xcodeproj/Concurrency_Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx" + ); + OTHER_CFLAGS = ( + "$(inherited)" + ); + OTHER_LDFLAGS = ( + "$(inherited)" + ); + OTHER_SWIFT_FLAGS = ( + "$(inherited)", + "-Xcc", + "-fmodule-map-file=$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap" + ); + PRODUCT_BUNDLE_IDENTIFIER = "Concurrency"; + PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = "YES"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( + "$(inherited)" + ); + SWIFT_VERSION = "4.0"; + TARGET_NAME = "Concurrency"; + }; + name = "Debug"; + }; + "OBJ_38" = { + isa = "XCBuildConfiguration"; + buildSettings = { + ENABLE_TESTABILITY = "YES"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks" + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/Sources/ObjCBridges/include", + "$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges" + ); + INFOPLIST_FILE = "Concurrency.xcodeproj/Concurrency_Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx" + ); + OTHER_CFLAGS = ( + "$(inherited)" + ); + OTHER_LDFLAGS = ( + "$(inherited)" + ); + OTHER_SWIFT_FLAGS = ( + "$(inherited)", + "-Xcc", + "-fmodule-map-file=$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap" + ); + PRODUCT_BUNDLE_IDENTIFIER = "Concurrency"; + PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = "YES"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( + "$(inherited)" + ); + SWIFT_VERSION = "4.0"; + TARGET_NAME = "Concurrency"; + }; + name = "Release"; + }; + "OBJ_39" = { + isa = "PBXSourcesBuildPhase"; + files = ( + "OBJ_40", + "OBJ_41", + "OBJ_42", + "OBJ_43", + "OBJ_44", + "OBJ_45", + "OBJ_46", + "OBJ_47" + ); + }; + "OBJ_4" = { + isa = "XCBuildConfiguration"; + buildSettings = { + CLANG_ENABLE_OBJC_ARC = "YES"; + COMBINE_HIDPI_IMAGES = "YES"; + COPY_PHASE_STRIP = "YES"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_OPTIMIZATION_LEVEL = "s"; + MACOSX_DEPLOYMENT_TARGET = "10.10"; + OTHER_SWIFT_FLAGS = ( + "-DXcode" + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = "macosx"; + SUPPORTED_PLATFORMS = ( + "macosx", + "iphoneos", + "iphonesimulator", + "appletvos", + "appletvsimulator", + "watchos", + "watchsimulator" + ); + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( + "SWIFT_PACKAGE" + ); + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + USE_HEADERMAP = "NO"; + }; + name = "Release"; + }; + "OBJ_40" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_14"; + }; + "OBJ_41" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_15"; + }; + "OBJ_42" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_16"; + }; + "OBJ_43" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_17"; + }; + "OBJ_44" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_19"; + }; + "OBJ_45" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_20"; + }; + "OBJ_46" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_21"; + }; + "OBJ_47" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_22"; + }; + "OBJ_48" = { + isa = "PBXFrameworksBuildPhase"; + files = ( + "OBJ_49" + ); + }; + "OBJ_49" = { + isa = "PBXBuildFile"; + fileRef = "Concurrency::ObjCBridges::Product"; + }; + "OBJ_5" = { + isa = "PBXGroup"; + children = ( + "OBJ_6", + "OBJ_7", + "OBJ_23", + "OBJ_31" + ); + path = ""; + sourceTree = ""; + }; + "OBJ_50" = { + isa = "PBXTargetDependency"; + target = "Concurrency::ObjCBridges"; + }; + "OBJ_53" = { + isa = "XCConfigurationList"; + buildConfigurations = ( + "OBJ_54", + "OBJ_55" + ); + defaultConfigurationIsVisible = "0"; + defaultConfigurationName = "Release"; + }; + "OBJ_54" = { + isa = "XCBuildConfiguration"; + buildSettings = { + LD = "/usr/bin/true"; + OTHER_SWIFT_FLAGS = ( + "-swift-version", + "4", + "-I", + "$(TOOLCHAIN_DIR)/usr/lib/swift/pm/4", + "-target", + "x86_64-apple-macosx10.10", + "-sdk", + "/Applications/Xcode.10.1.0.10B61.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk" + ); + SWIFT_VERSION = "4.0"; + }; + name = "Debug"; + }; + "OBJ_55" = { + isa = "XCBuildConfiguration"; + buildSettings = { + LD = "/usr/bin/true"; + OTHER_SWIFT_FLAGS = ( + "-swift-version", + "4", + "-I", + "$(TOOLCHAIN_DIR)/usr/lib/swift/pm/4", + "-target", + "x86_64-apple-macosx10.10", + "-sdk", + "/Applications/Xcode.10.1.0.10B61.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk" + ); + SWIFT_VERSION = "4.0"; + }; + name = "Release"; + }; + "OBJ_56" = { + isa = "PBXSourcesBuildPhase"; + files = ( + "OBJ_57" + ); + }; + "OBJ_57" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_6"; + }; + "OBJ_59" = { + isa = "XCConfigurationList"; + buildConfigurations = ( + "OBJ_60", + "OBJ_61" + ); + defaultConfigurationIsVisible = "0"; + defaultConfigurationName = "Release"; + }; + "OBJ_6" = { + isa = "PBXFileReference"; + explicitFileType = "sourcecode.swift"; + path = "Package.swift"; + sourceTree = ""; + }; + "OBJ_60" = { + isa = "XCBuildConfiguration"; + buildSettings = { + }; + name = "Debug"; + }; + "OBJ_61" = { + isa = "XCBuildConfiguration"; + buildSettings = { + }; + name = "Release"; + }; + "OBJ_62" = { + isa = "PBXTargetDependency"; + target = "Concurrency::ConcurrencyTests"; + }; + "OBJ_64" = { + isa = "XCConfigurationList"; + buildConfigurations = ( + "OBJ_65", + "OBJ_66" + ); + defaultConfigurationIsVisible = "0"; + defaultConfigurationName = "Release"; + }; + "OBJ_65" = { + isa = "XCBuildConfiguration"; + buildSettings = { + CLANG_ENABLE_MODULES = "YES"; + EMBEDDED_CONTENT_CONTAINS_SWIFT = "YES"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks" + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/Sources/ObjCBridges/include", + "$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges" + ); + INFOPLIST_FILE = "Concurrency.xcodeproj/ConcurrencyTests_Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@loader_path/../Frameworks", + "@loader_path/Frameworks" + ); + OTHER_CFLAGS = ( + "$(inherited)" + ); + OTHER_LDFLAGS = ( + "$(inherited)" + ); + OTHER_SWIFT_FLAGS = ( + "$(inherited)", + "-Xcc", + "-fmodule-map-file=$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap" + ); + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( + "$(inherited)" + ); + SWIFT_VERSION = "4.0"; + TARGET_NAME = "ConcurrencyTests"; + }; + name = "Debug"; + }; + "OBJ_66" = { + isa = "XCBuildConfiguration"; + buildSettings = { + CLANG_ENABLE_MODULES = "YES"; + EMBEDDED_CONTENT_CONTAINS_SWIFT = "YES"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks" + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/Sources/ObjCBridges/include", + "$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges" + ); + INFOPLIST_FILE = "Concurrency.xcodeproj/ConcurrencyTests_Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@loader_path/../Frameworks", + "@loader_path/Frameworks" + ); + OTHER_CFLAGS = ( + "$(inherited)" + ); + OTHER_LDFLAGS = ( + "$(inherited)" + ); + OTHER_SWIFT_FLAGS = ( + "$(inherited)", + "-Xcc", + "-fmodule-map-file=$(SRCROOT)/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap" + ); + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( + "$(inherited)" + ); + SWIFT_VERSION = "4.0"; + TARGET_NAME = "ConcurrencyTests"; + }; + name = "Release"; + }; + "OBJ_67" = { + isa = "PBXSourcesBuildPhase"; + files = ( + "OBJ_68", + "OBJ_69", + "OBJ_70", + "OBJ_71", + "OBJ_72" + ); + }; + "OBJ_68" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_25"; + }; + "OBJ_69" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_26"; + }; + "OBJ_7" = { + isa = "PBXGroup"; + children = ( + "OBJ_8", + "OBJ_13" + ); + name = "Sources"; + path = ""; + sourceTree = "SOURCE_ROOT"; + }; + "OBJ_70" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_27"; + }; + "OBJ_71" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_28"; + }; + "OBJ_72" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_30"; + }; + "OBJ_73" = { + isa = "PBXFrameworksBuildPhase"; + files = ( + "OBJ_74", + "OBJ_75" + ); + }; + "OBJ_74" = { + isa = "PBXBuildFile"; + fileRef = "Concurrency::Concurrency::Product"; + }; + "OBJ_75" = { + isa = "PBXBuildFile"; + fileRef = "Concurrency::ObjCBridges::Product"; + }; + "OBJ_76" = { + isa = "PBXTargetDependency"; + target = "Concurrency::Concurrency"; + }; + "OBJ_77" = { + isa = "PBXTargetDependency"; + target = "Concurrency::ObjCBridges"; + }; + "OBJ_78" = { + isa = "XCConfigurationList"; + buildConfigurations = ( + "OBJ_79", + "OBJ_80" + ); + defaultConfigurationIsVisible = "0"; + defaultConfigurationName = "Release"; + }; + "OBJ_79" = { + isa = "XCBuildConfiguration"; + buildSettings = { + DEFINES_MODULE = "NO"; + ENABLE_TESTABILITY = "YES"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks" + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/Sources/ObjCBridges/include" + ); + INFOPLIST_FILE = "Concurrency.xcodeproj/ObjCBridges_Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx" + ); + OTHER_CFLAGS = ( + "$(inherited)" + ); + OTHER_LDFLAGS = ( + "$(inherited)" + ); + OTHER_SWIFT_FLAGS = ( + "$(inherited)" + ); + PRODUCT_BUNDLE_IDENTIFIER = "ObjCBridges"; + PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = "YES"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( + "$(inherited)" + ); + TARGET_NAME = "ObjCBridges"; + }; + name = "Debug"; + }; + "OBJ_8" = { + isa = "PBXGroup"; + children = ( + "OBJ_9", + "OBJ_10" + ); + name = "ObjCBridges"; + path = "Sources/ObjCBridges"; + sourceTree = "SOURCE_ROOT"; + }; + "OBJ_80" = { + isa = "XCBuildConfiguration"; + buildSettings = { + DEFINES_MODULE = "NO"; + ENABLE_TESTABILITY = "YES"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks" + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/Sources/ObjCBridges/include" + ); + INFOPLIST_FILE = "Concurrency.xcodeproj/ObjCBridges_Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx" + ); + OTHER_CFLAGS = ( + "$(inherited)" + ); + OTHER_LDFLAGS = ( + "$(inherited)" + ); + OTHER_SWIFT_FLAGS = ( + "$(inherited)" + ); + PRODUCT_BUNDLE_IDENTIFIER = "ObjCBridges"; + PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = "YES"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( + "$(inherited)" + ); + TARGET_NAME = "ObjCBridges"; + }; + name = "Release"; + }; + "OBJ_81" = { + isa = "PBXSourcesBuildPhase"; + files = ( + "OBJ_82" + ); + }; + "OBJ_82" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_9"; + }; + "OBJ_83" = { + isa = "PBXFrameworksBuildPhase"; + files = ( + ); + }; + "OBJ_9" = { + isa = "PBXFileReference"; + path = "AtomicBridges.m"; + sourceTree = ""; + }; + }; + rootObject = "OBJ_1"; } diff --git a/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift b/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift index 997c1a6..25aa8ac 100644 --- a/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift +++ b/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift @@ -81,15 +81,19 @@ public class ConcurrentSequenceExecutor: SequenceExecutor { sequenceHandle.willBeginExecuting(taskId: task.id) } - let result = task.typeErasedExecute() - let nextExecution = execution(task, result) - self.taskSemaphore?.signal() - - switch nextExecution { - case .continueSequence(let nextTask): - self.execute(nextTask, with: sequenceHandle, execution) - case .endOfSequence(let result): - sequenceHandle.sequenceDidComplete(with: result) + do { + let result = try task.typeErasedExecute() + let nextExecution = execution(task, result) + self.taskSemaphore?.signal() + + switch nextExecution { + case .continueSequence(let nextTask): + self.execute(nextTask, with: sequenceHandle, execution) + case .endOfSequence(let result): + sequenceHandle.sequenceDidComplete(with: result) + } + } catch { + sequenceHandle.sequenceDidError(with: error) } } } @@ -101,11 +105,12 @@ private class SynchronizedSequenceExecutionHandle: SequenceE private let didCancel = AtomicBool(initialValue: false) private let currentTaskId = AtomicInt(initialValue: nonTrackingDefaultTaskId) - // Use a lock to ensure result is properly accessed, since the read + // Use a lock to ensure result/error is properly accessed, since the read // `await` method may be invoked on a different thread than the write - // `sequenceDidComplete` method. + // `sequenceDidComplete`/`sequenceDidError` method. private let resultLock = NSRecursiveLock() private var result: SequenceResultType? + private var error: Error? fileprivate var isCancelled: Bool { return didCancel.value @@ -125,9 +130,13 @@ private class SynchronizedSequenceExecutionHandle: SequenceE defer { resultLock.unlock() } - // If latch was counted down, the result must have been set. Therefore, - // this forced unwrap is safe. - return result! + if let error = self.error { + throw error + } else { + // If latch was counted down and there is no error, the result must have been + // set. Therefore, this forced-unwrap is safe. + return result! + } } fileprivate func sequenceDidComplete(with result: SequenceResultType) { @@ -138,6 +147,14 @@ private class SynchronizedSequenceExecutionHandle: SequenceE latch.countDown() } + fileprivate func sequenceDidError(with error: Error) { + resultLock.lock() + self.error = error + resultLock.unlock() + + latch.countDown() + } + fileprivate override func cancel() { didCancel.compareAndSet(expect: false, newValue: true) } diff --git a/Sources/Concurrency/Executor/ImmediateSerialSequenceExecutor.swift b/Sources/Concurrency/Executor/ImmediateSerialSequenceExecutor.swift index 667fc78..576b046 100644 --- a/Sources/Concurrency/Executor/ImmediateSerialSequenceExecutor.swift +++ b/Sources/Concurrency/Executor/ImmediateSerialSequenceExecutor.swift @@ -54,13 +54,17 @@ public class ImmediateSerialSequenceExecutor: SequenceExecutor { return } - let result = task.typeErasedExecute() - let nextExecution = execution(task, result) - switch nextExecution { - case .continueSequence(let nextTask): - self.execute(nextTask, with: sequenceHandle, execution) - case .endOfSequence(let result): - sequenceHandle.sequenceDidComplete(with: result) + do { + let result = try task.typeErasedExecute() + let nextExecution = execution(task, result) + switch nextExecution { + case .continueSequence(let nextTask): + self.execute(nextTask, with: sequenceHandle, execution) + case .endOfSequence(let result): + sequenceHandle.sequenceDidComplete(with: result) + } + } catch { + sequenceHandle.sequenceDidError(with: error) } } } @@ -69,19 +73,28 @@ private class SequenceExecutionHandleImpl: SequenceExecution private var didCancel = false private var result: SequenceResultType? + private var error: Error? fileprivate var isCancelled: Bool { return didCancel } fileprivate override func await(withTimeout timeout: TimeInterval?) throws -> SequenceResultType { - return result! + if let error = self.error { + throw error + } else { + return result! + } } fileprivate func sequenceDidComplete(with result: SequenceResultType) { self.result = result } + fileprivate func sequenceDidError(with error: Error) { + self.error = error + } + fileprivate override func cancel() { didCancel = true } diff --git a/Sources/Concurrency/Executor/SequenceExecutor.swift b/Sources/Concurrency/Executor/SequenceExecutor.swift index d87e3f8..27b5029 100644 --- a/Sources/Concurrency/Executor/SequenceExecutor.swift +++ b/Sources/Concurrency/Executor/SequenceExecutor.swift @@ -43,6 +43,7 @@ open class SequenceExecutionHandle { /// completes. /// - throws: `SequenceExecutionError.awaitTimeout` if the given timeout /// period elapsed before the sequence execution completed. + /// - throws: Any error thrown by the task during execution. open func await(withTimeout timeout: TimeInterval?) throws -> SequenceResultType { fatalError("await not yet implemented.") } diff --git a/Sources/Concurrency/Executor/Task.swift b/Sources/Concurrency/Executor/Task.swift index a969e75..a67a75b 100644 --- a/Sources/Concurrency/Executor/Task.swift +++ b/Sources/Concurrency/Executor/Task.swift @@ -32,10 +32,11 @@ public protocol Task { /// - note: This method should only be used by internal executor /// implementations. /// - returns: The type erased execution result of this task. + /// - throws: Any error occurred during execution. // Return type cannot be generic since the `Task` type needs to be // referenced by the executor class which cannot provide type information // for results. - func typeErasedExecute() -> Any + func typeErasedExecute() throws -> Any } /// The base abstraction of a task that has a defined execution result @@ -62,17 +63,19 @@ open class AbstractTask: Task { /// - note: This method should only be used by internal executor /// implementations. /// - returns: The type erased execution result of this task. + /// - throws: Any error occurred during execution. // Return type cannot be generic since the `Task` type needs to be // referenced by the executor class which cannot provide type information // for results. - public final func typeErasedExecute() -> Any { - return execute() + public final func typeErasedExecute() throws -> Any { + return try execute() } /// Execute this task and return the result. /// /// - returns: The execution result of this task. - open func execute() -> ResultType { + /// - throws: Any error occurred during execution. + open func execute() throws -> ResultType { fatalError("\(self).execute is not yet implemented.") } } diff --git a/Tests/ConcurrencyTests/Executor/ConcurrentSequenceExecutorTests.swift b/Tests/ConcurrencyTests/Executor/ConcurrentSequenceExecutorTests.swift index 7936e36..8c199d8 100644 --- a/Tests/ConcurrencyTests/Executor/ConcurrentSequenceExecutorTests.swift +++ b/Tests/ConcurrencyTests/Executor/ConcurrentSequenceExecutorTests.swift @@ -149,18 +149,46 @@ class ConcurrentSequenceExecutorTests: XCTestCase { XCTAssertTrue(didThrowError) } + + func test_executeSequence_taskThrowsError_verifyError() { + let executor = ConcurrentSequenceExecutor(name: "test_executeSequence_withNonTerminatingSequence_withTimeout_verifyAwaitTimeout", shouldTrackTaskId: true) + + let throwTask = MockSelfRepeatingTask(id: 123) { + throw MockError.messagedError("bhdsfgqowfnjkbvnzxcvojqweofbn9823ry3h9g") + } + + let handle = executor.executeSequence(from: throwTask) { (_, result) -> SequenceExecution in + return .endOfSequence(result as! Int) + } + + do { + _ = try handle.await(withTimeout: nil) + XCTFail() + } catch { + switch error { + case MockError.messagedError(let message): + XCTAssertEqual(message, "bhdsfgqowfnjkbvnzxcvojqweofbn9823ry3h9g") + default: + XCTFail() + } + } + } } class MockSelfRepeatingTask: AbstractTask { - private let execution: () -> Int + private let execution: () throws -> Int - init(id: Int = nonTrackingDefaultTaskId, execution: @escaping () -> Int) { + init(id: Int = nonTrackingDefaultTaskId, execution: @escaping () throws -> Int) { self.execution = execution super.init(id: id) } - override func execute() -> Int { - return execution() + override func execute() throws -> Int { + return try execution() } } + +enum MockError: Error { + case messagedError(String) +} From c773c323bdc7206d432c07169539f1119fe97eae Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Wed, 20 Feb 2019 10:38:30 -0800 Subject: [PATCH 12/17] Add AutoReleasingSemaphore (#30) Similar to `DispatchSemaphore`, `AutoReleasingSemaphore` is a synchronization mechanism that ensures only a set number of threads can concurrently access a protected resource. Unlike `DispatchSemaphore`, `AutoReleasingSemaphore` auto-releases all blocked threads when the semaphore itself is deallocated. --- Concurrency.xcodeproj/project.pbxproj | 442 +++++++++--------- .../Concurrency/AutoReleasingSemaphore.swift | 83 ++++ .../AutoReleasingSemaphoreTests.swift | 67 +++ 3 files changed, 382 insertions(+), 210 deletions(-) create mode 100644 Sources/Concurrency/AutoReleasingSemaphore.swift create mode 100644 Tests/ConcurrencyTests/AutoReleasingSemaphoreTests.swift diff --git a/Concurrency.xcodeproj/project.pbxproj b/Concurrency.xcodeproj/project.pbxproj index 70936a0..0109e86 100644 --- a/Concurrency.xcodeproj/project.pbxproj +++ b/Concurrency.xcodeproj/project.pbxproj @@ -5,13 +5,13 @@ objects = { "Concurrency::Concurrency" = { isa = "PBXNativeTarget"; - buildConfigurationList = "OBJ_36"; + buildConfigurationList = "OBJ_38"; buildPhases = ( - "OBJ_39", - "OBJ_48" + "OBJ_41", + "OBJ_51" ); dependencies = ( - "OBJ_50" + "OBJ_53" ); name = "Concurrency"; productName = "Concurrency"; @@ -25,25 +25,25 @@ }; "Concurrency::ConcurrencyPackageTests::ProductTarget" = { isa = "PBXAggregateTarget"; - buildConfigurationList = "OBJ_59"; + buildConfigurationList = "OBJ_62"; buildPhases = ( ); dependencies = ( - "OBJ_62" + "OBJ_65" ); name = "ConcurrencyPackageTests"; productName = "ConcurrencyPackageTests"; }; "Concurrency::ConcurrencyTests" = { isa = "PBXNativeTarget"; - buildConfigurationList = "OBJ_64"; + buildConfigurationList = "OBJ_67"; buildPhases = ( - "OBJ_67", - "OBJ_73" + "OBJ_70", + "OBJ_77" ); dependencies = ( - "OBJ_76", - "OBJ_77" + "OBJ_80", + "OBJ_81" ); name = "ConcurrencyTests"; productName = "ConcurrencyTests"; @@ -57,10 +57,10 @@ }; "Concurrency::ObjCBridges" = { isa = "PBXNativeTarget"; - buildConfigurationList = "OBJ_78"; + buildConfigurationList = "OBJ_82"; buildPhases = ( - "OBJ_81", - "OBJ_83" + "OBJ_85", + "OBJ_87" ); dependencies = ( ); @@ -76,9 +76,9 @@ }; "Concurrency::SwiftPMPackageDescription" = { isa = "PBXNativeTarget"; - buildConfigurationList = "OBJ_53"; + buildConfigurationList = "OBJ_56"; buildPhases = ( - "OBJ_56" + "OBJ_59" ); dependencies = ( ); @@ -99,7 +99,7 @@ "en" ); mainGroup = "OBJ_5"; - productRefGroup = "OBJ_31"; + productRefGroup = "OBJ_33"; projectDirPath = "."; targets = ( "Concurrency::Concurrency", @@ -110,75 +110,66 @@ ); }; "OBJ_10" = { - isa = "PBXGroup"; - children = ( - "OBJ_11", - "OBJ_12" - ); - name = "include"; - path = "include"; + isa = "PBXFileReference"; + path = "AtomicInt.swift"; sourceTree = ""; }; "OBJ_11" = { isa = "PBXFileReference"; - path = "AtomicBridges.h"; + path = "AtomicReference.swift"; sourceTree = ""; }; "OBJ_12" = { isa = "PBXFileReference"; - name = "module.modulemap"; - path = "/Users/yiw/Uber/GitHub/swift-concurrency/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap"; + path = "AutoReleasingSemaphore.swift"; sourceTree = ""; }; "OBJ_13" = { + isa = "PBXFileReference"; + path = "CountDownLatch.swift"; + sourceTree = ""; + }; + "OBJ_14" = { isa = "PBXGroup"; children = ( - "OBJ_14", "OBJ_15", "OBJ_16", "OBJ_17", "OBJ_18" ); - name = "Concurrency"; - path = "Sources/Concurrency"; - sourceTree = "SOURCE_ROOT"; - }; - "OBJ_14" = { - isa = "PBXFileReference"; - path = "AtomicBool.swift"; + name = "Executor"; + path = "Executor"; sourceTree = ""; }; "OBJ_15" = { isa = "PBXFileReference"; - path = "AtomicInt.swift"; + path = "ConcurrentSequenceExecutor.swift"; sourceTree = ""; }; "OBJ_16" = { isa = "PBXFileReference"; - path = "AtomicReference.swift"; + path = "ImmediateSerialSequenceExecutor.swift"; sourceTree = ""; }; "OBJ_17" = { isa = "PBXFileReference"; - path = "CountDownLatch.swift"; + path = "SequenceExecutor.swift"; sourceTree = ""; }; "OBJ_18" = { + isa = "PBXFileReference"; + path = "Task.swift"; + sourceTree = ""; + }; + "OBJ_19" = { isa = "PBXGroup"; children = ( - "OBJ_19", "OBJ_20", - "OBJ_21", - "OBJ_22" + "OBJ_21" ); - name = "Executor"; - path = "Executor"; - sourceTree = ""; - }; - "OBJ_19" = { - isa = "PBXFileReference"; - path = "ConcurrentSequenceExecutor.swift"; - sourceTree = ""; + name = "ObjCBridges"; + path = "Sources/ObjCBridges"; + sourceTree = "SOURCE_ROOT"; }; "OBJ_2" = { isa = "XCConfigurationList"; @@ -191,68 +182,71 @@ }; "OBJ_20" = { isa = "PBXFileReference"; - path = "ImmediateSerialSequenceExecutor.swift"; + path = "AtomicBridges.m"; sourceTree = ""; }; "OBJ_21" = { - isa = "PBXFileReference"; - path = "SequenceExecutor.swift"; + isa = "PBXGroup"; + children = ( + "OBJ_22", + "OBJ_23" + ); + name = "include"; + path = "include"; sourceTree = ""; }; "OBJ_22" = { isa = "PBXFileReference"; - path = "Task.swift"; + path = "AtomicBridges.h"; sourceTree = ""; }; "OBJ_23" = { + isa = "PBXFileReference"; + name = "module.modulemap"; + path = "/Users/yiw/Uber/GitHub/swift-concurrency/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap"; + sourceTree = ""; + }; + "OBJ_24" = { isa = "PBXGroup"; children = ( - "OBJ_24" + "OBJ_25" ); name = "Tests"; path = ""; sourceTree = "SOURCE_ROOT"; }; - "OBJ_24" = { + "OBJ_25" = { isa = "PBXGroup"; children = ( - "OBJ_25", "OBJ_26", "OBJ_27", "OBJ_28", - "OBJ_29" + "OBJ_29", + "OBJ_30", + "OBJ_31" ); name = "ConcurrencyTests"; path = "Tests/ConcurrencyTests"; sourceTree = "SOURCE_ROOT"; }; - "OBJ_25" = { - isa = "PBXFileReference"; - path = "AtomicBoolTests.swift"; - sourceTree = ""; - }; "OBJ_26" = { isa = "PBXFileReference"; - path = "AtomicIntTests.swift"; + path = "AtomicBoolTests.swift"; sourceTree = ""; }; "OBJ_27" = { isa = "PBXFileReference"; - path = "AtomicReferenceTests.swift"; + path = "AtomicIntTests.swift"; sourceTree = ""; }; "OBJ_28" = { isa = "PBXFileReference"; - path = "CountDownLatchTests.swift"; + path = "AtomicReferenceTests.swift"; sourceTree = ""; }; "OBJ_29" = { - isa = "PBXGroup"; - children = ( - "OBJ_30" - ); - name = "Executor"; - path = "Executor"; + isa = "PBXFileReference"; + path = "AutoReleasingSemaphoreTests.swift"; sourceTree = ""; }; "OBJ_3" = { @@ -296,30 +290,44 @@ }; "OBJ_30" = { isa = "PBXFileReference"; - path = "ConcurrentSequenceExecutorTests.swift"; + path = "CountDownLatchTests.swift"; sourceTree = ""; }; "OBJ_31" = { isa = "PBXGroup"; children = ( + "OBJ_32" + ); + name = "Executor"; + path = "Executor"; + sourceTree = ""; + }; + "OBJ_32" = { + isa = "PBXFileReference"; + path = "ConcurrentSequenceExecutorTests.swift"; + sourceTree = ""; + }; + "OBJ_33" = { + isa = "PBXGroup"; + children = ( + "Concurrency::ConcurrencyTests::Product", "Concurrency::Concurrency::Product", - "Concurrency::ObjCBridges::Product", - "Concurrency::ConcurrencyTests::Product" + "Concurrency::ObjCBridges::Product" ); name = "Products"; path = ""; sourceTree = "BUILT_PRODUCTS_DIR"; }; - "OBJ_36" = { + "OBJ_38" = { isa = "XCConfigurationList"; buildConfigurations = ( - "OBJ_37", - "OBJ_38" + "OBJ_39", + "OBJ_40" ); defaultConfigurationIsVisible = "0"; defaultConfigurationName = "Release"; }; - "OBJ_37" = { + "OBJ_39" = { isa = "XCBuildConfiguration"; buildSettings = { ENABLE_TESTABILITY = "YES"; @@ -360,7 +368,39 @@ }; name = "Debug"; }; - "OBJ_38" = { + "OBJ_4" = { + isa = "XCBuildConfiguration"; + buildSettings = { + CLANG_ENABLE_OBJC_ARC = "YES"; + COMBINE_HIDPI_IMAGES = "YES"; + COPY_PHASE_STRIP = "YES"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_OPTIMIZATION_LEVEL = "s"; + MACOSX_DEPLOYMENT_TARGET = "10.10"; + OTHER_SWIFT_FLAGS = ( + "-DXcode" + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = "macosx"; + SUPPORTED_PLATFORMS = ( + "macosx", + "iphoneos", + "iphonesimulator", + "appletvos", + "appletvsimulator", + "watchos", + "watchsimulator" + ); + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( + "SWIFT_PACKAGE" + ); + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + USE_HEADERMAP = "NO"; + }; + name = "Release"; + }; + "OBJ_40" = { isa = "XCBuildConfiguration"; buildSettings = { ENABLE_TESTABILITY = "YES"; @@ -401,118 +441,91 @@ }; name = "Release"; }; - "OBJ_39" = { + "OBJ_41" = { isa = "PBXSourcesBuildPhase"; files = ( - "OBJ_40", - "OBJ_41", "OBJ_42", "OBJ_43", "OBJ_44", "OBJ_45", "OBJ_46", - "OBJ_47" + "OBJ_47", + "OBJ_48", + "OBJ_49", + "OBJ_50" ); }; - "OBJ_4" = { - isa = "XCBuildConfiguration"; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = "YES"; - COMBINE_HIDPI_IMAGES = "YES"; - COPY_PHASE_STRIP = "YES"; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_OPTIMIZATION_LEVEL = "s"; - MACOSX_DEPLOYMENT_TARGET = "10.10"; - OTHER_SWIFT_FLAGS = ( - "-DXcode" - ); - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = "macosx"; - SUPPORTED_PLATFORMS = ( - "macosx", - "iphoneos", - "iphonesimulator", - "appletvos", - "appletvsimulator", - "watchos", - "watchsimulator" - ); - SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( - "SWIFT_PACKAGE" - ); - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - USE_HEADERMAP = "NO"; - }; - name = "Release"; - }; - "OBJ_40" = { - isa = "PBXBuildFile"; - fileRef = "OBJ_14"; - }; - "OBJ_41" = { - isa = "PBXBuildFile"; - fileRef = "OBJ_15"; - }; "OBJ_42" = { isa = "PBXBuildFile"; - fileRef = "OBJ_16"; + fileRef = "OBJ_9"; }; "OBJ_43" = { isa = "PBXBuildFile"; - fileRef = "OBJ_17"; + fileRef = "OBJ_10"; }; "OBJ_44" = { isa = "PBXBuildFile"; - fileRef = "OBJ_19"; + fileRef = "OBJ_11"; }; "OBJ_45" = { isa = "PBXBuildFile"; - fileRef = "OBJ_20"; + fileRef = "OBJ_12"; }; "OBJ_46" = { isa = "PBXBuildFile"; - fileRef = "OBJ_21"; + fileRef = "OBJ_13"; }; "OBJ_47" = { isa = "PBXBuildFile"; - fileRef = "OBJ_22"; + fileRef = "OBJ_15"; }; "OBJ_48" = { - isa = "PBXFrameworksBuildPhase"; - files = ( - "OBJ_49" - ); + isa = "PBXBuildFile"; + fileRef = "OBJ_16"; }; "OBJ_49" = { isa = "PBXBuildFile"; - fileRef = "Concurrency::ObjCBridges::Product"; + fileRef = "OBJ_17"; }; "OBJ_5" = { isa = "PBXGroup"; children = ( "OBJ_6", "OBJ_7", - "OBJ_23", - "OBJ_31" + "OBJ_24", + "OBJ_33" ); path = ""; sourceTree = ""; }; "OBJ_50" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_18"; + }; + "OBJ_51" = { + isa = "PBXFrameworksBuildPhase"; + files = ( + "OBJ_52" + ); + }; + "OBJ_52" = { + isa = "PBXBuildFile"; + fileRef = "Concurrency::ObjCBridges::Product"; + }; + "OBJ_53" = { isa = "PBXTargetDependency"; target = "Concurrency::ObjCBridges"; }; - "OBJ_53" = { + "OBJ_56" = { isa = "XCConfigurationList"; buildConfigurations = ( - "OBJ_54", - "OBJ_55" + "OBJ_57", + "OBJ_58" ); defaultConfigurationIsVisible = "0"; defaultConfigurationName = "Release"; }; - "OBJ_54" = { + "OBJ_57" = { isa = "XCBuildConfiguration"; buildSettings = { LD = "/usr/bin/true"; @@ -530,7 +543,7 @@ }; name = "Debug"; }; - "OBJ_55" = { + "OBJ_58" = { isa = "XCBuildConfiguration"; buildSettings = { LD = "/usr/bin/true"; @@ -548,57 +561,57 @@ }; name = "Release"; }; - "OBJ_56" = { + "OBJ_59" = { isa = "PBXSourcesBuildPhase"; files = ( - "OBJ_57" + "OBJ_60" ); }; - "OBJ_57" = { + "OBJ_6" = { + isa = "PBXFileReference"; + explicitFileType = "sourcecode.swift"; + path = "Package.swift"; + sourceTree = ""; + }; + "OBJ_60" = { isa = "PBXBuildFile"; fileRef = "OBJ_6"; }; - "OBJ_59" = { + "OBJ_62" = { isa = "XCConfigurationList"; buildConfigurations = ( - "OBJ_60", - "OBJ_61" + "OBJ_63", + "OBJ_64" ); defaultConfigurationIsVisible = "0"; defaultConfigurationName = "Release"; }; - "OBJ_6" = { - isa = "PBXFileReference"; - explicitFileType = "sourcecode.swift"; - path = "Package.swift"; - sourceTree = ""; - }; - "OBJ_60" = { + "OBJ_63" = { isa = "XCBuildConfiguration"; buildSettings = { }; name = "Debug"; }; - "OBJ_61" = { + "OBJ_64" = { isa = "XCBuildConfiguration"; buildSettings = { }; name = "Release"; }; - "OBJ_62" = { + "OBJ_65" = { isa = "PBXTargetDependency"; target = "Concurrency::ConcurrencyTests"; }; - "OBJ_64" = { + "OBJ_67" = { isa = "XCConfigurationList"; buildConfigurations = ( - "OBJ_65", - "OBJ_66" + "OBJ_68", + "OBJ_69" ); defaultConfigurationIsVisible = "0"; defaultConfigurationName = "Release"; }; - "OBJ_65" = { + "OBJ_68" = { isa = "XCBuildConfiguration"; buildSettings = { CLANG_ENABLE_MODULES = "YES"; @@ -637,7 +650,7 @@ }; name = "Debug"; }; - "OBJ_66" = { + "OBJ_69" = { isa = "XCBuildConfiguration"; buildSettings = { CLANG_ENABLE_MODULES = "YES"; @@ -676,79 +689,98 @@ }; name = "Release"; }; - "OBJ_67" = { - isa = "PBXSourcesBuildPhase"; - files = ( - "OBJ_68", - "OBJ_69", - "OBJ_70", - "OBJ_71", - "OBJ_72" - ); - }; - "OBJ_68" = { - isa = "PBXBuildFile"; - fileRef = "OBJ_25"; - }; - "OBJ_69" = { - isa = "PBXBuildFile"; - fileRef = "OBJ_26"; - }; "OBJ_7" = { isa = "PBXGroup"; children = ( "OBJ_8", - "OBJ_13" + "OBJ_19" ); name = "Sources"; path = ""; sourceTree = "SOURCE_ROOT"; }; "OBJ_70" = { + isa = "PBXSourcesBuildPhase"; + files = ( + "OBJ_71", + "OBJ_72", + "OBJ_73", + "OBJ_74", + "OBJ_75", + "OBJ_76" + ); + }; + "OBJ_71" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_26"; + }; + "OBJ_72" = { isa = "PBXBuildFile"; fileRef = "OBJ_27"; }; - "OBJ_71" = { + "OBJ_73" = { isa = "PBXBuildFile"; fileRef = "OBJ_28"; }; - "OBJ_72" = { + "OBJ_74" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_29"; + }; + "OBJ_75" = { isa = "PBXBuildFile"; fileRef = "OBJ_30"; }; - "OBJ_73" = { + "OBJ_76" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_32"; + }; + "OBJ_77" = { isa = "PBXFrameworksBuildPhase"; files = ( - "OBJ_74", - "OBJ_75" + "OBJ_78", + "OBJ_79" ); }; - "OBJ_74" = { + "OBJ_78" = { isa = "PBXBuildFile"; fileRef = "Concurrency::Concurrency::Product"; }; - "OBJ_75" = { + "OBJ_79" = { isa = "PBXBuildFile"; fileRef = "Concurrency::ObjCBridges::Product"; }; - "OBJ_76" = { + "OBJ_8" = { + isa = "PBXGroup"; + children = ( + "OBJ_9", + "OBJ_10", + "OBJ_11", + "OBJ_12", + "OBJ_13", + "OBJ_14" + ); + name = "Concurrency"; + path = "Sources/Concurrency"; + sourceTree = "SOURCE_ROOT"; + }; + "OBJ_80" = { isa = "PBXTargetDependency"; target = "Concurrency::Concurrency"; }; - "OBJ_77" = { + "OBJ_81" = { isa = "PBXTargetDependency"; target = "Concurrency::ObjCBridges"; }; - "OBJ_78" = { + "OBJ_82" = { isa = "XCConfigurationList"; buildConfigurations = ( - "OBJ_79", - "OBJ_80" + "OBJ_83", + "OBJ_84" ); defaultConfigurationIsVisible = "0"; defaultConfigurationName = "Release"; }; - "OBJ_79" = { + "OBJ_83" = { isa = "XCBuildConfiguration"; buildSettings = { DEFINES_MODULE = "NO"; @@ -786,17 +818,7 @@ }; name = "Debug"; }; - "OBJ_8" = { - isa = "PBXGroup"; - children = ( - "OBJ_9", - "OBJ_10" - ); - name = "ObjCBridges"; - path = "Sources/ObjCBridges"; - sourceTree = "SOURCE_ROOT"; - }; - "OBJ_80" = { + "OBJ_84" = { isa = "XCBuildConfiguration"; buildSettings = { DEFINES_MODULE = "NO"; @@ -834,24 +856,24 @@ }; name = "Release"; }; - "OBJ_81" = { + "OBJ_85" = { isa = "PBXSourcesBuildPhase"; files = ( - "OBJ_82" + "OBJ_86" ); }; - "OBJ_82" = { + "OBJ_86" = { isa = "PBXBuildFile"; - fileRef = "OBJ_9"; + fileRef = "OBJ_20"; }; - "OBJ_83" = { + "OBJ_87" = { isa = "PBXFrameworksBuildPhase"; files = ( ); }; "OBJ_9" = { isa = "PBXFileReference"; - path = "AtomicBridges.m"; + path = "AtomicBool.swift"; sourceTree = ""; }; }; diff --git a/Sources/Concurrency/AutoReleasingSemaphore.swift b/Sources/Concurrency/AutoReleasingSemaphore.swift new file mode 100644 index 0000000..67b7db6 --- /dev/null +++ b/Sources/Concurrency/AutoReleasingSemaphore.swift @@ -0,0 +1,83 @@ +// +// Copyright (c) 2018. Uber Technologies +// +// 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 Foundation + +/// Similar to `DispatchSemaphore`, `AutoReleasingSemaphore` is a +/// synchronization mechanism that ensures only a set number of threads can +/// concurrently access a protected resource. Unlike `DispatchSemaphore`, +/// `AutoReleasingSemaphore` auto-releases all blocked threads when the +/// semaphore itself is deallocated. +public class AutoReleasingSemaphore { + + /// Initializer. + /// + /// - parameter value: The starting value for the semaphore. Do not + /// pass a value less than zero. + public init(value: Int) { + semaphore = DispatchSemaphore(value: value) + } + + /// Signals, or increments, a semaphore. + /// + /// - note: Increment the counting semaphore. If the previous value + /// was less than zero, this function wakes a thread currently waiting + /// in dispatch_semaphore_wait(_:_:). + /// - returns: This function returns non-zero if a thread is woken. + /// Otherwise, zero is returned. + public func signal() -> Int { + let newValue = waitingCount.decrementAndGet() + if newValue < 0 { + waitingCount.value = 0 + } + return semaphore.signal() + } + + /// Waits for, or decrements, a semaphore. + /// + /// - note: Decrement the counting semaphore. If the resulting value + /// is less than zero, this function waits for a signal to occur + /// before returning. + public func wait() { + waitingCount.incrementAndGet() + semaphore.wait() + } + + /// Waits for, or decrements, a semaphore for up to the specified + /// time. + /// + /// - note: Decrement the counting semaphore. If the resulting value + /// is less than zero, this function waits for a signal to occur + /// before returning. + /// - parameter timeout: The amount of time in seconds to wait + /// before returning with failure. + /// - returns: The waiting result. + public func wait(timeout: TimeInterval) -> DispatchTimeoutResult { + waitingCount.incrementAndGet() + return semaphore.wait(timeout: DispatchTime.now() + timeout) + } + + deinit { + for _ in 0 ..< waitingCount.value { + semaphore.signal() + } + } + + // MARK: - Private + + private let semaphore: DispatchSemaphore + private let waitingCount = AtomicInt(initialValue: 0) +} diff --git a/Tests/ConcurrencyTests/AutoReleasingSemaphoreTests.swift b/Tests/ConcurrencyTests/AutoReleasingSemaphoreTests.swift new file mode 100644 index 0000000..23991d6 --- /dev/null +++ b/Tests/ConcurrencyTests/AutoReleasingSemaphoreTests.swift @@ -0,0 +1,67 @@ +// +// Copyright (c) 2018. Uber Technologies +// +// 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 XCTest +@testable import Concurrency + +class AutoReleasingSemaphoreTests: XCTestCase { + + func test_wait_releaseAfterWait_verifyAutoRelease() { + var semaphore: AutoReleasingSemaphore? = AutoReleasingSemaphore(value: 1) + + let autoreleaseExpectation = expectation(description: "autoreleaseExpectation") + DispatchQueue.global(qos: .background).async { + semaphore!.wait() + autoreleaseExpectation.fulfill() + } + + Thread.sleep(forTimeInterval: 1) + semaphore = nil + + waitForExpectations(timeout: 5, handler: nil) + } + + func test_waitWithTimeout_verifyTimeout() { + let semaphore = AutoReleasingSemaphore(value: 0) + + let waitExpectation = expectation(description: "waitExpectation") + DispatchQueue.global(qos: .background).async { + let result = semaphore.wait(timeout: 1) + XCTAssertEqual(result, DispatchTimeoutResult.timedOut) + waitExpectation.fulfill() + } + + waitForExpectations(timeout: 5, handler: nil) + } + + func test_wait_releaseAfterWait_overSignaling_verifyAutoRelease() { + var semaphore: AutoReleasingSemaphore? = AutoReleasingSemaphore(value: 1) + for _ in 0 ..< 1000 { + _ = semaphore!.signal() + } + + let autoreleaseExpectation = expectation(description: "autoreleaseExpectation") + DispatchQueue.global(qos: .background).async { + semaphore!.wait() + autoreleaseExpectation.fulfill() + } + + Thread.sleep(forTimeInterval: 1) + semaphore = nil + + waitForExpectations(timeout: 5, handler: nil) + } +} From 60edf0ab22a7e45332e2f68bef5c74e3b2dbfd88 Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Wed, 20 Feb 2019 11:24:30 -0800 Subject: [PATCH 13/17] Signal concurrency limiting semaphore when task errors (#31) This fixes the issue where if a task throws an error during execution, the concurrency limiting semaphore is never signaled. This can hault the entire sequence since no new tasks can continue execution. --- Concurrency.xcodeproj/project.pbxproj | 100 +++++++++--------- .../Executor/ConcurrentSequenceExecutor.swift | 1 + .../ConcurrentSequenceExecutorTests.swift | 63 +++++++++++ 3 files changed, 114 insertions(+), 50 deletions(-) diff --git a/Concurrency.xcodeproj/project.pbxproj b/Concurrency.xcodeproj/project.pbxproj index 0109e86..34dba73 100644 --- a/Concurrency.xcodeproj/project.pbxproj +++ b/Concurrency.xcodeproj/project.pbxproj @@ -110,66 +110,76 @@ ); }; "OBJ_10" = { - isa = "PBXFileReference"; - path = "AtomicInt.swift"; + isa = "PBXGroup"; + children = ( + "OBJ_11", + "OBJ_12" + ); + name = "include"; + path = "include"; sourceTree = ""; }; "OBJ_11" = { isa = "PBXFileReference"; - path = "AtomicReference.swift"; + path = "AtomicBridges.h"; sourceTree = ""; }; "OBJ_12" = { isa = "PBXFileReference"; - path = "AutoReleasingSemaphore.swift"; + name = "module.modulemap"; + path = "/Users/yiw/Uber/GitHub/swift-concurrency/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap"; sourceTree = ""; }; "OBJ_13" = { - isa = "PBXFileReference"; - path = "CountDownLatch.swift"; - sourceTree = ""; - }; - "OBJ_14" = { isa = "PBXGroup"; children = ( + "OBJ_14", "OBJ_15", "OBJ_16", "OBJ_17", - "OBJ_18" + "OBJ_18", + "OBJ_19" ); - name = "Executor"; - path = "Executor"; + name = "Concurrency"; + path = "Sources/Concurrency"; + sourceTree = "SOURCE_ROOT"; + }; + "OBJ_14" = { + isa = "PBXFileReference"; + path = "AtomicBool.swift"; sourceTree = ""; }; "OBJ_15" = { isa = "PBXFileReference"; - path = "ConcurrentSequenceExecutor.swift"; + path = "AtomicInt.swift"; sourceTree = ""; }; "OBJ_16" = { isa = "PBXFileReference"; - path = "ImmediateSerialSequenceExecutor.swift"; + path = "AtomicReference.swift"; sourceTree = ""; }; "OBJ_17" = { isa = "PBXFileReference"; - path = "SequenceExecutor.swift"; + path = "AutoReleasingSemaphore.swift"; sourceTree = ""; }; "OBJ_18" = { isa = "PBXFileReference"; - path = "Task.swift"; + path = "CountDownLatch.swift"; sourceTree = ""; }; "OBJ_19" = { isa = "PBXGroup"; children = ( "OBJ_20", - "OBJ_21" + "OBJ_21", + "OBJ_22", + "OBJ_23" ); - name = "ObjCBridges"; - path = "Sources/ObjCBridges"; - sourceTree = "SOURCE_ROOT"; + name = "Executor"; + path = "Executor"; + sourceTree = ""; }; "OBJ_2" = { isa = "XCConfigurationList"; @@ -182,28 +192,22 @@ }; "OBJ_20" = { isa = "PBXFileReference"; - path = "AtomicBridges.m"; + path = "ConcurrentSequenceExecutor.swift"; sourceTree = ""; }; "OBJ_21" = { - isa = "PBXGroup"; - children = ( - "OBJ_22", - "OBJ_23" - ); - name = "include"; - path = "include"; + isa = "PBXFileReference"; + path = "ImmediateSerialSequenceExecutor.swift"; sourceTree = ""; }; "OBJ_22" = { isa = "PBXFileReference"; - path = "AtomicBridges.h"; + path = "SequenceExecutor.swift"; sourceTree = ""; }; "OBJ_23" = { isa = "PBXFileReference"; - name = "module.modulemap"; - path = "/Users/yiw/Uber/GitHub/swift-concurrency/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap"; + path = "Task.swift"; sourceTree = ""; }; "OBJ_24" = { @@ -457,35 +461,35 @@ }; "OBJ_42" = { isa = "PBXBuildFile"; - fileRef = "OBJ_9"; + fileRef = "OBJ_14"; }; "OBJ_43" = { isa = "PBXBuildFile"; - fileRef = "OBJ_10"; + fileRef = "OBJ_15"; }; "OBJ_44" = { isa = "PBXBuildFile"; - fileRef = "OBJ_11"; + fileRef = "OBJ_16"; }; "OBJ_45" = { isa = "PBXBuildFile"; - fileRef = "OBJ_12"; + fileRef = "OBJ_17"; }; "OBJ_46" = { isa = "PBXBuildFile"; - fileRef = "OBJ_13"; + fileRef = "OBJ_18"; }; "OBJ_47" = { isa = "PBXBuildFile"; - fileRef = "OBJ_15"; + fileRef = "OBJ_20"; }; "OBJ_48" = { isa = "PBXBuildFile"; - fileRef = "OBJ_16"; + fileRef = "OBJ_21"; }; "OBJ_49" = { isa = "PBXBuildFile"; - fileRef = "OBJ_17"; + fileRef = "OBJ_22"; }; "OBJ_5" = { isa = "PBXGroup"; @@ -500,7 +504,7 @@ }; "OBJ_50" = { isa = "PBXBuildFile"; - fileRef = "OBJ_18"; + fileRef = "OBJ_23"; }; "OBJ_51" = { isa = "PBXFrameworksBuildPhase"; @@ -693,7 +697,7 @@ isa = "PBXGroup"; children = ( "OBJ_8", - "OBJ_19" + "OBJ_13" ); name = "Sources"; path = ""; @@ -753,14 +757,10 @@ isa = "PBXGroup"; children = ( "OBJ_9", - "OBJ_10", - "OBJ_11", - "OBJ_12", - "OBJ_13", - "OBJ_14" + "OBJ_10" ); - name = "Concurrency"; - path = "Sources/Concurrency"; + name = "ObjCBridges"; + path = "Sources/ObjCBridges"; sourceTree = "SOURCE_ROOT"; }; "OBJ_80" = { @@ -864,7 +864,7 @@ }; "OBJ_86" = { isa = "PBXBuildFile"; - fileRef = "OBJ_20"; + fileRef = "OBJ_9"; }; "OBJ_87" = { isa = "PBXFrameworksBuildPhase"; @@ -873,7 +873,7 @@ }; "OBJ_9" = { isa = "PBXFileReference"; - path = "AtomicBool.swift"; + path = "AtomicBridges.m"; sourceTree = ""; }; }; diff --git a/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift b/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift index 25aa8ac..ef27fa1 100644 --- a/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift +++ b/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift @@ -93,6 +93,7 @@ public class ConcurrentSequenceExecutor: SequenceExecutor { sequenceHandle.sequenceDidComplete(with: result) } } catch { + self.taskSemaphore?.signal() sequenceHandle.sequenceDidError(with: error) } } diff --git a/Tests/ConcurrencyTests/Executor/ConcurrentSequenceExecutorTests.swift b/Tests/ConcurrencyTests/Executor/ConcurrentSequenceExecutorTests.swift index 8c199d8..0aaf873 100644 --- a/Tests/ConcurrencyTests/Executor/ConcurrentSequenceExecutorTests.swift +++ b/Tests/ConcurrencyTests/Executor/ConcurrentSequenceExecutorTests.swift @@ -173,6 +173,69 @@ class ConcurrentSequenceExecutorTests: XCTestCase { } } } + + func test_executeSequence_limitMaxConcurrentTasks_withSuccessTasks_verifyCompletion() { + let executor = ConcurrentSequenceExecutor(name: "test_executeSequence_withNonTerminatingSequence_withTimeout_verifyAwaitTimeout", maxConcurrentTasks: 1) + + let taskCount = AtomicInt(initialValue: 0) + let sequencedTask = MockSelfRepeatingTask(id: 123) { + return 0 + } + + let handle = executor.executeSequence(from: sequencedTask) { _, _ -> SequenceExecution in + let nextTask = MockSelfRepeatingTask(id: 123) { + return 0 + } + let newCount = taskCount.incrementAndGet() + if newCount > 10 { + return .endOfSequence(32838) + } else { + return .continueSequence(nextTask) + } + } + + do { + _ = try handle.await(withTimeout: 0.5) + } catch { + XCTFail() + } + } + + func test_executeSequence_limitMaxConcurrentTasks_withErrorTasks_verifyCompletion() { + let executor = ConcurrentSequenceExecutor(name: "test_executeSequence_withNonTerminatingSequence_withTimeout_verifyAwaitTimeout", maxConcurrentTasks: 1) + + let taskCount = AtomicInt(initialValue: 0) + let sequencedTask = MockSelfRepeatingTask(id: 123) { + return 0 + } + + let handle = executor.executeSequence(from: sequencedTask) { _, _ -> SequenceExecution in + let newCount = taskCount.incrementAndGet() + if newCount > 10 { + let errorTask = MockSelfRepeatingTask(id: 123) { + throw MockError.messagedError("ghasvhfjhbafjkh") + } + return .continueSequence(errorTask) + } else { + let nextTask = MockSelfRepeatingTask(id: 123) { + return 0 + } + return .continueSequence(nextTask) + } + } + + do { + _ = try handle.await(withTimeout: nil) + XCTFail() + } catch { + switch error { + case MockError.messagedError(let message): + XCTAssertEqual(message, "ghasvhfjhbafjkh") + default: + XCTFail() + } + } + } } class MockSelfRepeatingTask: AbstractTask { From e29e42c41c47c82ec32d3a2b2695719c32415ca9 Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Wed, 20 Feb 2019 13:49:22 -0800 Subject: [PATCH 14/17] Update ConcurrentSequenceExecutor to use AutoReleasingSemaphore (#33) * Update ConcurrentSequenceExecutor to use AutoReleasingSemaphore Fixes #29 * Remove debugging code --- Sources/Concurrency/AutoReleasingSemaphore.swift | 2 ++ Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Sources/Concurrency/AutoReleasingSemaphore.swift b/Sources/Concurrency/AutoReleasingSemaphore.swift index 67b7db6..34a1c20 100644 --- a/Sources/Concurrency/AutoReleasingSemaphore.swift +++ b/Sources/Concurrency/AutoReleasingSemaphore.swift @@ -38,6 +38,7 @@ public class AutoReleasingSemaphore { /// in dispatch_semaphore_wait(_:_:). /// - returns: This function returns non-zero if a thread is woken. /// Otherwise, zero is returned. + @discardableResult public func signal() -> Int { let newValue = waitingCount.decrementAndGet() if newValue < 0 { @@ -65,6 +66,7 @@ public class AutoReleasingSemaphore { /// - parameter timeout: The amount of time in seconds to wait /// before returning with failure. /// - returns: The waiting result. + @discardableResult public func wait(timeout: TimeInterval) -> DispatchTimeoutResult { waitingCount.incrementAndGet() return semaphore.wait(timeout: DispatchTime.now() + timeout) diff --git a/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift b/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift index ef27fa1..35f6570 100644 --- a/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift +++ b/Sources/Concurrency/Executor/ConcurrentSequenceExecutor.swift @@ -39,7 +39,7 @@ public class ConcurrentSequenceExecutor: SequenceExecutor { public init(name: String, qos: DispatchQoS = .userInitiated, shouldTrackTaskId: Bool = false, maxConcurrentTasks: Int? = nil) { taskQueue = DispatchQueue(label: "Executor.taskQueue-\(name)", qos: qos, attributes: .concurrent) if let maxConcurrentTasks = maxConcurrentTasks { - taskSemaphore = DispatchSemaphore(value: maxConcurrentTasks) + taskSemaphore = AutoReleasingSemaphore(value: maxConcurrentTasks) } else { taskSemaphore = nil } @@ -66,7 +66,7 @@ public class ConcurrentSequenceExecutor: SequenceExecutor { // MARK: - Private private let taskQueue: DispatchQueue - private let taskSemaphore: DispatchSemaphore? + private let taskSemaphore: AutoReleasingSemaphore? private let shouldTrackTaskId: Bool private func execute(_ task: Task, with sequenceHandle: SynchronizedSequenceExecutionHandle, _ execution: @escaping (Task, Any) -> SequenceExecution) { From ccb486645fd0e71e5b6f024a4a1c12f113096439 Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Fri, 5 Apr 2019 13:16:40 -0700 Subject: [PATCH 15/17] Add related projects to top-level README (#34) --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 8f95362..3ae349f 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,12 @@ $ swift test Or you can follow the steps above to generate a Xcode project and run tests within Xcode. +## Related projects + +If you like Needle, check out other related open source projects from our team: +- [Needle](https://github.com/uber/needle): a compile-time safe Swift dependency injection framework. +- [Swift Abstract Class](https://github.com/uber/swift-abstract-class): a light-weight library along with an executable that enables compile-time safe abstract class development for Swift projects. +- [Swift Common](https://github.com/uber/swift-common): common libraries used by this set of Swift open source projects. ## License [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fuber%2Fswift-concurrency.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fuber%2Fswift-concurrency?ref=badge_large) From 12c72339313872378cb2dc08c45230654756ef43 Mon Sep 17 00:00:00 2001 From: Cameron Mc Gorian Date: Wed, 2 Oct 2019 14:26:02 +0200 Subject: [PATCH 16/17] Fix Carthage Build --- Concurrency.xcodeproj/project.pbxproj | 563 ++++++++++-------- Package.xcconfig | 2 + .../Concurrency/Concurrency-Bridging-Header.h | 23 + 3 files changed, 342 insertions(+), 246 deletions(-) create mode 100644 Package.xcconfig create mode 100644 Sources/Concurrency/Concurrency-Bridging-Header.h diff --git a/Concurrency.xcodeproj/project.pbxproj b/Concurrency.xcodeproj/project.pbxproj index 34dba73..b1c01df 100644 --- a/Concurrency.xcodeproj/project.pbxproj +++ b/Concurrency.xcodeproj/project.pbxproj @@ -5,13 +5,13 @@ objects = { "Concurrency::Concurrency" = { isa = "PBXNativeTarget"; - buildConfigurationList = "OBJ_38"; + buildConfigurationList = "OBJ_47"; buildPhases = ( - "OBJ_41", - "OBJ_51" + "OBJ_50", + "OBJ_60" ); dependencies = ( - "OBJ_53" + "OBJ_62" ); name = "Concurrency"; productName = "Concurrency"; @@ -25,25 +25,25 @@ }; "Concurrency::ConcurrencyPackageTests::ProductTarget" = { isa = "PBXAggregateTarget"; - buildConfigurationList = "OBJ_62"; + buildConfigurationList = "OBJ_71"; buildPhases = ( ); dependencies = ( - "OBJ_65" + "OBJ_74" ); name = "ConcurrencyPackageTests"; productName = "ConcurrencyPackageTests"; }; "Concurrency::ConcurrencyTests" = { isa = "PBXNativeTarget"; - buildConfigurationList = "OBJ_67"; + buildConfigurationList = "OBJ_76"; buildPhases = ( - "OBJ_70", - "OBJ_77" + "OBJ_79", + "OBJ_86" ); dependencies = ( - "OBJ_80", - "OBJ_81" + "OBJ_89", + "OBJ_90" ); name = "ConcurrencyTests"; productName = "ConcurrencyTests"; @@ -57,10 +57,10 @@ }; "Concurrency::ObjCBridges" = { isa = "PBXNativeTarget"; - buildConfigurationList = "OBJ_82"; + buildConfigurationList = "OBJ_91"; buildPhases = ( - "OBJ_85", - "OBJ_87" + "OBJ_94", + "OBJ_96" ); dependencies = ( ); @@ -76,9 +76,9 @@ }; "Concurrency::SwiftPMPackageDescription" = { isa = "PBXNativeTarget"; - buildConfigurationList = "OBJ_56"; + buildConfigurationList = "OBJ_65"; buildPhases = ( - "OBJ_59" + "OBJ_68" ); dependencies = ( ); @@ -89,6 +89,7 @@ "OBJ_1" = { isa = "PBXProject"; attributes = { + LastSwiftMigration = "9999"; LastUpgradeCheck = "9999"; }; buildConfigurationList = "OBJ_2"; @@ -99,7 +100,7 @@ "en" ); mainGroup = "OBJ_5"; - productRefGroup = "OBJ_33"; + productRefGroup = "OBJ_36"; projectDirPath = "."; targets = ( "Concurrency::Concurrency", @@ -113,74 +114,69 @@ isa = "PBXGroup"; children = ( "OBJ_11", - "OBJ_12" - ); - name = "include"; - path = "include"; - sourceTree = ""; - }; - "OBJ_11" = { - isa = "PBXFileReference"; - path = "AtomicBridges.h"; - sourceTree = ""; - }; - "OBJ_12" = { - isa = "PBXFileReference"; - name = "module.modulemap"; - path = "/Users/yiw/Uber/GitHub/swift-concurrency/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap"; - sourceTree = ""; - }; - "OBJ_13" = { - isa = "PBXGroup"; - children = ( + "OBJ_12", + "OBJ_13", "OBJ_14", "OBJ_15", "OBJ_16", - "OBJ_17", - "OBJ_18", - "OBJ_19" + "OBJ_17" ); name = "Concurrency"; path = "Sources/Concurrency"; sourceTree = "SOURCE_ROOT"; }; - "OBJ_14" = { + "OBJ_11" = { + isa = "PBXFileReference"; + path = "Concurrency-Bridging-Header.h"; + sourceTree = ""; + }; + "OBJ_12" = { isa = "PBXFileReference"; path = "AtomicBool.swift"; sourceTree = ""; }; - "OBJ_15" = { + "OBJ_13" = { isa = "PBXFileReference"; path = "AtomicInt.swift"; sourceTree = ""; }; - "OBJ_16" = { + "OBJ_14" = { isa = "PBXFileReference"; path = "AtomicReference.swift"; sourceTree = ""; }; - "OBJ_17" = { + "OBJ_15" = { isa = "PBXFileReference"; path = "AutoReleasingSemaphore.swift"; sourceTree = ""; }; - "OBJ_18" = { + "OBJ_16" = { isa = "PBXFileReference"; path = "CountDownLatch.swift"; sourceTree = ""; }; - "OBJ_19" = { + "OBJ_17" = { isa = "PBXGroup"; children = ( + "OBJ_18", + "OBJ_19", "OBJ_20", - "OBJ_21", - "OBJ_22", - "OBJ_23" + "OBJ_21" ); name = "Executor"; path = "Executor"; sourceTree = ""; }; + "OBJ_18" = { + isa = "PBXFileReference"; + path = "ConcurrentSequenceExecutor.swift"; + sourceTree = ""; + }; + "OBJ_19" = { + isa = "PBXFileReference"; + path = "ImmediateSerialSequenceExecutor.swift"; + sourceTree = ""; + }; "OBJ_2" = { isa = "XCConfigurationList"; buildConfigurations = ( @@ -192,65 +188,76 @@ }; "OBJ_20" = { isa = "PBXFileReference"; - path = "ConcurrentSequenceExecutor.swift"; + path = "SequenceExecutor.swift"; sourceTree = ""; }; "OBJ_21" = { isa = "PBXFileReference"; - path = "ImmediateSerialSequenceExecutor.swift"; + path = "Task.swift"; sourceTree = ""; }; "OBJ_22" = { - isa = "PBXFileReference"; - path = "SequenceExecutor.swift"; - sourceTree = ""; + isa = "PBXGroup"; + children = ( + "OBJ_23", + "OBJ_24" + ); + name = "ObjCBridges"; + path = "Sources/ObjCBridges"; + sourceTree = "SOURCE_ROOT"; }; "OBJ_23" = { isa = "PBXFileReference"; - path = "Task.swift"; + path = "AtomicBridges.m"; sourceTree = ""; }; "OBJ_24" = { isa = "PBXGroup"; children = ( - "OBJ_25" + "OBJ_25", + "OBJ_26" + ); + name = "include"; + path = "include"; + sourceTree = ""; + }; + "OBJ_25" = { + isa = "PBXFileReference"; + path = "AtomicBridges.h"; + sourceTree = ""; + }; + "OBJ_26" = { + isa = "PBXFileReference"; + name = "module.modulemap"; + path = "/Users/cameronmcgorian/Documents/dev/swift-concurrency/Concurrency.xcodeproj/GeneratedModuleMap/ObjCBridges/module.modulemap"; + sourceTree = ""; + }; + "OBJ_27" = { + isa = "PBXGroup"; + children = ( + "OBJ_28" ); name = "Tests"; path = ""; sourceTree = "SOURCE_ROOT"; }; - "OBJ_25" = { + "OBJ_28" = { isa = "PBXGroup"; children = ( - "OBJ_26", - "OBJ_27", - "OBJ_28", "OBJ_29", "OBJ_30", - "OBJ_31" + "OBJ_31", + "OBJ_32", + "OBJ_33", + "OBJ_34" ); name = "ConcurrencyTests"; path = "Tests/ConcurrencyTests"; sourceTree = "SOURCE_ROOT"; }; - "OBJ_26" = { - isa = "PBXFileReference"; - path = "AtomicBoolTests.swift"; - sourceTree = ""; - }; - "OBJ_27" = { - isa = "PBXFileReference"; - path = "AtomicIntTests.swift"; - sourceTree = ""; - }; - "OBJ_28" = { - isa = "PBXFileReference"; - path = "AtomicReferenceTests.swift"; - sourceTree = ""; - }; "OBJ_29" = { isa = "PBXFileReference"; - path = "AutoReleasingSemaphoreTests.swift"; + path = "AtomicBoolTests.swift"; sourceTree = ""; }; "OBJ_3" = { @@ -264,8 +271,9 @@ ENABLE_NS_ASSERTIONS = "YES"; GCC_OPTIMIZATION_LEVEL = "0"; GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)" + "$(inherited)", + "SWIFT_PACKAGE=1", + "DEBUG=1" ); MACOSX_DEPLOYMENT_TARGET = "10.10"; ONLY_ACTIVE_ARCH = "YES"; @@ -284,6 +292,7 @@ "watchsimulator" ); SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( + "$(inherited)", "SWIFT_PACKAGE", "DEBUG" ); @@ -294,45 +303,128 @@ }; "OBJ_30" = { isa = "PBXFileReference"; - path = "CountDownLatchTests.swift"; + path = "AtomicIntTests.swift"; sourceTree = ""; }; "OBJ_31" = { + isa = "PBXFileReference"; + path = "AtomicReferenceTests.swift"; + sourceTree = ""; + }; + "OBJ_32" = { + isa = "PBXFileReference"; + path = "AutoReleasingSemaphoreTests.swift"; + sourceTree = ""; + }; + "OBJ_33" = { + isa = "PBXFileReference"; + path = "CountDownLatchTests.swift"; + sourceTree = ""; + }; + "OBJ_34" = { isa = "PBXGroup"; children = ( - "OBJ_32" + "OBJ_35" ); name = "Executor"; path = "Executor"; sourceTree = ""; }; - "OBJ_32" = { + "OBJ_35" = { isa = "PBXFileReference"; path = "ConcurrentSequenceExecutorTests.swift"; sourceTree = ""; }; - "OBJ_33" = { + "OBJ_36" = { isa = "PBXGroup"; children = ( - "Concurrency::ConcurrencyTests::Product", "Concurrency::Concurrency::Product", + "Concurrency::ConcurrencyTests::Product", "Concurrency::ObjCBridges::Product" ); name = "Products"; path = ""; sourceTree = "BUILT_PRODUCTS_DIR"; }; - "OBJ_38" = { + "OBJ_4" = { + isa = "XCBuildConfiguration"; + buildSettings = { + CLANG_ENABLE_OBJC_ARC = "YES"; + COMBINE_HIDPI_IMAGES = "YES"; + COPY_PHASE_STRIP = "YES"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_OPTIMIZATION_LEVEL = "s"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "SWIFT_PACKAGE=1" + ); + MACOSX_DEPLOYMENT_TARGET = "10.10"; + OTHER_SWIFT_FLAGS = ( + "-DXcode" + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = "macosx"; + SUPPORTED_PLATFORMS = ( + "macosx", + "iphoneos", + "iphonesimulator", + "appletvos", + "appletvsimulator", + "watchos", + "watchsimulator" + ); + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( + "$(inherited)", + "SWIFT_PACKAGE" + ); + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + USE_HEADERMAP = "NO"; + }; + name = "Release"; + }; + "OBJ_40" = { + isa = "PBXFileReference"; + path = "CODE_OF_CONDUCT.md"; + sourceTree = ""; + }; + "OBJ_41" = { + isa = "PBXFileReference"; + path = "Package.xcconfig"; + sourceTree = ""; + }; + "OBJ_42" = { + isa = "PBXFileReference"; + path = "README.md"; + sourceTree = ""; + }; + "OBJ_43" = { + isa = "PBXFileReference"; + path = "NOTICE.txt"; + sourceTree = ""; + }; + "OBJ_44" = { + isa = "PBXFileReference"; + path = "CONTRIBUTING.md"; + sourceTree = ""; + }; + "OBJ_45" = { + isa = "PBXFileReference"; + path = "LICENSE.txt"; + sourceTree = ""; + }; + "OBJ_47" = { isa = "XCConfigurationList"; buildConfigurations = ( - "OBJ_39", - "OBJ_40" + "OBJ_48", + "OBJ_49" ); defaultConfigurationIsVisible = "0"; defaultConfigurationName = "Release"; }; - "OBJ_39" = { + "OBJ_48" = { isa = "XCBuildConfiguration"; + baseConfigurationReference = "OBJ_8"; buildSettings = { ENABLE_TESTABILITY = "YES"; FRAMEWORK_SEARCH_PATHS = ( @@ -372,40 +464,9 @@ }; name = "Debug"; }; - "OBJ_4" = { - isa = "XCBuildConfiguration"; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = "YES"; - COMBINE_HIDPI_IMAGES = "YES"; - COPY_PHASE_STRIP = "YES"; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_OPTIMIZATION_LEVEL = "s"; - MACOSX_DEPLOYMENT_TARGET = "10.10"; - OTHER_SWIFT_FLAGS = ( - "-DXcode" - ); - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = "macosx"; - SUPPORTED_PLATFORMS = ( - "macosx", - "iphoneos", - "iphonesimulator", - "appletvos", - "appletvsimulator", - "watchos", - "watchsimulator" - ); - SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( - "SWIFT_PACKAGE" - ); - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - USE_HEADERMAP = "NO"; - }; - name = "Release"; - }; - "OBJ_40" = { + "OBJ_49" = { isa = "XCBuildConfiguration"; + baseConfigurationReference = "OBJ_8"; buildSettings = { ENABLE_TESTABILITY = "YES"; FRAMEWORK_SEARCH_PATHS = ( @@ -445,91 +506,104 @@ }; name = "Release"; }; - "OBJ_41" = { - isa = "PBXSourcesBuildPhase"; - files = ( + "OBJ_5" = { + isa = "PBXGroup"; + children = ( + "OBJ_6", + "OBJ_7", + "OBJ_9", + "OBJ_27", + "OBJ_36", + "OBJ_40", + "OBJ_41", "OBJ_42", "OBJ_43", "OBJ_44", - "OBJ_45", - "OBJ_46", - "OBJ_47", - "OBJ_48", - "OBJ_49", - "OBJ_50" + "OBJ_45" ); + path = ""; + sourceTree = ""; }; - "OBJ_42" = { + "OBJ_50" = { + isa = "PBXSourcesBuildPhase"; + files = ( + "OBJ_51", + "OBJ_52", + "OBJ_53", + "OBJ_54", + "OBJ_55", + "OBJ_56", + "OBJ_57", + "OBJ_58", + "OBJ_59" + ); + }; + "OBJ_51" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_12"; + }; + "OBJ_52" = { + isa = "PBXBuildFile"; + fileRef = "OBJ_13"; + }; + "OBJ_53" = { isa = "PBXBuildFile"; fileRef = "OBJ_14"; }; - "OBJ_43" = { + "OBJ_54" = { isa = "PBXBuildFile"; fileRef = "OBJ_15"; }; - "OBJ_44" = { + "OBJ_55" = { isa = "PBXBuildFile"; fileRef = "OBJ_16"; }; - "OBJ_45" = { + "OBJ_56" = { isa = "PBXBuildFile"; - fileRef = "OBJ_17"; + fileRef = "OBJ_18"; }; - "OBJ_46" = { + "OBJ_57" = { isa = "PBXBuildFile"; - fileRef = "OBJ_18"; + fileRef = "OBJ_19"; }; - "OBJ_47" = { + "OBJ_58" = { isa = "PBXBuildFile"; fileRef = "OBJ_20"; }; - "OBJ_48" = { + "OBJ_59" = { isa = "PBXBuildFile"; fileRef = "OBJ_21"; }; - "OBJ_49" = { - isa = "PBXBuildFile"; - fileRef = "OBJ_22"; - }; - "OBJ_5" = { - isa = "PBXGroup"; - children = ( - "OBJ_6", - "OBJ_7", - "OBJ_24", - "OBJ_33" - ); - path = ""; + "OBJ_6" = { + isa = "PBXFileReference"; + explicitFileType = "sourcecode.swift"; + path = "Package.swift"; sourceTree = ""; }; - "OBJ_50" = { - isa = "PBXBuildFile"; - fileRef = "OBJ_23"; - }; - "OBJ_51" = { + "OBJ_60" = { isa = "PBXFrameworksBuildPhase"; files = ( - "OBJ_52" + "OBJ_61" ); }; - "OBJ_52" = { + "OBJ_61" = { isa = "PBXBuildFile"; fileRef = "Concurrency::ObjCBridges::Product"; }; - "OBJ_53" = { + "OBJ_62" = { isa = "PBXTargetDependency"; target = "Concurrency::ObjCBridges"; }; - "OBJ_56" = { + "OBJ_65" = { isa = "XCConfigurationList"; buildConfigurations = ( - "OBJ_57", - "OBJ_58" + "OBJ_66", + "OBJ_67" ); defaultConfigurationIsVisible = "0"; defaultConfigurationName = "Release"; }; - "OBJ_57" = { + "OBJ_66" = { isa = "XCBuildConfiguration"; buildSettings = { LD = "/usr/bin/true"; @@ -541,13 +615,13 @@ "-target", "x86_64-apple-macosx10.10", "-sdk", - "/Applications/Xcode.10.1.0.10B61.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk" + "/Applications/Xcode.10.2.1.10E1001.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk" ); SWIFT_VERSION = "4.0"; }; name = "Debug"; }; - "OBJ_58" = { + "OBJ_67" = { isa = "XCBuildConfiguration"; buildSettings = { LD = "/usr/bin/true"; @@ -559,64 +633,68 @@ "-target", "x86_64-apple-macosx10.10", "-sdk", - "/Applications/Xcode.10.1.0.10B61.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk" + "/Applications/Xcode.10.2.1.10E1001.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk" ); SWIFT_VERSION = "4.0"; }; name = "Release"; }; - "OBJ_59" = { + "OBJ_68" = { isa = "PBXSourcesBuildPhase"; files = ( - "OBJ_60" + "OBJ_69" ); }; - "OBJ_6" = { - isa = "PBXFileReference"; - explicitFileType = "sourcecode.swift"; - path = "Package.swift"; - sourceTree = ""; - }; - "OBJ_60" = { + "OBJ_69" = { isa = "PBXBuildFile"; fileRef = "OBJ_6"; }; - "OBJ_62" = { + "OBJ_7" = { + isa = "PBXGroup"; + children = ( + "OBJ_8" + ); + name = "Configs"; + path = ""; + sourceTree = ""; + }; + "OBJ_71" = { isa = "XCConfigurationList"; buildConfigurations = ( - "OBJ_63", - "OBJ_64" + "OBJ_72", + "OBJ_73" ); defaultConfigurationIsVisible = "0"; defaultConfigurationName = "Release"; }; - "OBJ_63" = { + "OBJ_72" = { isa = "XCBuildConfiguration"; buildSettings = { }; name = "Debug"; }; - "OBJ_64" = { + "OBJ_73" = { isa = "XCBuildConfiguration"; buildSettings = { }; name = "Release"; }; - "OBJ_65" = { + "OBJ_74" = { isa = "PBXTargetDependency"; target = "Concurrency::ConcurrencyTests"; }; - "OBJ_67" = { + "OBJ_76" = { isa = "XCConfigurationList"; buildConfigurations = ( - "OBJ_68", - "OBJ_69" + "OBJ_77", + "OBJ_78" ); defaultConfigurationIsVisible = "0"; defaultConfigurationName = "Release"; }; - "OBJ_68" = { + "OBJ_77" = { isa = "XCBuildConfiguration"; + baseConfigurationReference = "OBJ_8"; buildSettings = { CLANG_ENABLE_MODULES = "YES"; EMBEDDED_CONTENT_CONTAINS_SWIFT = "YES"; @@ -654,8 +732,9 @@ }; name = "Debug"; }; - "OBJ_69" = { + "OBJ_78" = { isa = "XCBuildConfiguration"; + baseConfigurationReference = "OBJ_8"; buildSettings = { CLANG_ENABLE_MODULES = "YES"; EMBEDDED_CONTENT_CONTAINS_SWIFT = "YES"; @@ -693,95 +772,91 @@ }; name = "Release"; }; - "OBJ_7" = { - isa = "PBXGroup"; - children = ( - "OBJ_8", - "OBJ_13" - ); - name = "Sources"; - path = ""; - sourceTree = "SOURCE_ROOT"; - }; - "OBJ_70" = { + "OBJ_79" = { isa = "PBXSourcesBuildPhase"; files = ( - "OBJ_71", - "OBJ_72", - "OBJ_73", - "OBJ_74", - "OBJ_75", - "OBJ_76" + "OBJ_80", + "OBJ_81", + "OBJ_82", + "OBJ_83", + "OBJ_84", + "OBJ_85" ); }; - "OBJ_71" = { + "OBJ_8" = { + isa = "PBXFileReference"; + path = "Package.xcconfig"; + sourceTree = ""; + }; + "OBJ_80" = { isa = "PBXBuildFile"; - fileRef = "OBJ_26"; + fileRef = "OBJ_29"; }; - "OBJ_72" = { + "OBJ_81" = { isa = "PBXBuildFile"; - fileRef = "OBJ_27"; + fileRef = "OBJ_30"; }; - "OBJ_73" = { + "OBJ_82" = { isa = "PBXBuildFile"; - fileRef = "OBJ_28"; + fileRef = "OBJ_31"; }; - "OBJ_74" = { + "OBJ_83" = { isa = "PBXBuildFile"; - fileRef = "OBJ_29"; + fileRef = "OBJ_32"; }; - "OBJ_75" = { + "OBJ_84" = { isa = "PBXBuildFile"; - fileRef = "OBJ_30"; + fileRef = "OBJ_33"; }; - "OBJ_76" = { + "OBJ_85" = { isa = "PBXBuildFile"; - fileRef = "OBJ_32"; + fileRef = "OBJ_35"; }; - "OBJ_77" = { + "OBJ_86" = { isa = "PBXFrameworksBuildPhase"; files = ( - "OBJ_78", - "OBJ_79" + "OBJ_87", + "OBJ_88" ); }; - "OBJ_78" = { + "OBJ_87" = { isa = "PBXBuildFile"; fileRef = "Concurrency::Concurrency::Product"; }; - "OBJ_79" = { + "OBJ_88" = { isa = "PBXBuildFile"; fileRef = "Concurrency::ObjCBridges::Product"; }; - "OBJ_8" = { + "OBJ_89" = { + isa = "PBXTargetDependency"; + target = "Concurrency::Concurrency"; + }; + "OBJ_9" = { isa = "PBXGroup"; children = ( - "OBJ_9", - "OBJ_10" + "OBJ_10", + "OBJ_22" ); - name = "ObjCBridges"; - path = "Sources/ObjCBridges"; + name = "Sources"; + path = ""; sourceTree = "SOURCE_ROOT"; }; - "OBJ_80" = { - isa = "PBXTargetDependency"; - target = "Concurrency::Concurrency"; - }; - "OBJ_81" = { + "OBJ_90" = { isa = "PBXTargetDependency"; target = "Concurrency::ObjCBridges"; }; - "OBJ_82" = { + "OBJ_91" = { isa = "XCConfigurationList"; buildConfigurations = ( - "OBJ_83", - "OBJ_84" + "OBJ_92", + "OBJ_93" ); defaultConfigurationIsVisible = "0"; defaultConfigurationName = "Release"; }; - "OBJ_83" = { + "OBJ_92" = { isa = "XCBuildConfiguration"; + baseConfigurationReference = "OBJ_8"; buildSettings = { DEFINES_MODULE = "NO"; ENABLE_TESTABILITY = "YES"; @@ -818,8 +893,9 @@ }; name = "Debug"; }; - "OBJ_84" = { + "OBJ_93" = { isa = "XCBuildConfiguration"; + baseConfigurationReference = "OBJ_8"; buildSettings = { DEFINES_MODULE = "NO"; ENABLE_TESTABILITY = "YES"; @@ -856,26 +932,21 @@ }; name = "Release"; }; - "OBJ_85" = { + "OBJ_94" = { isa = "PBXSourcesBuildPhase"; files = ( - "OBJ_86" + "OBJ_95" ); }; - "OBJ_86" = { + "OBJ_95" = { isa = "PBXBuildFile"; - fileRef = "OBJ_9"; + fileRef = "OBJ_23"; }; - "OBJ_87" = { + "OBJ_96" = { isa = "PBXFrameworksBuildPhase"; files = ( ); }; - "OBJ_9" = { - isa = "PBXFileReference"; - path = "AtomicBridges.m"; - sourceTree = ""; - }; }; rootObject = "OBJ_1"; } diff --git a/Package.xcconfig b/Package.xcconfig new file mode 100644 index 0000000..057251e --- /dev/null +++ b/Package.xcconfig @@ -0,0 +1,2 @@ + +SWIFT_OBJC_BRIDGING_HEADER = Sources/Concurrency/Concurrency-Bridging-Header.h diff --git a/Sources/Concurrency/Concurrency-Bridging-Header.h b/Sources/Concurrency/Concurrency-Bridging-Header.h new file mode 100644 index 0000000..2a05e68 --- /dev/null +++ b/Sources/Concurrency/Concurrency-Bridging-Header.h @@ -0,0 +1,23 @@ +// +// Copyright (c) 2018. Uber Technologies +// +// 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. +// + +#ifndef Concurrency_Bridging_Header_h +#define Concurrency_Bridging_Header_h + +#import "AtomicBridges.h" + + +#endif /* Concurrency_Bridging_Header_h */ From 648aaecaec3e517e4e0379ac367b3b07072161cb Mon Sep 17 00:00:00 2001 From: Rudro Samanta Date: Tue, 17 Mar 2020 10:30:16 -0700 Subject: [PATCH 17/17] Move to Xcode 11 and newer SPM version (#42) --- .travis.yml | 2 +- Package.swift | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 52fe3e8..d600172 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: objective-c -osx_image: xcode10.1 +osx_image: xcode11.2 env: - ACTION=test PLATFORM=Mac DESTINATION='platform=OS X' diff --git a/Package.swift b/Package.swift index 72c0539..7025229 100644 --- a/Package.swift +++ b/Package.swift @@ -1,5 +1,4 @@ -// swift-tools-version:4.0 -// The swift-tools-version declares the minimum version of Swift required to build this package. +// swift-tools-version:5.1 import PackageDescription @@ -22,5 +21,5 @@ let package = Package( name: "ConcurrencyTests", dependencies: ["Concurrency"]), ], - swiftLanguageVersions: [4] + swiftLanguageVersions: [.v5] )