0001    //
0002    //  MainScheduler.swift
0003    //  Rx
0004    //
0005    //  Created by Krunoslav Zaher on 2/8/15.
0006    //  Copyright © 2015 Krunoslav Zaher. All rights reserved.
0007    //
0008    
0009    import Foundation
0010    
0011    /**
0012    Abstracts work that needs to be performed on `MainThread`. In case `schedule` methods are called from main thread, it will perform action immediately without scheduling.
0013    
0014    This scheduler is usually used to perform UI work.
0015    
0016    Main scheduler is a specialization of `SerialDispatchQueueScheduler`.
0017    
0018    This scheduler is optimized for `observeOn` operator. To ensure observable sequence is subscribed on main thread using `subscribeOn`
0019    operator please use `ConcurrentMainScheduler` because it is more optimized for that purpose.
0020    */
0021    public final class MainScheduler
ConcurrentDispatchQueueScheduler.swift:96
        let dispatchInterval = MainScheduler.convertTimeIntervalToDispatchTime(dueTime)
ConcurrentDispatchQueueScheduler.swift:128
        let initial = MainScheduler.convertTimeIntervalToDispatchTime(startAfter)
ConcurrentDispatchQueueScheduler.swift:129
        let dispatchInterval = MainScheduler.convertTimeIntervalToDispatchInterval(period)
ConcurrentMainScheduler.swift:21
    private let _mainScheduler: MainScheduler
ConcurrentMainScheduler.swift:33
    private init(mainScheduler: MainScheduler) {
ConcurrentMainScheduler.swift:41
    public static let instance = ConcurrentMainScheduler(mainScheduler: MainScheduler.instance)
MainScheduler.swift:35
    public static let instance = MainScheduler()
SerialDispatchQueueScheduler.swift:133
        let dispatchInterval = MainScheduler.convertTimeIntervalToDispatchTime(dueTime)
SerialDispatchQueueScheduler.swift:165
        let initial = MainScheduler.convertTimeIntervalToDispatchTime(startAfter)
SerialDispatchQueueScheduler.swift:166
        let dispatchInterval = MainScheduler.convertTimeIntervalToDispatchInterval(period)
VirtualTimeScheduler.swift:118
        MainScheduler.ensureExecutingOnScheduler()
VirtualTimeScheduler.swift:147
        MainScheduler.ensureExecutingOnScheduler()
VirtualTimeScheduler.swift:189
        MainScheduler.ensureExecutingOnScheduler()
VirtualTimeScheduler.swift:221
        MainScheduler.ensureExecutingOnScheduler()
VirtualTimeScheduler.swift:235
        MainScheduler.ensureExecutingOnScheduler()
: SerialDispatchQueueScheduler { 0022 0023 private let _mainQueue
MainScheduler.swift:28
        _mainQueue = dispatch_get_main_queue()
MainScheduler.swift:29
        super.init(serialQueue: _mainQueue)
MainScheduler.swift:57
        dispatch_async(_mainQueue) {
: dispatch_queue_t 0024 0025 var numberEnqueued
MainScheduler.swift:47
        let currentNumberEnqueued = AtomicIncrement(&numberEnqueued)
MainScheduler.swift:51
            AtomicDecrement(&numberEnqueued)
MainScheduler.swift:62
            AtomicDecrement(&self.numberEnqueued)
: AtomicInt = 0 0026 0027 private init
MainScheduler.swift:35
    public static let instance = MainScheduler()
() { 0028 _mainQueue = dispatch_get_main_queue() 0029 super.init(serialQueue: _mainQueue) 0030 } 0031 0032 /** 0033 Singleton instance of `MainScheduler` 0034 */ 0035 public static let instance
ConcurrentMainScheduler.swift:41
    public static let instance = ConcurrentMainScheduler(mainScheduler: MainScheduler.instance)
= MainScheduler() 0036 0037 /** 0038 In case this method is called on a background thread it will throw an exception. 0039 */ 0040 public class func ensureExecutingOnScheduler
VirtualTimeScheduler.swift:118
        MainScheduler.ensureExecutingOnScheduler()
VirtualTimeScheduler.swift:147
        MainScheduler.ensureExecutingOnScheduler()
VirtualTimeScheduler.swift:189
        MainScheduler.ensureExecutingOnScheduler()
VirtualTimeScheduler.swift:221
        MainScheduler.ensureExecutingOnScheduler()
VirtualTimeScheduler.swift:235
        MainScheduler.ensureExecutingOnScheduler()
() { 0041 if !NSThread.currentThread().isMainThread { 0042 rxFatalError("Executing on backgound thread. Please use `MainScheduler.instance.schedule` to schedule work on main thread.") 0043 } 0044 } 0045 0046 override func scheduleInternal<StateType>(state: StateType, action: StateType -> Disposable) -> Disposable { 0047 let currentNumberEnqueued = AtomicIncrement(&numberEnqueued) 0048 0049 if NSThread.currentThread().isMainThread && currentNumberEnqueued == 1 { 0050 let disposable = action(state) 0051 AtomicDecrement(&numberEnqueued) 0052 return disposable 0053 } 0054 0055 let cancel = SingleAssignmentDisposable() 0056 0057 dispatch_async(_mainQueue) { 0058 if !cancel.disposed { 0059 action(state) 0060 } 0061 0062 AtomicDecrement(&self.numberEnqueued) 0063 } 0064 0065 return cancel 0066 } 0067 } 0068