0001 // 0002 // AsyncLock.swift 0003 // Rx 0004 // 0005 // Created by Krunoslav Zaher on 3/21/15. 0006 // Copyright © 2015 Krunoslav Zaher. All rights reserved. 0007 // 0008 0009 import Foundation 0010 0011 /** 0012 In case nobody holds this lock, the work will be queued and executed immediately 0013 on thread that is requesting lock. 0014 0015 In case there is somebody currently holding that lock, action will be enqueued. 0016 When owned of the lock finishes with it's processing, it will also execute 0017 and pending work. 0018 0019 That means that enqueued work could possibly be executed later on a different thread. 0020 */ 0021 class AsyncLock<I
ImmediateScheduler.swift:16 private let _asyncLock = AsyncLock<AnonymousInvocable>()TailRecursiveSink.swift:33 var _gate = AsyncLock<InvocableScheduledItem<TailRecursiveSink<S, O>>>(): InvocableType> 0022 : Disposable 0023 , Lock 0024 , SynchronizedDisposeType { 0025 typealias Action = () -> Void 0026 0027 var _lock
AsyncLock.swift:29 private var _queue: Queue<I> = Queue(capacity: 0)AsyncLock.swift:44 private func enqueue(action: I) -> I? {AsyncLock.swift:44 private func enqueue(action: I) -> I? {AsyncLock.swift:61 private func dequeue() -> I? {AsyncLock.swift:73 func invoke(action: I) {= SpinLock() 0028 0029 private var _queue
AsyncLock.swift:36 _lock.lock()AsyncLock.swift:40 _lock.unlock()AsyncLock.swift:45 _lock.lock(); defer { _lock.unlock() } // {AsyncLock.swift:45 _lock.lock(); defer { _lock.unlock() } // {AsyncLock.swift:62 _lock.lock(); defer { _lock.unlock() } // {AsyncLock.swift:62 _lock.lock(); defer { _lock.unlock() } // {: Queue<I> = Queue(capacity: 0) 0030 0031 private var _isExecuting
AsyncLock.swift:51 _queue.enqueue(action)AsyncLock.swift:63 if _queue.count > 0 {AsyncLock.swift:64 return _queue.dequeue()AsyncLock.swift:101 _queue = Queue(capacity: 0): Bool = false 0032 private var _hasFaulted
AsyncLock.swift:50 if _isExecuting {AsyncLock.swift:55 _isExecuting = trueAsyncLock.swift:67 _isExecuting = false: Bool = false 0033 0034 // lock { 0035 func lock() { 0036 _lock.lock() 0037 } 0038 0039 func unlock() { 0040 _lock.unlock() 0041 } 0042 // } 0043 0044 private func enqueue
AsyncLock.swift:46 if _hasFaulted {AsyncLock.swift:102 _hasFaulted = true(action: I) -> I? { 0045 _lock.lock(); defer { _lock.unlock() } // { 0046 if _hasFaulted { 0047 return nil 0048 } 0049 0050 if _isExecuting { 0051 _queue.enqueue(action) 0052 return nil 0053 } 0054 0055 _isExecuting = true 0056 0057 return action 0058 // } 0059 } 0060 0061 private func dequeue
AsyncLock.swift:74 let firstEnqueuedAction = enqueue(action)() -> I? { 0062 _lock.lock(); defer { _lock.unlock() } // { 0063 if _queue.count > 0 { 0064 return _queue.dequeue() 0065 } 0066 else { 0067 _isExecuting = false 0068 return nil 0069 } 0070 // } 0071 } 0072 0073 func invoke
AsyncLock.swift:85 let nextAction = dequeue()(action: I) { 0074 let firstEnqueuedAction = enqueue(action) 0075 0076 if let firstEnqueuedAction = firstEnqueuedAction { 0077 firstEnqueuedAction.invoke() 0078 } 0079 else { 0080 // action is enqueued, it's somebody else's concern now 0081 return 0082 } 0083 0084 while true { 0085 let nextAction = dequeue() 0086 0087 if let nextAction = nextAction { 0088 nextAction.invoke() 0089 } 0090 else { 0091 return 0092 } 0093 } 0094 } 0095 0096 func dispose() { 0097 synchronizedDispose() 0098 } 0099 0100 func _synchronized_dispose() { 0101 _queue = Queue(capacity: 0) 0102 _hasFaulted = true 0103 } 0104 } 0105
ImmediateScheduler.swift:30 _asyncLock.invoke(AnonymousInvocable {TailRecursiveSink.swift:58 _gate.invoke(InvocableScheduledItem(invocable: self, state: command))