Skip to content

Commit 34c57d1

Browse files
author
pranav shenoy
committed
Using RunLoopSource in XCTestCase.waitForExpectations(withTimeout:file:line:handler:)
1 parent 1764c54 commit 34c57d1

File tree

1 file changed

+7
-23
lines changed

1 file changed

+7
-23
lines changed

Sources/XCTest/Public/Asynchronous/XCTWaiter.swift

+7-23
Original file line numberDiff line numberDiff line change
@@ -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

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

Comments
 (0)