File tree Expand file tree Collapse file tree 1 file changed +18
-0
lines changed
Expand file tree Collapse file tree 1 file changed +18
-0
lines changed Original file line number Diff line number Diff line change @@ -110,6 +110,24 @@ internal struct _AsyncBytesBuffer: @unchecked Sendable {
110110 }
111111 try Task . checkCancellation ( )
112112 do {
113+ // If two tasks have access to this iterator then the references on
114+ // the storage will be non uniquely owned. This means that any reload
115+ // must happen into it's own fresh buffer. The consumption of those
116+ // bytes between two tasks are inherently defined as potential
117+ // duplication by the nature of sending that buffer across the two
118+ // tasks - this means that the brief period in which they may be
119+ // sharing non reloaded bytes is to be expected; basically in that
120+ // edge case of making the iterator and sending that across to two
121+ // places to iterate is asking for something bizzare and the answer
122+ // should not be crash, but it definitely cannot be consistent.
123+ //
124+ // The unique ref check is here to prevent the potentials of a crashing
125+ // secnario.
126+ if !isKnownUniquelyReferenced( & storage) {
127+ // The count is not mutated across invocations so the access is safe.
128+ let capacity = storage. buffer. count
129+ storage = Storage ( capacity: capacity)
130+ }
113131 let readSize : Int = try await readFunction ( storage. buffer)
114132 if readSize == 0 {
115133 finished = true
You can’t perform that action at this time.
0 commit comments