-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Avoid empty segments from PipeReader.ReadAsync #72536
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -197,20 +197,41 @@ private void AllocateWriteHeadSynchronized(int sizeHint) | |||||
| _writingHeadBytesBuffered = 0; | ||||||
| } | ||||||
|
|
||||||
| BufferSegment newSegment = AllocateSegment(sizeHint); | ||||||
| if (_writingHead.Length == 0) | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would use _writingHeadBytesBuffered instead (but the logic would need to be reworked a bit)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I tried using that field initially, but it gets set to 0 in Advance with a non-zero value, so you need to check some other value anyways. What's wrong with
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nothing wrong with it, it just avoids the indirection but this is fine. |
||||||
| { | ||||||
| // If we got here that means Advance was called with 0 bytes or GetMemory was called again without any writes occurring | ||||||
| // And, the newly requested memory size is greater than our unused segments internal memory buffer | ||||||
| // So we should reuse the BufferSegment and replace the memory it's holding, this way ReadAsync will not receive a buffer with one segment being empty | ||||||
| _writingHead.ResetMemory(preserveIndex: true); | ||||||
| SetupSegment(_writingHead, sizeHint); | ||||||
| } | ||||||
| else | ||||||
| { | ||||||
| BufferSegment newSegment = AllocateSegment(sizeHint); | ||||||
|
|
||||||
| _writingHead.SetNext(newSegment); | ||||||
| _writingHead = newSegment; | ||||||
| _writingHead.SetNext(newSegment); | ||||||
| _writingHead = newSegment; | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| private BufferSegment AllocateSegment(int sizeHint) | ||||||
| { | ||||||
| Debug.Assert(sizeHint >= 0); | ||||||
| BufferSegment newSegment = CreateSegmentUnsynchronized(); | ||||||
|
|
||||||
| SetupSegment(newSegment, sizeHint); | ||||||
|
|
||||||
| return newSegment; | ||||||
| } | ||||||
|
|
||||||
| private void SetupSegment(BufferSegment segment, int sizeHint) | ||||||
|
||||||
| private void SetupSegment(BufferSegment segment, int sizeHint) | |
| private void RentMemory(BufferSegment segment, int sizeHint) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit:
Maybe add a
ClearMemory()method and rename this toReset()and have it callClearMemory(). Because this is doing more than just resetting memory, it's resetting theRunningIndexand the_nextpointer too. It might make sense forClearMemory()to keep theResetMemory()name.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 I was thinking along those lines when writing it. Good to know we're thinking that same thing.