]> git.saurik.com Git - apple/libdispatch.git/blob - src/swift/Dispatch.swift
libdispatch-703.50.37.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 10.10, iOS 8.0, *)
63 public static let userInitiated = DispatchQoS(qosClass: .userInitiated, relativePriority: 0)
64
65 @available(OSX 10.10, iOS 8.0, *)
66 public static let userInteractive = DispatchQoS(qosClass: .userInteractive, relativePriority: 0)
67
68 public static let unspecified = DispatchQoS(qosClass: .unspecified, relativePriority: 0)
69
70 public enum QoSClass {
71 @available(OSX 10.10, iOS 8.0, *)
72 case background
73
74 @available(OSX 10.10, iOS 8.0, *)
75 case utility
76
77 @available(OSX 10.10, iOS 8.0, *)
78 case `default`
79
80 @available(OSX 10.10, iOS 8.0, *)
81 case userInitiated
82
83 @available(OSX 10.10, iOS 8.0, *)
84 case userInteractive
85
86 case unspecified
87
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) {
92 switch rawValue {
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
99 default: return nil
100 }
101 }
102
103 @available(OSX 10.10, iOS 8.0, *)
104 internal var rawValue: _OSQoSClass {
105 switch self {
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
112 }
113 }
114 }
115
116 public init(qosClass: QoSClass, relativePriority: Int) {
117 self.qosClass = qosClass
118 self.relativePriority = relativePriority
119 }
120 }
121
122 public func ==(a: DispatchQoS, b: DispatchQoS) -> Bool {
123 return a.qosClass == b.qosClass && a.relativePriority == b.relativePriority
124 }
125
126 ///
127
128 public enum DispatchTimeoutResult {
129 static let KERN_OPERATION_TIMED_OUT:Int = 49
130 case success
131 case timedOut
132 }
133
134 /// dispatch_group
135
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)
141 } else {
142 dispatch_group_notify(self.__wrapped, queue.__wrapped, work)
143 }
144 }
145
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)
149 }
150
151 public func wait() {
152 _ = dispatch_group_wait(self.__wrapped, DispatchTime.distantFuture.rawValue)
153 }
154
155 public func wait(timeout: DispatchTime) -> DispatchTimeoutResult {
156 return dispatch_group_wait(self.__wrapped, timeout.rawValue) == 0 ? .success : .timedOut
157 }
158
159 public func wait(wallTimeout timeout: DispatchWallTime) -> DispatchTimeoutResult {
160 return dispatch_group_wait(self.__wrapped, timeout.rawValue) == 0 ? .success : .timedOut
161 }
162 }
163
164 /// dispatch_semaphore
165
166 public extension DispatchSemaphore {
167 @discardableResult
168 public func signal() -> Int {
169 return dispatch_semaphore_signal(self.__wrapped)
170 }
171
172 public func wait() {
173 _ = dispatch_semaphore_wait(self.__wrapped, DispatchTime.distantFuture.rawValue)
174 }
175
176 public func wait(timeout: DispatchTime) -> DispatchTimeoutResult {
177 return dispatch_semaphore_wait(self.__wrapped, timeout.rawValue) == 0 ? .success : .timedOut
178 }
179
180 public func wait(wallTimeout: DispatchWallTime) -> DispatchTimeoutResult {
181 return dispatch_semaphore_wait(self.__wrapped, wallTimeout.rawValue) == 0 ? .success : .timedOut
182 }
183 }