Skip to content
This repository was archived by the owner on Aug 29, 2022. It is now read-only.

Commit fbfeb4b

Browse files
committed
Merge pull request #304 from bignerdranch/zwaldowski/modern-swift
Bump minimum Swift and OS versions
2 parents 92a6ab7 + d611303 commit fbfeb4b

File tree

11 files changed

+53
-134
lines changed

11 files changed

+53
-134
lines changed

BNRDeferred.podspec

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ Pod::Spec.new do |s|
2323
s.social_media_url = "https://twitter.com/bignerdranch"
2424

2525
# ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
26-
s.swift_version = "4.2"
26+
s.swift_version = "5.1"
2727
s.cocoapods_version = ">=1.1.0"
28-
s.ios.deployment_target = "8.0"
29-
s.osx.deployment_target = "10.10"
30-
s.watchos.deployment_target = "2.0"
31-
s.tvos.deployment_target = "9.0"
28+
s.ios.deployment_target = "10.0"
29+
s.osx.deployment_target = "10.12"
30+
s.watchos.deployment_target = "3.0"
31+
s.tvos.deployment_target = "10.0"
3232

3333
# ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
3434
s.source = { :git => "https://github.com/bignerdranch/Deferred.git", :tag => "#{s.version}" }

Configurations/Base.xcconfig

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ TOOLCHAINS = default
33

44
// Deployment
55
COPY_PHASE_STRIP = NO
6-
MACOSX_DEPLOYMENT_TARGET = 10.10
7-
IPHONEOS_DEPLOYMENT_TARGET = 8.0
8-
WATCHOS_DEPLOYMENT_TARGET = 2.0
9-
TVOS_DEPLOYMENT_TARGET = 9.0
6+
MACOSX_DEPLOYMENT_TARGET = 10.12
7+
IPHONEOS_DEPLOYMENT_TARGET = 10.0
8+
WATCHOS_DEPLOYMENT_TARGET = 3.0
9+
TVOS_DEPLOYMENT_TARGET = 10.0
1010

1111
// Search Paths
1212
ALWAYS_SEARCH_USER_PATHS = NO
@@ -79,4 +79,4 @@ CLANG_ANALYZER_NONNULL = YES
7979
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE
8080

8181
// Swift Compiler - Version
82-
SWIFT_VERSION = 4.2
82+
SWIFT_VERSION = 5.1

Package.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1-
// swift-tools-version:4.2
1+
// swift-tools-version:5.1
22

33
//
44
// Package.swift
55
// Deferred
66
//
77
// Created by Zachary Waldowski on 12/7/15.
8-
// Copyright © 2015-2018 Big Nerd Ranch. Licensed under MIT.
8+
// Copyright © 2015-2020 Big Nerd Ranch. Licensed under MIT.
99
//
1010

1111
import PackageDescription
1212

1313
let package = Package(
1414
name: "Deferred",
15+
platforms: [
16+
.macOS(.v10_12), .iOS(.v10), .watchOS(.v3), .tvOS(.v10)
17+
],
1518
products: [
1619
.library(name: "Deferred", targets: [ "Deferred", "Task" ])
1720
],
@@ -31,5 +34,4 @@ let package = Package(
3134
name: "TaskTests",
3235
dependencies: [ "Deferred", "Task" ],
3336
exclude: [ "Tests/AllTestsCommon.swift" ])
34-
],
35-
swiftLanguageVersions: [.v4_2, .version("5")])
37+
])

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Deferred is a "futures library", probably like ones you've already heard about.
66

77
| **Vital Statistics** |
88
|:-------------------------------------------------------------------------------------------------------|
9-
|[![Requires Swift 4.2 or greater](https://img.shields.io/badge/swift-4.2%2B-EF5138.svg)][Swift] |
9+
|[![Requires Swift 5.1 or greater](https://img.shields.io/badge/swift-5.1%2B-EF5138.svg)][Swift] |
1010
|[![Under MIT License](https://img.shields.io/badge/license-MIT-blue.svg)][MIT] |
1111
|![Multiplatform](https://img.shields.io/badge/platforms-macOS,_iOS,_watchOS,_tvOS,_Linux-lightgrey.svg) |
1212
|[![Circle CI](https://img.shields.io/circleci/build/gh/bignerdranch/Deferred.svg)][CI] |

Sources/Deferred/Executor.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,6 @@ extension CFRunLoop: Executor {
123123
/// of the run loop.
124124
extension RunLoop: Executor {
125125
public func submit(_ body: @escaping() -> Void) {
126-
if #available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) {
127-
perform(body)
128-
} else {
129-
getCFRunLoop().submit(body)
130-
}
126+
perform(body)
131127
}
132128
}

Sources/Deferred/Locking.swift

Lines changed: 21 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -52,83 +52,61 @@ extension Locking {
5252
/// block efficiently on contention. This locking type behaves the same for both
5353
/// read and write locks.
5454
///
55-
/// - On recent versions of Darwin (iOS 10.0, macOS 12.0, tvOS 1.0, watchOS 3.0,
56-
/// or better), this efficiency is a guarantee.
55+
/// - On Apple platforms (iOS, macOS, tvOS, watchOS, or better), this efficiency is a guarantee.
5756
/// - On Linux, BSD, or Android, waiters perform comparably to a kernel lock
5857
/// under contention.
5958
public final class NativeLock: Locking {
60-
private let lock: UnsafeMutableRawPointer
59+
#if canImport(os)
60+
private let lock = UnsafeMutablePointer<os_unfair_lock>.allocate(capacity: 1)
61+
#else
62+
private let lock = UnsafeMutablePointer<pthread_mutex_t>.allocate(capacity: 1)
63+
#endif
6164

6265
/// Creates a standard platform lock.
6366
public init() {
6467
#if canImport(os)
65-
if #available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) {
66-
let lock = UnsafeMutablePointer<os_unfair_lock>.allocate(capacity: 1)
67-
lock.initialize(to: os_unfair_lock())
68-
self.lock = UnsafeMutableRawPointer(lock)
69-
return
70-
}
71-
#endif
72-
73-
let lock = UnsafeMutablePointer<pthread_mutex_t>.allocate(capacity: 1)
68+
lock.initialize(to: os_unfair_lock())
69+
#else
7470
lock.initialize(to: pthread_mutex_t())
7571
pthread_mutex_init(lock, nil)
76-
self.lock = UnsafeMutableRawPointer(lock)
72+
#endif
7773
}
7874

7975
deinit {
80-
#if canImport(os)
81-
if #available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) {
82-
let lock = self.lock.assumingMemoryBound(to: os_unfair_lock.self)
83-
lock.deinitialize(count: 1)
84-
lock.deallocate()
85-
return
86-
}
87-
#endif
88-
89-
let lock = self.lock.assumingMemoryBound(to: pthread_mutex_t.self)
76+
#if !canImport(os)
9077
pthread_mutex_destroy(lock)
78+
#endif
9179
lock.deinitialize(count: 1)
9280
lock.deallocate()
9381
}
9482

9583
public func withReadLock<Return>(_ body: () throws -> Return) rethrows -> Return {
9684
#if canImport(os)
97-
if #available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) {
98-
let lock = self.lock.assumingMemoryBound(to: os_unfair_lock.self)
99-
os_unfair_lock_lock(lock)
100-
defer {
101-
os_unfair_lock_unlock(lock)
102-
}
103-
return try body()
85+
os_unfair_lock_lock(lock)
86+
defer {
87+
os_unfair_lock_unlock(lock)
10488
}
105-
#endif
106-
107-
let lock = self.lock.assumingMemoryBound(to: pthread_mutex_t.self)
89+
#else
10890
pthread_mutex_lock(lock)
10991
defer {
11092
pthread_mutex_unlock(lock)
11193
}
94+
#endif
11295
return try body()
11396
}
11497

11598
public func withAttemptedReadLock<Return>(_ body: () throws -> Return) rethrows -> Return? {
11699
#if canImport(os)
117-
if #available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) {
118-
let lock = self.lock.assumingMemoryBound(to: os_unfair_lock.self)
119-
guard os_unfair_lock_trylock(lock) else { return nil }
120-
defer {
121-
os_unfair_lock_unlock(lock)
122-
}
123-
return try body()
100+
guard os_unfair_lock_trylock(lock) else { return nil }
101+
defer {
102+
os_unfair_lock_unlock(lock)
124103
}
125-
#endif
126-
127-
let lock = self.lock.assumingMemoryBound(to: pthread_mutex_t.self)
104+
#else
128105
guard pthread_mutex_trylock(lock) == 0 else { return nil }
129106
defer {
130107
pthread_mutex_unlock(lock)
131108
}
109+
#endif
132110
return try body()
133111
}
134112
}

Sources/Task/Progress+ExplicitComposition.swift

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ private final class ProxyProgress: Progress {
4444
observee.pause()
4545
}
4646

47-
@available(macOS 10.11, iOS 9.0, watchOS 2.0, tvOS 9.0, *)
4847
override func resume() {
4948
observee.resume()
5049
}
@@ -81,7 +80,7 @@ private final class ProxyProgress: Progress {
8180
func inheritPaused() {
8281
if observee.isPaused {
8382
super.pause()
84-
} else if #available(macOS 10.11, iOS 9.0, watchOS 2.0, tvOS 9.0, *) {
83+
} else {
8584
super.resume()
8685
}
8786
}
@@ -136,19 +135,6 @@ private final class ProxyProgress: Progress {
136135
}
137136

138137
extension Progress {
139-
/// Add a progress object as a child of a progress tree. The
140-
/// `pendingUnitCount` indicates the expected work for the progress unit.
141-
///
142-
/// This method is a shim for `Progress.addChild(_:withPendingUnitCount:)`,
143-
/// using an approximation of the behavior on iOS 8 and macOS 10.10.
144-
func adoptChild(_ child: Progress, withPendingUnitCount pendingUnitCount: Int64) {
145-
if #available(macOS 10.11, iOS 9.0, watchOS 2.0, tvOS 9.0, *) {
146-
addChild(child, withPendingUnitCount: pendingUnitCount)
147-
} else {
148-
monitorChild(child, withPendingUnitCount: pendingUnitCount)
149-
}
150-
}
151-
152138
/// Adds an external progress tree as a child of this progress tree.
153139
///
154140
/// This method has a similar effect to
@@ -157,15 +143,9 @@ extension Progress {
157143
///
158144
/// This method may be useful if `child` cannot be known to already have no
159145
/// parent.
160-
func monitorChild(_ child: Progress, withPendingUnitCount pendingUnitCount: Int64) {
161-
if #available(macOS 10.11, iOS 9.0, watchOS 2.0, tvOS 9.0, *) {
162-
let child = ProxyProgress(parent: nil, referencing: child)
163-
addChild(child, withPendingUnitCount: pendingUnitCount)
164-
} else {
165-
becomeCurrent(withPendingUnitCount: pendingUnitCount)
166-
_ = ProxyProgress(parent: self, referencing: child)
167-
resignCurrent()
168-
}
146+
func addProxiedChild(_ child: Progress, withPendingUnitCount pendingUnitCount: Int64) {
147+
let child = ProxyProgress(parent: nil, referencing: child)
148+
addChild(child, withPendingUnitCount: pendingUnitCount)
169149
}
170150
}
171151
#endif

Sources/Task/Progress+Future.swift

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ extension Progress {
2727

2828
/// Returns a progress that is indeterminate until `wrapped` is fulfilled,
2929
/// then finishes at 100%.
30-
static func basicProgress<Wrapped: FutureProtocol>(parent: Progress?, for wrapped: Wrapped, uponCancel cancellation: (() -> Void)? = nil) -> Progress {
31-
let child = Progress(parent: parent, userInfo: [
30+
static func basicProgress<Wrapped: FutureProtocol>(for wrapped: Wrapped, uponCancel cancellation: (() -> Void)?) -> Progress {
31+
let child = Progress(parent: nil, userInfo: [
3232
Progress.didTaskGenerateKey: true
3333
])
3434

@@ -50,7 +50,7 @@ extension Progress {
5050
return child
5151
}
5252

53-
/// `true` for wrappers created by `Progress.basicProgress(parent:for:uponCancel:)`.
53+
/// `true` for wrappers created by `Progress.basicProgress(for:uponCancel:)`.
5454
var wasGeneratedByTask: Bool {
5555
return userInfo[Progress.didTaskGenerateKey] as? Bool == true
5656
}
@@ -60,14 +60,8 @@ extension Progress {
6060
/// `pendingUnitCount` of `self` is assigned upon fulfillment. Otherwise,
6161
/// the `pendingUnitCount` becomes complete immediately.
6262
func monitorCompletion<Wrapped: FutureProtocol>(of wrapped: Wrapped, uponCancel cancellation: (() -> Void)? = nil, withPendingUnitCount pendingUnitCount: Int64) {
63-
if #available(macOS 10.11, iOS 9.0, watchOS 2.0, tvOS 9.0, *) {
64-
let child = Progress.basicProgress(parent: nil, for: wrapped, uponCancel: cancellation)
65-
addChild(child, withPendingUnitCount: pendingUnitCount)
66-
} else {
67-
becomeCurrent(withPendingUnitCount: pendingUnitCount)
68-
_ = Progress.basicProgress(parent: self, for: wrapped, uponCancel: cancellation)
69-
resignCurrent()
70-
}
63+
let child = Progress.basicProgress(for: wrapped, uponCancel: cancellation)
64+
addChild(child, withPendingUnitCount: pendingUnitCount)
7165
}
7266
}
7367
#endif

Sources/Task/TaskChain.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ struct TaskChain {
6161
}
6262
}
6363

64-
@available(macOS 10.11, iOS 9.0, watchOS 2.0, tvOS 9.0, *)
6564
override func addChild(_ child: Progress, withPendingUnitCount unitCount: Int64) {
6665
if expandsAddedChildren, !child.wasGeneratedByTask {
6766
totalUnitCount += TaskChain.explicitChildUnitCount - unitCount
@@ -87,7 +86,7 @@ struct TaskChain {
8786
if let root = Root.activeStack.last {
8887
// We're inside `andThen` — `commitAndThen(with:)` will compose instead.
8988
self.root = root
90-
self.effectiveProgress = customProgress ?? .basicProgress(parent: nil, for: wrapped, uponCancel: cancellation)
89+
self.effectiveProgress = customProgress ?? .basicProgress(for: wrapped, uponCancel: cancellation)
9190
} else if let root = customProgress as? Root {
9291
// Being passed the `progress` of another `Task`. Just pass it through.
9392
self.root = root
@@ -101,7 +100,7 @@ struct TaskChain {
101100
self.effectiveProgress = root
102101

103102
if let customProgress = customProgress, cancellation == nil {
104-
root.adoptChild(customProgress, withPendingUnitCount: unitCount)
103+
root.addChild(customProgress, withPendingUnitCount: unitCount)
105104
} else {
106105
root.monitorCompletion(of: wrapped, uponCancel: cancellation, withPendingUnitCount: unitCount)
107106
}
@@ -137,8 +136,7 @@ struct TaskChain {
137136

138137
/// The handler passed to `map` can use implicit progress reporting.
139138
/// During the handler, the first `Progress` object created using
140-
/// `parent: .current()` will be given a larger slice of the task chain on
141-
/// macOS 10.11, iOS 9, and above.
139+
/// `parent: .current()` will be given a larger slice of the task chain.
142140
func beginMap() {
143141
root.expandsAddedChildren = true
144142
root.becomeCurrent(withPendingUnitCount: TaskChain.singleUnit)
@@ -172,7 +170,7 @@ struct TaskChain {
172170
let pendingUnitCount = wrappedProgress?.wasGeneratedByTask == false ? TaskChain.explicitChildUnitCount : TaskChain.singleUnit
173171
root.totalUnitCount += pendingUnitCount - TaskChain.undeterminedUnit
174172
if let wrappedProgress = wrappedProgress {
175-
root.monitorChild(wrappedProgress, withPendingUnitCount: pendingUnitCount)
173+
root.addProxiedChild(wrappedProgress, withPendingUnitCount: pendingUnitCount)
176174
} else {
177175
root.monitorCompletion(of: wrapped, uponCancel: wrapped.cancel, withPendingUnitCount: pendingUnitCount)
178176
}

Sources/Task/TaskCollections.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ private struct AllFilled<Success>: TaskProtocol {
3636
for future in array {
3737
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
3838
if let task = future as? Task<Base.Element.Success> {
39-
progress.monitorChild(task.progress, withPendingUnitCount: 1)
39+
progress.addProxiedChild(task.progress, withPendingUnitCount: 1)
4040
} else {
4141
progress.monitorCompletion(of: future, withPendingUnitCount: 1)
4242
}

0 commit comments

Comments
 (0)