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 10.10, iOS 8.0, *)
63 public static let userInitiated = DispatchQoS(qosClass: .userInitiated, relativePriority: 0)
65 @available(OSX 10.10, iOS 8.0, *)
66 public static let userInteractive = DispatchQoS(qosClass: .userInteractive, relativePriority: 0)
68 public static let unspecified = DispatchQoS(qosClass: .unspecified, relativePriority: 0)
70 public enum QoSClass {
71 @available(OSX 10.10, iOS 8.0, *)
74 @available(OSX 10.10, iOS 8.0, *)
77 @available(OSX 10.10, iOS 8.0, *)
80 @available(OSX 10.10, iOS 8.0, *)
83 @available(OSX 10.10, iOS 8.0, *)
88 // _OSQoSClass is internal on Linux, so this initialiser has to
89 // remain as an internal init.
90 @available(OSX 10.10, iOS 8.0, *)
91 internal init?(rawValue: _OSQoSClass) {
93 case .QOS_CLASS_BACKGROUND: self = .background
94 case .QOS_CLASS_UTILITY: self = .utility
95 case .QOS_CLASS_DEFAULT: self = .default
96 case .QOS_CLASS_USER_INITIATED: self = .userInitiated
97 case .QOS_CLASS_USER_INTERACTIVE: self = .userInteractive
98 case .QOS_CLASS_UNSPECIFIED: self = .unspecified
103 @available(OSX 10.10, iOS 8.0, *)
104 internal var rawValue: _OSQoSClass {
106 case .background: return .QOS_CLASS_BACKGROUND
107 case .utility: return .QOS_CLASS_UTILITY
108 case .default: return .QOS_CLASS_DEFAULT
109 case .userInitiated: return .QOS_CLASS_USER_INITIATED
110 case .userInteractive: return .QOS_CLASS_USER_INTERACTIVE
111 case .unspecified: return .QOS_CLASS_UNSPECIFIED
116 public init(qosClass: QoSClass, relativePriority: Int) {
117 self.qosClass = qosClass
118 self.relativePriority = relativePriority
122 public func ==(a: DispatchQoS, b: DispatchQoS) -> Bool {
123 return a.qosClass == b.qosClass && a.relativePriority == b.relativePriority
128 public enum DispatchTimeoutResult {
129 static let KERN_OPERATION_TIMED_OUT:Int = 49
136 public extension DispatchGroup {
137 public func notify(qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], queue: DispatchQueue, execute work: @escaping @convention(block) () -> ()) {
138 if #available(OSX 10.10, iOS 8.0, *), qos != .unspecified || !flags.isEmpty {
139 let item = DispatchWorkItem(qos: qos, flags: flags, block: work)
140 dispatch_group_notify(self.__wrapped, queue.__wrapped, item._block)
142 dispatch_group_notify(self.__wrapped, queue.__wrapped, work)
146 @available(OSX 10.10, iOS 8.0, *)
147 public func notify(queue: DispatchQueue, work: DispatchWorkItem) {
148 dispatch_group_notify(self.__wrapped, queue.__wrapped, work._block)
152 _ = dispatch_group_wait(self.__wrapped, DispatchTime.distantFuture.rawValue)
155 public func wait(timeout: DispatchTime) -> DispatchTimeoutResult {
156 return dispatch_group_wait(self.__wrapped, timeout.rawValue) == 0 ? .success : .timedOut
159 public func wait(wallTimeout timeout: DispatchWallTime) -> DispatchTimeoutResult {
160 return dispatch_group_wait(self.__wrapped, timeout.rawValue) == 0 ? .success : .timedOut
164 /// dispatch_semaphore
166 public extension DispatchSemaphore {
168 public func signal() -> Int {
169 return dispatch_semaphore_signal(self.__wrapped)
173 _ = dispatch_semaphore_wait(self.__wrapped, DispatchTime.distantFuture.rawValue)
176 public func wait(timeout: DispatchTime) -> DispatchTimeoutResult {
177 return dispatch_semaphore_wait(self.__wrapped, timeout.rawValue) == 0 ? .success : .timedOut
180 public func wait(wallTimeout: DispatchWallTime) -> DispatchTimeoutResult {
181 return dispatch_semaphore_wait(self.__wrapped, wallTimeout.rawValue) == 0 ? .success : .timedOut