]> git.saurik.com Git - apple/libdispatch.git/blob - src/swift/Dispatch.swift
libdispatch-703.1.4.tar.gz
[apple/libdispatch.git] / src / swift / Dispatch.swift
1 //===----------------------------------------------------------------------===//
2 //
3 // This source file is part of the Swift.org open source project
4 //
5 // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6 // Licensed under Apache License v2.0 with Runtime Library Exception
7 //
8 // See http://swift.org/LICENSE.txt for license information
9 // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10 //
11 //===----------------------------------------------------------------------===//
12
13 @_exported import Dispatch
14
15 import CDispatch
16
17 /// dispatch_assert
18
19 @available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)
20 public enum DispatchPredicate {
21 case onQueue(DispatchQueue)
22 case onQueueAsBarrier(DispatchQueue)
23 case notOnQueue(DispatchQueue)
24 }
25
26 @available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)
27 public func _dispatchPreconditionTest(_ condition: DispatchPredicate) -> Bool {
28 switch condition {
29 case .onQueue(let q):
30 dispatch_assert_queue(q.__wrapped)
31 case .onQueueAsBarrier(let q):
32 dispatch_assert_queue_barrier(q.__wrapped)
33 case .notOnQueue(let q):
34 dispatch_assert_queue_not(q.__wrapped)
35 }
36 return true
37 }
38
39 @_transparent
40 @available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)
41 public func dispatchPrecondition(condition: @autoclosure () -> DispatchPredicate) {
42 // precondition is able to determine release-vs-debug asserts where the overlay
43 // cannot, so formulating this into a call that we can call with precondition()
44 precondition(_dispatchPreconditionTest(condition()), "dispatchPrecondition failure")
45 }
46
47 /// qos_class_t
48
49 public struct DispatchQoS : Equatable {
50 public let qosClass: QoSClass
51 public let relativePriority: Int
52
53 @available(OSX 10.10, iOS 8.0, *)
54 public static let background = DispatchQoS(qosClass: .background, relativePriority: 0)
55
56 @available(OSX 10.10, iOS 8.0, *)
57 public static let utility = DispatchQoS(qosClass: .utility, relativePriority: 0)
58
59 @available(OSX 10.10, iOS 8.0, *)
60 public static let `default` = DispatchQoS(qosClass: .default, relativePriority: 0)
61
62 @available(OSX, introduced: 10.10, deprecated: 10.10, renamed: "DispatchQoS.default")
63 @available(iOS, introduced: 8.0, deprecated: 8.0, renamed: "DispatchQoS.default")
64 @available(*, deprecated, renamed: "DispatchQoS.default")
65 public static let defaultQoS = DispatchQoS.default
66
67 @available(OSX 10.10, iOS 8.0, *)
68 public static let userInitiated = DispatchQoS(qosClass: .userInitiated, relativePriority: 0)
69
70 @available(OSX 10.10, iOS 8.0, *)
71 public static let userInteractive = DispatchQoS(qosClass: .userInteractive, relativePriority: 0)
72
73 public static let unspecified = DispatchQoS(qosClass: .unspecified, relativePriority: 0)
74
75 public enum QoSClass {
76 @available(OSX 10.10, iOS 8.0, *)
77 case background
78
79 @available(OSX 10.10, iOS 8.0, *)
80 case utility
81
82 @available(OSX 10.10, iOS 8.0, *)
83 case `default`
84
85 @available(OSX, introduced: 10.10, deprecated: 10.10, renamed: "QoSClass.default")
86 @available(iOS, introduced: 8.0, deprecated: 8.0, renamed: "QoSClass.default")
87 @available(*, deprecated, renamed: "QoSClass.default")
88 static let defaultQoS = QoSClass.default
89
90 @available(OSX 10.10, iOS 8.0, *)
91 case userInitiated
92
93 @available(OSX 10.10, iOS 8.0, *)
94 case userInteractive
95
96 case unspecified
97
98 @available(OSX 10.10, iOS 8.0, *)
99 internal init?(qosClass: _OSQoSClass) {
100 switch qosClass {
101 case .QOS_CLASS_BACKGROUND: self = .background
102 case .QOS_CLASS_UTILITY: self = .utility
103 case .QOS_CLASS_DEFAULT: self = .default
104 case .QOS_CLASS_USER_INITIATED: self = .userInitiated
105 case .QOS_CLASS_USER_INTERACTIVE: self = .userInteractive
106 case .QOS_CLASS_UNSPECIFIED: self = .unspecified
107 default: return nil
108 }
109 }
110
111 @available(OSX 10.10, iOS 8.0, *)
112 internal var rawValue: _OSQoSClass {
113 switch self {
114 case .background: return .QOS_CLASS_BACKGROUND
115 case .utility: return .QOS_CLASS_UTILITY
116 case .default: return .QOS_CLASS_DEFAULT
117 case .userInitiated: return .QOS_CLASS_USER_INITIATED
118 case .userInteractive: return .QOS_CLASS_USER_INTERACTIVE
119 case .unspecified: return .QOS_CLASS_UNSPECIFIED
120 }
121 }
122 }
123
124 public init(qosClass: QoSClass, relativePriority: Int) {
125 self.qosClass = qosClass
126 self.relativePriority = relativePriority
127 }
128 }
129
130 public func ==(a: DispatchQoS, b: DispatchQoS) -> Bool {
131 return a.qosClass == b.qosClass && a.relativePriority == b.relativePriority
132 }
133
134 ///
135
136 public enum DispatchTimeoutResult {
137 static let KERN_OPERATION_TIMED_OUT:Int = 49
138 case Success
139 case TimedOut
140 }
141
142 /// dispatch_group
143
144 public extension DispatchGroup {
145 public func notify(qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], queue: DispatchQueue, execute work: @convention(block) () -> ()) {
146 if #available(OSX 10.10, iOS 8.0, *), qos != .unspecified || !flags.isEmpty {
147 let item = DispatchWorkItem(qos: qos, flags: flags, block: work)
148 dispatch_group_notify(self.__wrapped, queue.__wrapped, item._block)
149 } else {
150 dispatch_group_notify(self.__wrapped, queue.__wrapped, work)
151 }
152 }
153
154 @available(OSX 10.10, iOS 8.0, *)
155 public func notify(queue: DispatchQueue, work: DispatchWorkItem) {
156 dispatch_group_notify(self.__wrapped, queue.__wrapped, work._block)
157 }
158
159 public func wait() {
160 _ = dispatch_group_wait(self.__wrapped, DispatchTime.distantFuture.rawValue)
161 }
162
163 public func wait(timeout: DispatchTime) -> DispatchTimeoutResult {
164 return dispatch_group_wait(self.__wrapped, timeout.rawValue) == 0 ? .Success : .TimedOut
165 }
166
167 public func wait(wallTimeout timeout: DispatchWallTime) -> DispatchTimeoutResult {
168 return dispatch_group_wait(self.__wrapped, timeout.rawValue) == 0 ? .Success : .TimedOut
169 }
170 }
171
172 public extension DispatchGroup {
173 @available(*, deprecated, renamed: "DispatchGroup.wait(self:wallTimeout:)")
174 public func wait(walltime timeout: DispatchWallTime) -> Int {
175 switch wait(wallTimeout: timeout) {
176 case .Success: return 0
177 case .TimedOut: return DispatchTimeoutResult.KERN_OPERATION_TIMED_OUT
178 }
179 }
180 }
181
182 /// dispatch_semaphore
183
184 public extension DispatchSemaphore {
185 @discardableResult
186 public func signal() -> Int {
187 return dispatch_semaphore_signal(self.__wrapped)
188 }
189
190 public func wait() {
191 _ = dispatch_semaphore_wait(self.__wrapped, DispatchTime.distantFuture.rawValue)
192 }
193
194 public func wait(timeout: DispatchTime) -> DispatchTimeoutResult {
195 return dispatch_semaphore_wait(self.__wrapped, timeout.rawValue) == 0 ? .Success : .TimedOut
196 }
197
198 public func wait(wallTimeout: DispatchWallTime) -> DispatchTimeoutResult {
199 return dispatch_semaphore_wait(self.__wrapped, wallTimeout.rawValue) == 0 ? .Success : .TimedOut
200 }
201 }
202
203 public extension DispatchSemaphore {
204 @available(*, deprecated, renamed: "DispatchSemaphore.wait(self:wallTimeout:)")
205 public func wait(walltime timeout: DispatchWalltime) -> Int {
206 switch wait(wallTimeout: timeout) {
207 case .Success: return 0
208 case .TimedOut: return DispatchTimeoutResult.KERN_OPERATION_TIMED_OUT
209 }
210 }
211 }