@@ -117,7 +117,7 @@ open class XCTWaiter {
117117 internal var waitSourceLocation : SourceLocation ?
118118 private weak var manager : WaiterManager < XCTWaiter > ?
119119 private var runLoop : RunLoop ?
120-
120+ private var runLoopSource : RunLoop . _Source ?
121121 private weak var _delegate : XCTWaiterDelegate ?
122122 private let delegateQueue = DispatchQueue ( label: " org.swift.XCTest.XCTWaiter.delegate " )
123123
@@ -208,7 +208,8 @@ open class XCTWaiter {
208208 queue_configureExpectations ( expectations)
209209 state = . waiting( state: waitingState)
210210 self . runLoop = runLoop
211-
211+ self . runLoopSource = RunLoop . _Source ( )
212+ self . runLoop? . _add ( self . runLoopSource!, forMode: . default)
212213 queue_validateExpectationFulfillment ( dueToTimeout: false )
213214 }
214215
@@ -217,14 +218,7 @@ open class XCTWaiter {
217218 self . manager = manager
218219
219220 // 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)
228222
229223 manager. stopManaging ( self )
230224 self . manager = nil
@@ -356,22 +350,12 @@ open class XCTWaiter {
356350
357351private extension XCTWaiter {
358352 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) )
366354 }
367355
368356 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 ( )
375359 }
376360}
377361
0 commit comments