Skip to content

Commit 4b7289d

Browse files
author
pranav shenoy
committed
Using RunLoopSource in XCTestCase.waitForExpectations(withTimeout:file:line:handler:)
1 parent ec352a0 commit 4b7289d

File tree

1 file changed

+7
-23
lines changed

1 file changed

+7
-23
lines changed

Sources/XCTest/Public/Asynchronous/XCTWaiter.swift

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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

357351
private 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

Comments
 (0)