Make LimitArrayPoolWriteStream.ReturnAllPooledBuffers idempotent#128083
Make LimitArrayPoolWriteStream.ReturnAllPooledBuffers idempotent#128083EgorBo wants to merge 1 commit into
Conversation
Use Interlocked exchanges so that concurrent Dispose() calls cannot double-return the same buffer to ArrayPool<byte>.Shared. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Tagging subscribers to this area: @karelz, @dotnet/ncl |
There was a problem hiding this comment.
Pull request overview
This PR makes HttpContent.LimitArrayPoolWriteStream.ReturnAllPooledBuffers() safe to call multiple times concurrently by making buffer-return operations idempotent, preventing accidental double-return of the same byte[] to ArrayPool<byte>.Shared (which can corrupt the shared pool).
Changes:
- Atomically claims and clears
_pooledBuffersviaInterlocked.Exchange(ref _pooledBuffers, null)so only one caller returns the pooled buffer list. - Atomically claims and clears
_lastBufferIsPooledviaInterlocked.Exchange(ref _lastBufferIsPooled, false)so only one caller returns the final pooled buffer. - Updates internal comments to document the rationale and the concurrency/idempotency intent.
|
We could consider having In your example, if you call |
Makes
LimitArrayPoolWriteStream.ReturnAllPooledBuffersidempotent under concurrentDispose()so that user code cannot accidentally double-return the same buffer toArrayPool<byte>.Shared. TwoInterlocked.Exchangecalls on the existing fields are enough — no new allocations or fast-path overhead in the single-threaded case.It's not a security issue, just makes code more robust to buggy implementations
Note
This PR was authored with the assistance of GitHub Copilot.