0001    //
0002    //  Deferred.swift
0003    //  Deferred
0004    //
0005    //  Created by John Gallagher on 7/19/14.
0006    //  Copyright © 2014-2015 Big Nerd Ranch. Licensed under MIT.
0007    //
0008    
0009    import Dispatch
0010    
0011    // MARK: - DispatchBlockMarker
0012    
0013    // A dispatch block (which is different from a plain closure!) constitutes the
0014    // second half of Deferred. The `dispatch_block_notify` API defines the notifier
0015    // list used by `Deferred.upon(queue:body:)`.
0016    private struct DispatchBlockMarker
Deferred.swift:44
    private let onFilled = DispatchBlockMarker()
: CallbacksList { 0017 let block
Deferred.swift:22
        return dispatch_block_testcancel(block) != 0
Deferred.swift:27
        dispatch_block_cancel(block)
Deferred.swift:29
        block()
Deferred.swift:33
        dispatch_block_notify(block, queue, body)
= dispatch_block_create(DISPATCH_BLOCK_NO_QOS_CLASS, { 0018 fatalError("This code should never be executed") 0019 })! 0020 0021 var isCompleted
Deferred.swift:71
        return onFilled.isCompleted
: Bool { 0022 return dispatch_block_testcancel(block) != 0 0023 } 0024 0025 func markCompleted
Deferred.swift:54
        onFilled.markCompleted()
Deferred.swift:131
            onFilled.markCompleted()
() { 0026 // Cancel it so we can use `dispatch_block_testcancel` to mean "filled" 0027 dispatch_block_cancel(block) 0028 // Executing the block "unblocks" it, calling all the `_notify` blocks 0029 block() 0030 } 0031 0032 func notify
Deferred.swift:65
        onFilled.notify(upon: queue, body: block)
(upon queue: dispatch_queue_t, body: dispatch_block_t) { 0033 dispatch_block_notify(block, queue, body) 0034 } 0035 } 0036 0037 // MARK: - Deferred 0038 0039 /// A deferred is a value that may become determined (or "filled") at some point 0040 /// in the future. Once a deferred value is determined, it cannot change. 0041 public struct Deferred
FutureCollections.swift:17
        let combined = Deferred<Generator.Element.Value>()
FutureCollections.swift:38
        let combined = Deferred<[Generator.Element.Value]>()
FutureType.swift:128
        let d = Deferred<NewFuture.Value>()
FutureType.swift:148
        let d = Deferred<NewValue>()
<Value
Deferred.swift:43
    private let storage: MemoStore<Value>
Deferred.swift:52
    public init(value: Value) {
Deferred.swift:59
    private func upon(queue: dispatch_queue_t, options inOptions: dispatch_block_flags_t, body: Value -> Void) -> dispatch_block_t {
Deferred.swift:83
    public func upon(queue: dispatch_queue_t, body: Value -> ()) {
Deferred.swift:96
    public func wait(time: Timeout) -> Value? {
Deferred.swift:128
    public func fill(value: Value) -> Bool {
>: FutureType, PromiseType { 0042 0043 private let storage
Deferred.swift:48
        storage = MemoStore.createWithValue(nil)
Deferred.swift:53
        storage = MemoStore.createWithValue(value)
Deferred.swift:62
        let block = dispatch_block_create(options) { [storage] in
Deferred.swift:105
            storage.withValue(assign)
Deferred.swift:129
        let wasFilled = storage.fill(value)
: MemoStore<Value> 0044 private let onFilled
Deferred.swift:54
        onFilled.markCompleted()
Deferred.swift:65
        onFilled.notify(upon: queue, body: block)
Deferred.swift:71
        return onFilled.isCompleted
Deferred.swift:131
            onFilled.markCompleted()
= DispatchBlockMarker() 0045 0046 /// Initialize an unfilled Deferred. 0047 public init() { 0048 storage = MemoStore.createWithValue(nil) 0049 } 0050 0051 /// Initialize a filled Deferred with the given value. 0052 public init(value: Value) { 0053 storage = MemoStore.createWithValue(value) 0054 onFilled.markCompleted() 0055 } 0056 0057 // MARK: FutureType 0058 0059 private func upon
Deferred.swift:84
        _ = upon(queue, options: DISPATCH_BLOCK_INHERIT_QOS_CLASS, body: body)
Deferred.swift:110
        let handler = upon(queue, options: DISPATCH_BLOCK_ENFORCE_QOS_CLASS, body: assign)
(queue: dispatch_queue_t, options inOptions: dispatch_block_flags_t, body: Value -> Void) -> dispatch_block_t { 0060 var options = inOptions 0061 options.rawValue |= DISPATCH_BLOCK_ASSIGN_CURRENT.rawValue 0062 let block = dispatch_block_create(options) { [storage] in 0063 storage.withValue(body) 0064 } 0065 onFilled.notify(upon: queue, body: block) 0066 return block 0067 } 0068 0069 /// Check whether or not the receiver is filled. 0070 public var isFilled
Deferred.swift:104
        if isFilled {
: Bool { 0071 return onFilled.isCompleted 0072 } 0073 0074 /** 0075 Call some function once the value is determined. 0076 0077 If the value is already determined, the function will be submitted to the 0078 queue immediately. An `upon` call is always executed asynchronously. 0079 0080 :param: queue A dispatch queue for executing the given function on. 0081 :param: body A function that uses the determined value. 0082 */ 0083 public func upon(queue: dispatch_queue_t, body: Value -> ()) { 0084 _ = upon(queue, options: DISPATCH_BLOCK_INHERIT_QOS_CLASS, body: body) 0085 } 0086 0087 /** 0088 Waits synchronously for the value to become determined. 0089 0090 If the value is already determined, the call returns immediately with the 0091 value. 0092 0093 :param: time A length of time to wait for the value to be determined. 0094 :returns: The determined value, if filled within the timeout, or `nil`. 0095 */ 0096 public func wait(time: Timeout) -> Value? { 0097 var result: Value? 0098 func assign(value: Value) { 0099 result = value 0100 } 0101 0102 // FutureType can't generally do this; `isFilled` is normally 0103 // implemented in terms of wait() normally. 0104 if isFilled { 0105 storage.withValue(assign) 0106 return result 0107 } 0108 0109 let queue = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0) 0110 let handler = upon(queue, options: DISPATCH_BLOCK_ENFORCE_QOS_CLASS, body: assign) 0111 0112 guard dispatch_block_wait(handler, time.rawValue) == 0 else { 0113 dispatch_block_cancel(handler) 0114 return nil 0115 } 0116 0117 return result 0118 } 0119 0120 // MARK: PromiseType 0121 0122 /// Determines the deferred value with a given result. 0123 /// 0124 /// Filling a deferred value should usually be attempted only once. 0125 /// 0126 /// - parameter value: The resolved value for the instance. 0127 /// - returns: Whether the promise was fulfilled with `value`. 0128 public func fill
FutureCollections.swift:20
                combined.fill($0)
FutureCollections.swift:49
            combined.fill(array.map {
FutureType.swift:131
                d.fill($0)
FutureType.swift:150
            d.fill(transform($0))
(value: Value) -> Bool { 0129 let wasFilled = storage.fill(value) 0130 if wasFilled { 0131 onFilled.markCompleted() 0132 } 0133 return wasFilled 0134 } 0135 } 0136