1 //===----------------------------------------------------------------------===//
3 // This source file is part of the Swift.org open source project
5 // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6 // Licensed under Apache License v2.0 with Runtime Library Exception
8 // See http://swift.org/LICENSE.txt for license information
9 // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
11 //===----------------------------------------------------------------------===//
13 @_exported import Dispatch
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)
26 @available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)
27 public func _dispatchPreconditionTest(_ condition: DispatchPredicate) -> Bool {
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)
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")
49 public struct DispatchQoS : Equatable {
50 public let qosClass: QoSClass
51 public let relativePriority: Int
53 @available(OSX 10.10, iOS 8.0, *)
54 public static let background = DispatchQoS(qosClass: .background, relativePriority: 0)
56 @available(OSX 10.10, iOS 8.0, *)
57 public static let utility = DispatchQoS(qosClass: .utility, relativePriority: 0)
59 @available(OSX 10.10, iOS 8.0, *)
60 public static let `default` = DispatchQoS(qosClass: .default, relativePriority: 0)
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
67 @available(OSX 10.10, iOS 8.0, *)
68 public static let userInitiated = DispatchQoS(qosClass: .userInitiated, relativePriority: 0)
70 @available(OSX 10.10, iOS 8.0, *)
71 public static let userInteractive = DispatchQoS(qosClass: .userInteractive, relativePriority: 0)
73 public static let unspecified = DispatchQoS(qosClass: .unspecified, relativePriority: 0)
75 public enum QoSClass {
76 @available(OSX 10.10, iOS 8.0, *)
79 @available(OSX 10.10, iOS 8.0, *)
82 @available(OSX 10.10, iOS 8.0, *)
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
90 @available(OSX 10.10, iOS 8.0, *)
93 @available(OSX 10.10, iOS 8.0, *)
98 @available(OSX 10.10, iOS 8.0, *)
99 internal init?(qosClass: _OSQoSClass) {
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
111 @available(OSX 10.10, iOS 8.0, *)
112 internal var rawValue: _OSQoSClass {
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
124 public init(qosClass: QoSClass, relativePriority: Int) {
125 self.qosClass = qosClass
126 self.relativePriority = relativePriority
130 public func ==(a: DispatchQoS, b: DispatchQoS) -> Bool {
131 return a.qosClass == b.qosClass && a.relativePriority == b.relativePriority
136 public enum DispatchTimeoutResult {
137 static let KERN_OPERATION_TIMED_OUT:Int = 49
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)
150 dispatch_group_notify(self.__wrapped, queue.__wrapped, work)
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)
160 _ = dispatch_group_wait(self.__wrapped, DispatchTime.distantFuture.rawValue)
163 public func wait(timeout: DispatchTime) -> DispatchTimeoutResult {
164 return dispatch_group_wait(self.__wrapped, timeout.rawValue) == 0 ? .Success : .TimedOut
167 public func wait(wallTimeout timeout: DispatchWallTime) -> DispatchTimeoutResult {
168 return dispatch_group_wait(self.__wrapped, timeout.rawValue) == 0 ? .Success : .TimedOut
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
182 /// dispatch_semaphore
184 public extension DispatchSemaphore {
186 public func signal() -> Int {
187 return dispatch_semaphore_signal(self.__wrapped)
191 _ = dispatch_semaphore_wait(self.__wrapped, DispatchTime.distantFuture.rawValue)
194 public func wait(timeout: DispatchTime) -> DispatchTimeoutResult {
195 return dispatch_semaphore_wait(self.__wrapped, timeout.rawValue) == 0 ? .Success : .TimedOut
198 public func wait(wallTimeout: DispatchWallTime) -> DispatchTimeoutResult {
199 return dispatch_semaphore_wait(self.__wrapped, wallTimeout.rawValue) == 0 ? .Success : .TimedOut
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