@@ -119,7 +119,7 @@ open class XCTWaiter {
119
119
internal var waitSourceLocation : SourceLocation ?
120
120
private weak var manager : WaiterManager < XCTWaiter > ?
121
121
private var runLoop : RunLoop ?
122
-
122
+ private var runLoopSource : RunLoop . _Source ?
123
123
private weak var _delegate : XCTWaiterDelegate ?
124
124
private let delegateQueue = DispatchQueue ( label: " org.swift.XCTest.XCTWaiter.delegate " )
125
125
@@ -210,7 +210,8 @@ open class XCTWaiter {
210
210
queue_configureExpectations ( expectations)
211
211
state = . waiting( state: waitingState)
212
212
self . runLoop = runLoop
213
-
213
+ self . runLoopSource = RunLoop . _Source ( )
214
+ self . runLoop? . _add ( self . runLoopSource!, forMode: . default)
214
215
queue_validateExpectationFulfillment ( dueToTimeout: false )
215
216
}
216
217
@@ -219,14 +220,7 @@ open class XCTWaiter {
219
220
self . manager = manager
220
221
221
222
// Begin the core wait loop.
222
- let timeoutTimestamp = Date . timeIntervalSinceReferenceDate + timeout
223
- while !isFinished {
224
- let remaining = timeoutTimestamp - Date. timeIntervalSinceReferenceDate
225
- if remaining <= 0 {
226
- break
227
- }
228
- primitiveWait ( using: runLoop, duration: remaining)
229
- }
223
+ primitiveWait ( using: runLoop, duration: timeout)
230
224
231
225
manager. stopManaging ( self )
232
226
self . manager = nil
@@ -358,22 +352,12 @@ open class XCTWaiter {
358
352
359
353
private extension XCTWaiter {
360
354
func primitiveWait( using runLoop: RunLoop , duration timeout: TimeInterval ) {
361
- // The contract for `primitiveWait(for:)` explicitly allows waiting for a shorter period than requested
362
- // by the `timeout` argument. Only run for a short time in case `cancelPrimitiveWait()` was called and
363
- // issued `CFRunLoopStop` just before we reach this point.
364
- let timeIntervalToRun = min ( 0.1 , timeout)
365
-
366
- // RunLoop.run(mode:before:) should have @discardableResult <rdar://problem/45371901>
367
- _ = runLoop. run ( mode: . default, before: Date ( timeIntervalSinceNow: timeIntervalToRun) )
355
+ runLoop. run ( until: . init( timeIntervalSinceNow: timeout) )
368
356
}
369
357
370
358
func cancelPrimitiveWait( ) {
371
- guard let runLoop = runLoop else { return }
372
- #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
373
- CFRunLoopStop ( runLoop. getCFRunLoop ( ) )
374
- #else
375
- runLoop. _stop ( )
376
- #endif
359
+ dispatchPrecondition ( condition: . onQueue( XCTWaiter . subsystemQueue) )
360
+ runLoopSource? . invalidate ( )
377
361
}
378
362
}
379
363
0 commit comments