Skip to content

Commit

Permalink
Using RunLoopSource in XCTestCase.waitForExpectations(withTimeout:fil…
Browse files Browse the repository at this point in the history
…e:line:handler:)
  • Loading branch information
pranav shenoy committed Dec 15, 2020
1 parent 1764c54 commit 34c57d1
Showing 1 changed file with 7 additions and 23 deletions.
30 changes: 7 additions & 23 deletions Sources/XCTest/Public/Asynchronous/XCTWaiter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ open class XCTWaiter {
internal var waitSourceLocation: SourceLocation?
private weak var manager: WaiterManager<XCTWaiter>?
private var runLoop: RunLoop?

private var runLoopSource: RunLoop._Source?
private weak var _delegate: XCTWaiterDelegate?
private let delegateQueue = DispatchQueue(label: "org.swift.XCTest.XCTWaiter.delegate")

Expand Down Expand Up @@ -210,7 +210,8 @@ open class XCTWaiter {
queue_configureExpectations(expectations)
state = .waiting(state: waitingState)
self.runLoop = runLoop

self.runLoopSource = RunLoop._Source()
self.runLoop?._add(self.runLoopSource!, forMode: .default)
queue_validateExpectationFulfillment(dueToTimeout: false)
}

Expand All @@ -219,14 +220,7 @@ open class XCTWaiter {
self.manager = manager

// Begin the core wait loop.
let timeoutTimestamp = Date.timeIntervalSinceReferenceDate + timeout
while !isFinished {
let remaining = timeoutTimestamp - Date.timeIntervalSinceReferenceDate
if remaining <= 0 {
break
}
primitiveWait(using: runLoop, duration: remaining)
}
primitiveWait(using: runLoop, duration: timeout)

manager.stopManaging(self)
self.manager = nil
Expand Down Expand Up @@ -358,22 +352,12 @@ open class XCTWaiter {

private extension XCTWaiter {
func primitiveWait(using runLoop: RunLoop, duration timeout: TimeInterval) {
// The contract for `primitiveWait(for:)` explicitly allows waiting for a shorter period than requested
// by the `timeout` argument. Only run for a short time in case `cancelPrimitiveWait()` was called and
// issued `CFRunLoopStop` just before we reach this point.
let timeIntervalToRun = min(0.1, timeout)

// RunLoop.run(mode:before:) should have @discardableResult <rdar://problem/45371901>
_ = runLoop.run(mode: .default, before: Date(timeIntervalSinceNow: timeIntervalToRun))
runLoop.run(until: .init(timeIntervalSinceNow: timeout))
}

func cancelPrimitiveWait() {
guard let runLoop = runLoop else { return }
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
CFRunLoopStop(runLoop.getCFRunLoop())
#else
runLoop._stop()
#endif
dispatchPrecondition(condition: .onQueue(XCTWaiter.subsystemQueue))
runLoopSource?.invalidate()
}
}

Expand Down

0 comments on commit 34c57d1

Please sign in to comment.