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
ImmediateScheduler.swift:16
    private let _asyncLock = AsyncLock<AnonymousInvocable>()
TailRecursiveSink.swift:33
    var _gate = AsyncLock<InvocableScheduledItem<TailRecursiveSink<S, O>>>()
<I
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) {
: InvocableType> 0022 : Disposable 0023 , Lock 0024 , SynchronizedDisposeType { 0025 typealias Action = () -> Void 0026 0027 var _lock
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() } // {
= SpinLock() 0028 0029 private var _queue
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)
: Queue<I> = Queue(capacity: 0) 0030 0031 private var _isExecuting
AsyncLock.swift:50
            if _isExecuting {
AsyncLock.swift:55
            _isExecuting = true
AsyncLock.swift:67
                _isExecuting = false
: Bool = false 0032 private var _hasFaulted
AsyncLock.swift:46
            if _hasFaulted {
AsyncLock.swift:102
        _hasFaulted = true
: 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:74
        let firstEnqueuedAction = enqueue(action)
(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:85
            let nextAction = dequeue()
() -> 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
ImmediateScheduler.swift:30
        _asyncLock.invoke(AnonymousInvocable {
TailRecursiveSink.swift:58
        _gate.invoke(InvocableScheduledItem(invocable: self, state: command))
(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