@@ -142,7 +142,7 @@ public override async ValueTask<FlushResult> WriteAsync(ReadOnlyMemory<byte> sou
142142 var frameHeaderLength = PrepareFrameHeader ( buffer . AsSpan ( ) , source . Length , _frameType ) ;
143143 source . CopyTo ( buffer . AsMemory ( frameHeaderLength ) ) ;
144144 await _responseStream . WriteAsync ( buffer . AsMemory ( 0 ..( source . Length + frameHeaderLength ) ) , cancellationToken ) ;
145- ArrayPool < byte > . Shared . Return ( buffer ) ;
145+ ArrayPool < byte > . Shared . Return ( buffer , true ) ;
146146 }
147147 else
148148 {
@@ -208,11 +208,6 @@ public override async ValueTask<FlushResult> FlushAsync(CancellationToken cancel
208208
209209 private async Task < FlushResult > FlushAllSegmentsAsync ( int startOffset , CancellationToken localToken )
210210 {
211- if ( ! _currentSegment . IsEmpty )
212- _segments . Add ( _currentSegment ) ;
213- else if ( _currentSegment . IsAllocated )
214- _currentSegment = _currentSegment with { Used = Memory < byte > . Empty } ;
215-
216211 // First segment handled with offset.
217212 var memory = _segments [ 0 ] ;
218213 Debug . Assert ( ! memory . IsEmpty ) ;
@@ -227,6 +222,12 @@ private async Task<FlushResult> FlushAllSegmentsAsync(int startOffset, Cancellat
227222 await _responseStream . WriteAsync ( memory . Used , localToken ) ;
228223 _memoryPool . Return ( memory . Reference , true ) ;
229224 }
225+
226+ // Last segment (the _currentSegment is not returned to the memory pool.
227+ if ( ! _currentSegment . IsEmpty )
228+ await _responseStream . WriteAsync ( _currentSegment . Used , localToken ) ;
229+ _currentSegment = _currentSegment with { Used = Memory < byte > . Empty } ;
230+
230231 _segments . Clear ( ) ;
231232 _unflushedBytes = 0 ;
232233 _responseStream . Flush ( ) ;
@@ -263,24 +264,27 @@ public void Flush()
263264
264265 private void FlushAllSegments ( int startOffset )
265266 {
266- if ( ! _currentSegment . IsEmpty )
267- _segments . Add ( _currentSegment ) ;
268- else if ( _currentSegment . IsAllocated )
269- _currentSegment = _currentSegment with { Used = Memory < byte > . Empty } ;
270-
267+ // First segment handled with offset.
271268 var source = CollectionsMarshal . AsSpan ( _segments ) ;
272269 ref var initialMemory = ref source [ 0 ] ;
273270 Debug . Assert ( ! initialMemory . IsEmpty ) ;
274271 _responseStream . Write ( initialMemory . Used . Span [ startOffset ..] ) ;
275272 _memoryPool . Return ( initialMemory . Reference , true ) ;
276273
274+ // Remaining segments.
277275 for ( int i = 1 ; i < _segments . Count ; i ++ )
278276 {
279277 ref var memory = ref source [ i ] ;
280278 if ( memory . Used . Length > 0 )
281279 _responseStream . Write ( memory . Used . Span ) ;
282280 _memoryPool . Return ( memory . Reference , true ) ;
283281 }
282+
283+ // Last segment (the _currentSegment is not returned to the memory pool.
284+ if ( ! _currentSegment . IsEmpty )
285+ _responseStream . Write ( _currentSegment . Used . Span ) ;
286+ _currentSegment = _currentSegment with { Used = Memory < byte > . Empty } ;
287+
284288 _segments . Clear ( ) ;
285289 _unflushedBytes = 0 ;
286290 _responseStream . Flush ( ) ;
@@ -335,15 +339,15 @@ private void ClearSegments(Span<Segment> source, bool clearCurrent = true)
335339 for ( int i = 0 ; i < source . Length ; i ++ )
336340 {
337341 ref var memory = ref source [ i ] ;
338- if ( memory . Reference . Length != 0 )
342+ if ( memory . IsAllocated )
339343 _memoryPool . Return ( memory . Reference , true ) ;
340344 }
341345 _unflushedBytes = 0 ;
342346 _segments . Clear ( ) ;
343347 if ( clearCurrent )
344348 {
345349 if ( _currentSegment . IsAllocated )
346- _memoryPool . Return ( _currentSegment . Reference ) ;
350+ _memoryPool . Return ( _currentSegment . Reference , true ) ;
347351 _currentSegment = new Segment ( ) ;
348352 }
349353 else
0 commit comments