mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-16 23:52:40 -06:00
642b486986
Make timeout paths cancel or release every pending test continuation before cleanup, so failures cannot poison the remaining Swift suite. Inject the retry sleeper to preserve invalidation-before-backoff ordering without real-time polling.
40 lines
1.2 KiB
Swift
40 lines
1.2 KiB
Swift
import Foundation
|
|
|
|
final class AsyncTestGate: @unchecked Sendable {
|
|
private let lock = NSLock()
|
|
private var isOpen = false
|
|
private var waiters: [UUID: CheckedContinuation<Void, Never>] = [:]
|
|
|
|
func wait() async {
|
|
let id = UUID()
|
|
await withTaskCancellationHandler {
|
|
await withCheckedContinuation { continuation in
|
|
let resumeImmediately = self.lock.withLock {
|
|
guard !self.isOpen, !Task.isCancelled else { return true }
|
|
self.waiters[id] = continuation
|
|
return false
|
|
}
|
|
if resumeImmediately {
|
|
continuation.resume()
|
|
}
|
|
}
|
|
} onCancel: {
|
|
let continuation = self.lock.withLock {
|
|
self.waiters.removeValue(forKey: id)
|
|
}
|
|
continuation?.resume()
|
|
}
|
|
}
|
|
|
|
func open() {
|
|
let continuations = self.lock.withLock {
|
|
self.isOpen = true
|
|
defer { self.waiters.removeAll() }
|
|
return Array(self.waiters.values)
|
|
}
|
|
for continuation in continuations {
|
|
continuation.resume()
|
|
}
|
|
}
|
|
}
|