@@ -119,7 +119,7 @@ open class XCTWaiter {
119119 internal var waitSourceLocation : SourceLocation ?
120120 private weak var manager : WaiterManager < XCTWaiter > ?
121121 private var runLoop : RunLoop ?
122-
122+ private var runLoopSource : RunLoop . _Source ?
123123 private weak var _delegate : XCTWaiterDelegate ?
124124 private let delegateQueue = DispatchQueue ( label: " org.swift.XCTest.XCTWaiter.delegate " )
125125
@@ -210,7 +210,8 @@ open class XCTWaiter {
210210 queue_configureExpectations ( expectations)
211211 state = . waiting( state: waitingState)
212212 self . runLoop = runLoop
213-
213+ self . runLoopSource = RunLoop . _Source ( )
214+ self . runLoop? . _add ( self . runLoopSource!, forMode: . default)
214215 queue_validateExpectationFulfillment ( dueToTimeout: false )
215216 }
216217
@@ -219,14 +220,7 @@ open class XCTWaiter {
219220 self . manager = manager
220221
221222 // 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)
230224
231225 manager. stopManaging ( self )
232226 self . manager = nil
@@ -358,22 +352,12 @@ open class XCTWaiter {
358352
359353private extension XCTWaiter {
360354 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) )
368356 }
369357
370358 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 ( )
377361 }
378362}
379363
0 commit comments