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