@@ -136,37 +136,44 @@ public final class UIScheduler: Scheduler {
136
136
/// begins.
137
137
@discardableResult
138
138
public func schedule( _ action: @escaping ( ) -> Void ) -> Disposable ? {
139
- let disposable = AnyDisposable ( )
140
- let actionAndDecrement = {
141
- if !disposable. isDisposed {
139
+ let positionInQueue = enqueue ( )
140
+
141
+ // If we're already running on the main queue, and there isn't work
142
+ // already enqueued, we can skip scheduling and just execute directly.
143
+ if positionInQueue == 1 && DispatchQueue . getSpecific ( key: UIScheduler . dispatchSpecificKey) == UIScheduler . dispatchSpecificValue {
144
+ action ( )
145
+ dequeue ( )
146
+ return nil
147
+ } else {
148
+ let disposable = AnyDisposable ( )
149
+
150
+ DispatchQueue . main. async {
151
+ defer { self . dequeue ( ) }
152
+ guard !disposable. isDisposed else { return }
142
153
action ( )
143
154
}
144
155
145
- #if os(Linux)
146
- self . queueLength. modify { $0 -= 1 }
147
- #else
148
- OSAtomicDecrement32 ( self . queueLength)
149
- #endif
156
+ return disposable
150
157
}
158
+ }
151
159
160
+ private func dequeue( ) {
152
161
#if os(Linux)
153
- let queued = self . queueLength. modify { value -> Int32 in
154
- value += 1
155
- return value
156
- }
162
+ queueLength. modify { $0 -= 1 }
157
163
#else
158
- let queued = OSAtomicIncrement32 ( queueLength)
164
+ OSAtomicDecrement32 ( queueLength)
159
165
#endif
166
+ }
160
167
161
- // If we're already running on the main queue, and there isn't work
162
- // already enqueued, we can skip scheduling and just execute directly.
163
- if queued == 1 && DispatchQueue . getSpecific ( key: UIScheduler . dispatchSpecificKey) == UIScheduler . dispatchSpecificValue {
164
- actionAndDecrement ( )
165
- } else {
166
- DispatchQueue . main. async ( execute: actionAndDecrement)
168
+ private func enqueue( ) -> Int32 {
169
+ #if os(Linux)
170
+ return queueLength. modify { value -> Int32 in
171
+ value += 1
172
+ return value
167
173
}
168
-
169
- return disposable
174
+ #else
175
+ return OSAtomicIncrement32 ( queueLength)
176
+ #endif
170
177
}
171
178
}
172
179
0 commit comments