Skip to content

Commit

Permalink
Make the Polling Helpers Sendable (#1133)
Browse files Browse the repository at this point in the history
  • Loading branch information
younata committed Apr 11, 2024
1 parent 08e2632 commit f4b472a
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 10 deletions.
2 changes: 1 addition & 1 deletion Sources/Nimble/Polling+AsyncAwait.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ internal actor Poller<T> {
file: expression.location.file,
line: expression.location.line,
fnName: fnName) {
if self.updateMatcherResult(result: try await matcherRunner())
if await self.updateMatcherResult(result: try await matcherRunner())
.toBoolean(expectation: style) {
if matchStyle.isContinous {
return .incomplete
Expand Down
18 changes: 9 additions & 9 deletions Sources/Nimble/Utils/AsyncAwait.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ private let pollLeeway = NimbleTimeInterval.milliseconds(1)

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

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

private func poll(_ pollInterval: NimbleTimeInterval, expression: @escaping () async throws -> PollStatus) async -> AsyncPollResult<Bool> {
private func poll(_ pollInterval: NimbleTimeInterval, expression: @escaping @Sendable () async throws -> PollStatus) async -> AsyncPollResult<Bool> {
for try await _ in AsyncTimerSequence(interval: pollInterval) {
do {
if case .finished(let result) = try await expression() {
Expand Down Expand Up @@ -199,7 +199,7 @@ private func runPoller(
pollInterval: NimbleTimeInterval,
awaiter: Awaiter,
fnName: String = #function, file: FileString = #file, line: UInt = #line,
expression: @escaping () async throws -> PollStatus
expression: @escaping @Sendable () async throws -> PollStatus
) async -> AsyncPollResult<Bool> {
awaiter.waitLock.acquireWaitingLock(
fnName,
Expand Down Expand Up @@ -258,7 +258,7 @@ private func runAwaitTrigger<T>(
timeoutInterval: NimbleTimeInterval,
leeway: NimbleTimeInterval,
file: FileString, line: UInt,
_ closure: @escaping (@escaping (T) -> Void) async throws -> Void
_ closure: @escaping @Sendable (@escaping @Sendable (T) -> Void) async throws -> Void
) async -> AsyncPollResult<T> {
let timeoutQueue = awaiter.timeoutQueue
let completionCount = Box(value: 0)
Expand Down Expand Up @@ -309,7 +309,7 @@ internal func performBlock<T>(
timeoutInterval: NimbleTimeInterval,
leeway: NimbleTimeInterval,
file: FileString, line: UInt,
_ closure: @escaping (@escaping (T) -> Void) async throws -> Void
_ closure: @escaping @Sendable (@escaping @Sendable (T) -> Void) async throws -> Void
) async -> AsyncPollResult<T> {
await runAwaitTrigger(
awaiter: NimbleEnvironment.activeInstance.awaiter,
Expand All @@ -324,7 +324,7 @@ internal func pollBlock(
file: FileString,
line: UInt,
fnName: String = #function,
expression: @escaping () async throws -> PollStatus) async -> AsyncPollResult<Bool> {
expression: @escaping @Sendable () async throws -> PollStatus) async -> AsyncPollResult<Bool> {
await runPoller(
timeoutInterval: timeoutInterval,
pollInterval: pollInterval,
Expand Down

0 comments on commit f4b472a

Please sign in to comment.