Skip to content

Commit f98fef5

Browse files
authored
Make the Polling Helpers Sendable (#1133)
1 parent a9e5c1a commit f98fef5

File tree

2 files changed

+10
-10
lines changed

2 files changed

+10
-10
lines changed

Sources/Nimble/Polling+AsyncAwait.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ internal actor Poller<T> {
4141
file: expression.location.file,
4242
line: expression.location.line,
4343
fnName: fnName) {
44-
if self.updateMatcherResult(result: try await matcherRunner())
44+
if await self.updateMatcherResult(result: try await matcherRunner())
4545
.toBoolean(expectation: style) {
4646
if matchStyle.isContinous {
4747
return .incomplete

Sources/Nimble/Utils/AsyncAwait.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ private let pollLeeway = NimbleTimeInterval.milliseconds(1)
1212

1313
// Like PollResult, except it doesn't support objective-c exceptions.
1414
// Which is tolerable because Swift Concurrency doesn't support recording objective-c exceptions.
15-
internal enum AsyncPollResult<T> {
15+
internal enum AsyncPollResult<T: Sendable>: Sendable {
1616
/// Incomplete indicates None (aka - this value hasn't been fulfilled yet)
1717
case incomplete
1818
/// TimedOut indicates the result reached its defined timeout limit before returning
@@ -57,10 +57,10 @@ internal enum AsyncPollResult<T> {
5757
// Inspired by swift-async-algorithm's AsyncChannel, but massively simplified
5858
// especially given Nimble's usecase.
5959
// AsyncChannel: https://github.com/apple/swift-async-algorithms/blob/main/Sources/AsyncAlgorithms/Channels/AsyncChannel.swift
60-
internal actor AsyncPromise<T> {
60+
internal actor AsyncPromise<T: Sendable> {
6161
private let storage = Storage()
6262

63-
private final class Storage {
63+
private final class Storage: @unchecked Sendable {
6464
private var continuations: [UnsafeContinuation<T, Never>] = []
6565
private var value: T?
6666
// Yes, this is not the fastest lock, but it's platform independent,
@@ -131,7 +131,7 @@ internal actor AsyncPromise<T> {
131131
/// checked.
132132
///
133133
/// In addition, stopping the run loop is used to halt code executed on the main run loop.
134-
private func timeout<T>(timeoutQueue: DispatchQueue, timeoutInterval: NimbleTimeInterval, forcefullyAbortTimeout: NimbleTimeInterval) async -> AsyncPollResult<T> {
134+
private func timeout<T: Sendable>(timeoutQueue: DispatchQueue, timeoutInterval: NimbleTimeInterval, forcefullyAbortTimeout: NimbleTimeInterval) async -> AsyncPollResult<T> {
135135
do {
136136
try await Task.sleep(nanoseconds: timeoutInterval.nanoseconds)
137137
} catch {}
@@ -165,7 +165,7 @@ private func timeout<T>(timeoutQueue: DispatchQueue, timeoutInterval: NimbleTime
165165
return await promise.value
166166
}
167167

168-
private func poll(_ pollInterval: NimbleTimeInterval, expression: @escaping () async throws -> PollStatus) async -> AsyncPollResult<Bool> {
168+
private func poll(_ pollInterval: NimbleTimeInterval, expression: @escaping @Sendable () async throws -> PollStatus) async -> AsyncPollResult<Bool> {
169169
for try await _ in AsyncTimerSequence(interval: pollInterval) {
170170
do {
171171
if case .finished(let result) = try await expression() {
@@ -199,7 +199,7 @@ private func runPoller(
199199
pollInterval: NimbleTimeInterval,
200200
awaiter: Awaiter,
201201
fnName: String = #function, file: FileString = #file, line: UInt = #line,
202-
expression: @escaping () async throws -> PollStatus
202+
expression: @escaping @Sendable () async throws -> PollStatus
203203
) async -> AsyncPollResult<Bool> {
204204
awaiter.waitLock.acquireWaitingLock(
205205
fnName,
@@ -258,7 +258,7 @@ private func runAwaitTrigger<T>(
258258
timeoutInterval: NimbleTimeInterval,
259259
leeway: NimbleTimeInterval,
260260
file: FileString, line: UInt,
261-
_ closure: @escaping (@escaping (T) -> Void) async throws -> Void
261+
_ closure: @escaping @Sendable (@escaping @Sendable (T) -> Void) async throws -> Void
262262
) async -> AsyncPollResult<T> {
263263
let timeoutQueue = awaiter.timeoutQueue
264264
let completionCount = Box(value: 0)
@@ -309,7 +309,7 @@ internal func performBlock<T>(
309309
timeoutInterval: NimbleTimeInterval,
310310
leeway: NimbleTimeInterval,
311311
file: FileString, line: UInt,
312-
_ closure: @escaping (@escaping (T) -> Void) async throws -> Void
312+
_ closure: @escaping @Sendable (@escaping @Sendable (T) -> Void) async throws -> Void
313313
) async -> AsyncPollResult<T> {
314314
await runAwaitTrigger(
315315
awaiter: NimbleEnvironment.activeInstance.awaiter,
@@ -324,7 +324,7 @@ internal func pollBlock(
324324
file: FileString,
325325
line: UInt,
326326
fnName: String = #function,
327-
expression: @escaping () async throws -> PollStatus) async -> AsyncPollResult<Bool> {
327+
expression: @escaping @Sendable () async throws -> PollStatus) async -> AsyncPollResult<Bool> {
328328
await runPoller(
329329
timeoutInterval: timeoutInterval,
330330
pollInterval: pollInterval,

0 commit comments

Comments
 (0)