-
Notifications
You must be signed in to change notification settings - Fork 10.4k
/
Copy pathDispatch.swift
180 lines (143 loc) · 5.45 KB
/
Dispatch.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
@_exported import Dispatch
import _SwiftDispatchOverlayShims
/// dispatch_assert
@available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)
public enum DispatchPredicate {
case onQueue(DispatchQueue)
case onQueueAsBarrier(DispatchQueue)
case notOnQueue(DispatchQueue)
}
@available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)
public func _dispatchPreconditionTest(_ condition: DispatchPredicate) -> Bool {
switch condition {
case .onQueue(let q):
__dispatch_assert_queue(q)
case .onQueueAsBarrier(let q):
__dispatch_assert_queue_barrier(q)
case .notOnQueue(let q):
__dispatch_assert_queue_not(q)
}
return true
}
@_transparent
@available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)
public func dispatchPrecondition(condition: @autoclosure () -> DispatchPredicate) {
// precondition is able to determine release-vs-debug asserts where the overlay
// cannot, so formulating this into a call that we can call with precondition()
precondition(_dispatchPreconditionTest(condition()), "dispatchPrecondition failure")
}
/// qos_class_t
public struct DispatchQoS : Equatable {
public let qosClass: QoSClass
public let relativePriority: Int
@available(OSX 10.10, iOS 8.0, *)
public static let background = DispatchQoS(qosClass: .background, relativePriority: 0)
@available(OSX 10.10, iOS 8.0, *)
public static let utility = DispatchQoS(qosClass: .utility, relativePriority: 0)
@available(OSX 10.10, iOS 8.0, *)
public static let `default` = DispatchQoS(qosClass: .default, relativePriority: 0)
@available(OSX 10.10, iOS 8.0, *)
public static let userInitiated = DispatchQoS(qosClass: .userInitiated, relativePriority: 0)
@available(OSX 10.10, iOS 8.0, *)
public static let userInteractive = DispatchQoS(qosClass: .userInteractive, relativePriority: 0)
public static let unspecified = DispatchQoS(qosClass: .unspecified, relativePriority: 0)
public enum QoSClass {
@available(OSX 10.10, iOS 8.0, *)
case background
@available(OSX 10.10, iOS 8.0, *)
case utility
@available(OSX 10.10, iOS 8.0, *)
case `default`
@available(OSX 10.10, iOS 8.0, *)
case userInitiated
@available(OSX 10.10, iOS 8.0, *)
case userInteractive
case unspecified
@available(OSX 10.10, iOS 8.0, *)
public init?(rawValue: qos_class_t) {
switch rawValue {
case QOS_CLASS_BACKGROUND: self = .background
case QOS_CLASS_UTILITY: self = .utility
case QOS_CLASS_DEFAULT: self = .default
case QOS_CLASS_USER_INITIATED: self = .userInitiated
case QOS_CLASS_USER_INTERACTIVE: self = .userInteractive
case QOS_CLASS_UNSPECIFIED: self = .unspecified
default: return nil
}
}
@available(OSX 10.10, iOS 8.0, *)
public var rawValue: qos_class_t {
switch self {
case .background: return QOS_CLASS_BACKGROUND
case .utility: return QOS_CLASS_UTILITY
case .default: return QOS_CLASS_DEFAULT
case .userInitiated: return QOS_CLASS_USER_INITIATED
case .userInteractive: return QOS_CLASS_USER_INTERACTIVE
case .unspecified: return QOS_CLASS_UNSPECIFIED
}
}
}
public init(qosClass: QoSClass, relativePriority: Int) {
self.qosClass = qosClass
self.relativePriority = relativePriority
}
}
public func ==(a: DispatchQoS, b: DispatchQoS) -> Bool {
return a.qosClass == b.qosClass && a.relativePriority == b.relativePriority
}
///
public enum DispatchTimeoutResult {
case success
case timedOut
}
/// dispatch_group
public extension DispatchGroup {
public func notify(qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], queue: DispatchQueue, execute work: @escaping @convention(block) () -> Void) {
if #available(OSX 10.10, iOS 8.0, *), qos != .unspecified || !flags.isEmpty {
let item = DispatchWorkItem(qos: qos, flags: flags, block: work)
_swift_dispatch_group_notify(self, queue, item._block)
} else {
_swift_dispatch_group_notify(self, queue, work)
}
}
@available(OSX 10.10, iOS 8.0, *)
public func notify(queue: DispatchQueue, work: DispatchWorkItem) {
_swift_dispatch_group_notify(self, queue, work._block)
}
public func wait() {
_ = __dispatch_group_wait(self, DispatchTime.distantFuture.rawValue)
}
public func wait(timeout: DispatchTime) -> DispatchTimeoutResult {
return __dispatch_group_wait(self, timeout.rawValue) == 0 ? .success : .timedOut
}
public func wait(wallTimeout timeout: DispatchWallTime) -> DispatchTimeoutResult {
return __dispatch_group_wait(self, timeout.rawValue) == 0 ? .success : .timedOut
}
}
/// dispatch_semaphore
public extension DispatchSemaphore {
@discardableResult
public func signal() -> Int {
return __dispatch_semaphore_signal(self)
}
public func wait() {
_ = __dispatch_semaphore_wait(self, DispatchTime.distantFuture.rawValue)
}
public func wait(timeout: DispatchTime) -> DispatchTimeoutResult {
return __dispatch_semaphore_wait(self, timeout.rawValue) == 0 ? .success : .timedOut
}
public func wait(wallTimeout: DispatchWallTime) -> DispatchTimeoutResult {
return __dispatch_semaphore_wait(self, wallTimeout.rawValue) == 0 ? .success : .timedOut
}
}