Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Simplify the allocate and commit logic #33811

Merged
merged 2 commits into from
Dec 5, 2018
Merged

Conversation

davidfowl
Copy link
Member

@davidfowl davidfowl commented Dec 4, 2018

  • Only clear the writing head when the list is empty.
  • Commit just updates the reading tail (renamed the commit head).

PS: I'm not super happy about the PipeOperationState changes but I didn't want to change all of the tests. Suggestions welcome.

cc @benaadams

- Only clear the writing head when the list is empty.
- Commit just updates the reading tail (renamed the commit head).
BeginRead = 1,
BeginReadTenative = 2,
EndRead = 4,
WritingActive = 8
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before a non-null _writeHead meant that the there was a write in progress. This state keeps track of that fact now.

public bool IsReadingActive => (_state & State.BeginRead) == State.BeginRead;

[Flags]
internal enum State
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does Pipe pack better if this is a byte size?

internal enum State : byte

{
BeginRead = 1,
BeginReadTenative = 2,
EndRead = 4,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need EndRead state? The only check it is used for can be done via checking for BeginRead

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have extremely weird behavior here.

  • If you call TryRead and that returns false, then you call AdvanceTo it's supposed to work. In this case, nothing is set. This might be the one case that isn't possible to represent without a state. Just checking for the absence of BeginRead isn't enough.

Copy link
Member Author

@davidfowl davidfowl Dec 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just looked at this again, here's the state machine:


BeginRead()
EndRead()

OK

BeginReadTentative()
EndRead()

OK

EndRead() 

OK

BeginReadTentative()
BeginRead()

OK

BeginRead()
BeginRead() // Throws already reading

BeginRead()
BeginReadTentative() // Throws already reading

EndRead()
EndRead() // Throws no reading operation

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is a single EndRead() without beginread ok?

src/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.cs Outdated Show resolved Hide resolved
src/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.cs Outdated Show resolved Hide resolved
src/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.cs Outdated Show resolved Hide resolved
}

_state &= ~State.EndRead;
_state |= State.BeginReadTenative;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just get rid of the BeginReadTenative [sic] state entirely. The only place it's ever referenced is in EndRead() when it's unset. Nothing ever actually checks whether the state is set or not.

You should leave the BeginReadTentative() method in order to throw if BeginRead is set end to unset the EndRead state, but the state itself can be removed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out that isn't quite true. Look at the state diagram here https://github.com/dotnet/corefx/pull/33811/files#r238908068

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. You could get rid of the EndRead state or the ReadingTentative state, but not both.

@davidfowl
Copy link
Member Author

🆙📅

@@ -423,7 +383,7 @@ internal void AdvanceReader(in SequencePosition consumed, in SequencePosition ex
AdvanceReader((BufferSegment)consumed.GetObject(), consumed.GetInteger(), (BufferSegment)examined.GetObject(), examined.GetInteger());
}

internal void AdvanceReader(BufferSegment consumedSegment, int consumedIndex, BufferSegment examinedSegment, int examinedIndex)
private void AdvanceReader(BufferSegment consumedSegment, int consumedIndex, BufferSegment examinedSegment, int examinedIndex)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why private?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nobody calls it outside of this class

@davidfowl davidfowl merged commit 07d1bb7 into master Dec 5, 2018
jlennox pushed a commit to jlennox/corefx that referenced this pull request Dec 16, 2018
- Only clear the writing head when the list is empty.
- Commit just updates the reading tail (renamed the commit head).
@davidfowl davidfowl deleted the davidfowl/simplify-alloc branch December 19, 2018 14:29
@karelz karelz added this to the 3.0 milestone Dec 21, 2018
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
- Only clear the writing head when the list is empty.
- Commit just updates the reading tail (renamed the commit head).



Commit migrated from dotnet/corefx@07d1bb7
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants