Skip to content

Commit 87791e0

Browse files
committed
use Atomics package instead of Locking where possible
1 parent 451654f commit 87791e0

File tree

4 files changed

+64
-64
lines changed

4 files changed

+64
-64
lines changed

Package.resolved

Lines changed: 39 additions & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version:5.5
1+
// swift-tools-version:6.0
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
33

44
import PackageDescription
@@ -20,19 +20,17 @@ let package = Package(
2020
.package(url: "https://github.com/apple/swift-collections.git", .upToNextMajor(from: "1.0.3")),
2121
.package(url: "https://github.com/OpenCombine/OpenCombine.git", from: "0.14.0"),
2222
.package(url: "https://github.com/apple/swift-async-algorithms.git", .upToNextMajor(from: "1.0.0")),
23+
.package(url: "https://github.com/apple/swift-atomics.git", .upToNextMajor(from: "1.2.0")),
2324
],
2425
targets: [
2526
.target(
2627
name: "AsyncExtensions",
27-
dependencies: [.product(name: "Collections", package: "swift-collections")],
28-
path: "Sources"
29-
// ,
30-
// swiftSettings: [
31-
// .unsafeFlags([
32-
// "-Xfrontend", "-warn-concurrency",
33-
// "-Xfrontend", "-enable-actor-data-race-checks",
34-
// ])
35-
// ]
28+
dependencies: [
29+
.product(name: "Collections", package: "swift-collections"),
30+
.product(name: "Atomics", package: "swift-atomics")
31+
],
32+
path: "Sources",
33+
swiftSettings: [.swiftLanguageMode(.v5)]
3634
),
3735
.testTarget(
3836
name: "AsyncExtensionsTests",
@@ -41,6 +39,8 @@ let package = Package(
4139
.product(name: "OpenCombine", package: "OpenCombine", condition: .when(platforms: [.linux])),
4240
.product(name: "AsyncAlgorithms", package: "swift-async-algorithms")
4341
],
44-
path: "Tests"),
42+
path: "Tests",
43+
swiftSettings: [.swiftLanguageMode(.v5)]
44+
),
4545
]
4646
)

Sources/AsyncChannels/AsyncBufferedChannel.swift

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// Created by Thibault Wittemberg on 07/01/2022.
66
//
77

8+
import Atomics
89
import DequeModule
910
import OrderedCollections
1011

@@ -77,19 +78,16 @@ public final class AsyncBufferedChannel<Element>: AsyncSequence, Sendable {
7778
}
7879
}
7980

80-
let ids: ManagedCriticalState<Int>
81+
let ids: ManagedAtomic<Int>
8182
let state: ManagedCriticalState<State>
8283

8384
public init() {
84-
self.ids = ManagedCriticalState(0)
85+
self.ids = ManagedAtomic(0)
8586
self.state = ManagedCriticalState(.initial)
8687
}
8788

8889
func generateId() -> Int {
89-
self.ids.withCriticalRegion { ids in
90-
ids += 1
91-
return ids
92-
}
90+
ids.wrappingIncrementThenLoad(by: 1, ordering: .relaxed)
9391
}
9492

9593
var hasBufferedElements: Bool {
@@ -155,12 +153,12 @@ public final class AsyncBufferedChannel<Element>: AsyncSequence, Sendable {
155153

156154
func next(onSuspend: (() -> Void)? = nil) async -> Element? {
157155
let awaitingId = self.generateId()
158-
let cancellation = ManagedCriticalState<Bool>(false)
156+
let cancellation = ManagedAtomic<Bool>(false)
159157

160158
return await withTaskCancellationHandler {
161159
await withCheckedContinuation { [state] (continuation: CheckedContinuation<Element?, Never>) in
162160
let decision = state.withCriticalRegion { state -> AwaitingDecision in
163-
let isCancelled = cancellation.withCriticalRegion { $0 }
161+
let isCancelled = cancellation.load(ordering: .acquiring)
164162
guard !isCancelled else { return .resume(nil) }
165163

166164
switch state {
@@ -200,9 +198,7 @@ public final class AsyncBufferedChannel<Element>: AsyncSequence, Sendable {
200198
}
201199
} onCancel: { [state] in
202200
let awaiting = state.withCriticalRegion { state -> Awaiting? in
203-
cancellation.withCriticalRegion { cancellation in
204-
cancellation = true
205-
}
201+
cancellation.store(true, ordering: .releasing)
206202
switch state {
207203
case .awaiting(var awaitings):
208204
let awaiting = awaitings.remove(.placeHolder(id: awaitingId))

Sources/AsyncChannels/AsyncThrowingBufferedChannel.swift

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// Created by Thibault Wittemberg on 07/01/2022.
66
//
77

8+
import Atomics
89
import DequeModule
910
import OrderedCollections
1011

@@ -88,19 +89,16 @@ public final class AsyncThrowingBufferedChannel<Element, Failure: Error>: AsyncS
8889
}
8990
}
9091

91-
let ids: ManagedCriticalState<Int>
92+
let ids: ManagedAtomic<Int>
9293
let state: ManagedCriticalState<State>
9394

9495
public init() {
95-
self.ids = ManagedCriticalState(0)
96+
self.ids = ManagedAtomic(0)
9697
self.state = ManagedCriticalState(.initial)
9798
}
9899

99100
func generateId() -> Int {
100-
self.ids.withCriticalRegion { ids in
101-
ids += 1
102-
return ids
103-
}
101+
ids.wrappingIncrementThenLoad(by: 1, ordering: .relaxed)
104102
}
105103

106104
var hasBufferedElements: Bool {
@@ -176,12 +174,12 @@ public final class AsyncThrowingBufferedChannel<Element, Failure: Error>: AsyncS
176174

177175
func next(onSuspend: (() -> Void)? = nil) async throws -> Element? {
178176
let awaitingId = self.generateId()
179-
let cancellation = ManagedCriticalState<Bool>(false)
177+
let cancellation = ManagedAtomic<Bool>(false)
180178

181179
return try await withTaskCancellationHandler {
182180
try await withUnsafeThrowingContinuation { [state] (continuation: UnsafeContinuation<Element?, Error>) in
183181
let decision = state.withCriticalRegion { state -> AwaitingDecision in
184-
let isCancelled = cancellation.withCriticalRegion { $0 }
182+
let isCancelled = cancellation.load(ordering: .acquiring)
185183
guard !isCancelled else { return .resume(nil) }
186184

187185
switch state {
@@ -227,9 +225,7 @@ public final class AsyncThrowingBufferedChannel<Element, Failure: Error>: AsyncS
227225
}
228226
} onCancel: { [state] in
229227
let awaiting = state.withCriticalRegion { state -> Awaiting? in
230-
cancellation.withCriticalRegion { cancellation in
231-
cancellation = true
232-
}
228+
cancellation.store(true, ordering: .releasing)
233229
switch state {
234230
case .awaiting(var awaitings):
235231
let awaiting = awaitings.remove(.placeHolder(id: awaitingId))

0 commit comments

Comments
 (0)