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: CallbacksList { 0017 let block
Deferred.swift:44 private let onFilled = DispatchBlockMarker()= dispatch_block_create(DISPATCH_BLOCK_NO_QOS_CLASS, { 0018 fatalError("This code should never be executed") 0019 })! 0020 0021 var isCompleted
Deferred.swift:22 return dispatch_block_testcancel(block) != 0Deferred.swift:27 dispatch_block_cancel(block)Deferred.swift:29 block()Deferred.swift:33 dispatch_block_notify(block, queue, body): Bool { 0022 return dispatch_block_testcancel(block) != 0 0023 } 0024 0025 func markCompleted
Deferred.swift:71 return onFilled.isCompleted() { 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:54 onFilled.markCompleted()Deferred.swift:131 onFilled.markCompleted()(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
Deferred.swift:65 onFilled.notify(upon: queue, body: block)<Value
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>()>: FutureType, PromiseType { 0042 0043 private let storage
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 {: MemoStore<Value> 0044 private let onFilled
Deferred.swift:48 storage = MemoStore.createWithValue(nil)Deferred.swift:53 storage = MemoStore.createWithValue(value)Deferred.swift:62 let block = dispatch_block_create(options) { [storage] inDeferred.swift:105 storage.withValue(assign)Deferred.swift:129 let wasFilled = storage.fill(value)= 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:54 onFilled.markCompleted()Deferred.swift:65 onFilled.notify(upon: queue, body: block)Deferred.swift:71 return onFilled.isCompletedDeferred.swift:131 onFilled.markCompleted()(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: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): 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
Deferred.swift:104 if isFilled {(value: Value) -> Bool { 0129 let wasFilled = storage.fill(value) 0130 if wasFilled { 0131 onFilled.markCompleted() 0132 } 0133 return wasFilled 0134 } 0135 } 0136
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))