//===----------------------------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// @_exported import Dispatch import SwiftShims /// 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) () -> ()) { 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 } }