Skip to content

Commit 11a7b71

Browse files
twittembmanmal
authored andcommitted
asyncChannel: fixes potential crashes when no more awaiting (apple#143)
This commit fixes crashes where the state is "awaiting" with no more awaiting clients. The state is now set to .idle to reflect the reality. # Conflicts: # Sources/AsyncAlgorithms/AsyncChannel.swift
1 parent 4b11faa commit 11a7b71

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

Sources/AsyncAlgorithms/AsyncChannel.swift

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ public final class AsyncChannel<Element: Sendable>: AsyncSequence, Sendable {
7070
switch self {
7171
case .awaiting(var awaiting):
7272
let continuation = awaiting.remove(Awaiting(placeholder: generation))?.continuation
73-
self = .awaiting(awaiting)
73+
if awaiting.isEmpty {
74+
self = .idle
75+
} else {
76+
self = .awaiting(awaiting)
77+
}
7478
return continuation
7579
default:
7680
return nil
@@ -117,8 +121,15 @@ public final class AsyncChannel<Element: Sendable>: AsyncSequence, Sendable {
117121
}
118122
return UnsafeResumption(continuation: send, success: continuation)
119123
case .awaiting(var nexts):
120-
nexts.insert(Awaiting(generation: generation, continuation: continuation))
121-
state.emission = .awaiting(nexts)
124+
if nexts.update(with: Awaiting(generation: generation, continuation: continuation)) != nil {
125+
nexts.remove(Awaiting(placeholder: generation))
126+
cancelled = true
127+
}
128+
if nexts.isEmpty {
129+
state.emission = .idle
130+
} else {
131+
state.emission = .awaiting(nexts)
132+
}
122133
return nil
123134
}
124135
}?.resume()

0 commit comments

Comments
 (0)