@@ -50,41 +50,44 @@ public final class AsyncChannel<Element: Sendable>: AsyncSequence, Sendable {
50
50
}
51
51
}
52
52
53
- struct Awaiting : Hashable {
53
+ typealias Pending = ChannelToken < UnsafeContinuation < UnsafeContinuation < Element ? , Never > ? , Never > >
54
+ typealias Awaiting = ChannelToken < UnsafeContinuation < Element ? , Never > >
55
+
56
+ struct ChannelToken < Continuation> : Hashable {
54
57
var generation : Int
55
- var continuation : UnsafeContinuation < Element ? , Never > ?
58
+ var continuation : Continuation ?
56
59
let cancelled : Bool
57
-
58
- init ( generation: Int , continuation: UnsafeContinuation < Element ? , Never > ) {
60
+
61
+ init ( generation: Int , continuation: Continuation ) {
59
62
self . generation = generation
60
63
self . continuation = continuation
61
64
cancelled = false
62
65
}
63
-
66
+
64
67
init ( placeholder generation: Int ) {
65
68
self . generation = generation
66
69
self . continuation = nil
67
70
cancelled = false
68
71
}
69
-
72
+
70
73
init ( cancelled generation: Int ) {
71
74
self . generation = generation
72
75
self . continuation = nil
73
76
cancelled = true
74
77
}
75
-
78
+
76
79
func hash( into hasher: inout Hasher ) {
77
80
hasher. combine ( generation)
78
81
}
79
-
80
- static func == ( _ lhs: Awaiting , _ rhs: Awaiting ) -> Bool {
82
+
83
+ static func == ( _ lhs: ChannelToken , _ rhs: ChannelToken ) -> Bool {
81
84
return lhs. generation == rhs. generation
82
85
}
83
86
}
84
87
85
88
enum Emission {
86
89
case idle
87
- case pending( [ UnsafeContinuation < UnsafeContinuation < Element ? , Never > ? , Never > ] )
90
+ case pending( [ Pending ] )
88
91
case awaiting( Set < Awaiting > )
89
92
90
93
mutating func cancel( _ generation: Int ) -> UnsafeContinuation < Element ? , Never > ? {
@@ -131,7 +134,7 @@ public final class AsyncChannel<Element: Sendable>: AsyncSequence, Sendable {
131
134
}
132
135
133
136
func next( _ generation: Int ) async -> Element ? {
134
- return await withUnsafeContinuation { continuation in
137
+ return await withUnsafeContinuation { ( continuation: UnsafeContinuation < Element ? , Never > ) in
135
138
var cancelled = false
136
139
var terminal = false
137
140
state. withCriticalRegion { state -> UnsafeResumption < UnsafeContinuation < Element ? , Never > ? , Never > ? in
@@ -150,7 +153,7 @@ public final class AsyncChannel<Element: Sendable>: AsyncSequence, Sendable {
150
153
} else {
151
154
state. emission = . pending( sends)
152
155
}
153
- return UnsafeResumption ( continuation: send, success: continuation)
156
+ return UnsafeResumption ( continuation: send. continuation , success: continuation)
154
157
case . awaiting( var nexts) :
155
158
if nexts. update ( with: Awaiting ( generation: generation, continuation: continuation) ) != nil {
156
159
nexts. remove ( Awaiting ( placeholder: generation) )
@@ -171,7 +174,7 @@ public final class AsyncChannel<Element: Sendable>: AsyncSequence, Sendable {
171
174
}
172
175
173
176
func terminateAll( ) {
174
- let ( sends, nexts) = state. withCriticalRegion { state -> ( [ UnsafeContinuation < UnsafeContinuation < Element ? , Never > ? , Never > ] , Set < Awaiting > ) in
177
+ let ( sends, nexts) = state. withCriticalRegion { state -> ( [ Pending ] , Set < Awaiting > ) in
175
178
if state. terminal {
176
179
return ( [ ] , [ ] )
177
180
}
@@ -188,14 +191,16 @@ public final class AsyncChannel<Element: Sendable>: AsyncSequence, Sendable {
188
191
}
189
192
}
190
193
for send in sends {
191
- send. resume ( returning: nil )
194
+ send. continuation ? . resume ( returning: nil )
192
195
}
193
196
for next in nexts {
194
197
next. continuation? . resume ( returning: nil )
195
198
}
196
199
}
197
200
198
201
func _send( _ element: Element ) async {
202
+ let generation = establish ( )
203
+
199
204
await withTaskCancellationHandler {
200
205
terminateAll ( )
201
206
} operation: {
@@ -206,10 +211,10 @@ public final class AsyncChannel<Element: Sendable>: AsyncSequence, Sendable {
206
211
}
207
212
switch state. emission {
208
213
case . idle:
209
- state. emission = . pending( [ continuation] )
214
+ state. emission = . pending( [ Pending ( generation : generation , continuation: continuation ) ] )
210
215
return nil
211
216
case . pending( var sends) :
212
- sends. append ( continuation)
217
+ sends. append ( Pending ( generation : generation , continuation: continuation ) )
213
218
state. emission = . pending( sends)
214
219
return nil
215
220
case . awaiting( var nexts) :
0 commit comments