Skip to content
This repository has been archived by the owner on Aug 2, 2023. It is now read-only.

Commit

Permalink
Merge Fix issue where GetPosition might cross outside of ROB
Browse files Browse the repository at this point in the history
  • Loading branch information
pakrym committed Jan 29, 2018
2 parents b5b8dab + f774728 commit fa5e8b0
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,9 @@ private static SequencePosition SeekMultiSegment(IMemoryList<byte> start, int st

memory = memory.Slice(0, currentEnd - currentIndex);
// We would prefer to put cursor in the beginning of next segment
// then past the end of previous one, but only if next exists

// then past the end of previous one, but only if we are not leaving current buffer
if (memory.Length > bytes ||
(memory.Length == bytes && current.Next == null))
(memory.Length == bytes && current == end))
{
result = new SequencePosition(current, currentIndex + (int)bytes);
foundResult = true;
Expand Down
3 changes: 1 addition & 2 deletions src/System.IO.Pipelines/System/IO/Pipelines/Pipe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -407,8 +407,7 @@ internal void Advance(SequencePosition consumed, SequencePosition examined)
// if we are going to return commit head
// we need to check that there is no writing operation that
// might be using tailspace
if (consumed.Index == returnEnd.Length &&
!(_commitHead == returnEnd && _writingHead != null))
if (consumed.Index == returnEnd.Length && _writingHead != returnEnd)
{
var nextBlock = returnEnd.NextSegment;
if (_commitHead == returnEnd)
Expand Down
31 changes: 27 additions & 4 deletions tests/System.Buffers.Primitives.Tests/ReadableBufferFacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,22 +87,22 @@ public void ReadableBufferDoesNotAllowSlicingOutOfRange(Action<ReadOnlyBuffer<by
}

[Fact]
public void ReadableBufferMove_MovesReadCursor()
public void ReadableBufferGetPosition_MovesReadCursor()
{
var buffer = Factory.CreateOfSize(100);
var cursor = buffer.GetPosition(buffer.Start, 65);
Assert.Equal(buffer.Slice(65).Start, cursor);
}

[Fact]
public void ReadableBufferMove_ChecksBounds()
public void ReadableBufferGetPosition_ChecksBounds()
{
var buffer = Factory.CreateOfSize(100);
Assert.Throws<InvalidOperationException>(() => buffer.GetPosition(buffer.Start, 101));
}

[Fact]
public void ReadableBufferMove_DoesNotAlowNegative()
public void ReadableBufferGetPosition_DoesNotAlowNegative()
{
var buffer = Factory.CreateOfSize(20);
Assert.Throws<ArgumentOutOfRangeException>(() => buffer.GetPosition(buffer.Start, -1));
Expand Down Expand Up @@ -140,7 +140,7 @@ public void SegmentStartIsConsideredInBoundsCheck()
}

[Fact]
public void MovePrefersNextSegment()
public void GetPositionPrefersNextSegment()
{
var bufferSegment1 = new BufferSegment();
bufferSegment1.SetMemory(new OwnedArray<byte>(new byte[100]), 49, 99);
Expand All @@ -157,6 +157,29 @@ public void MovePrefersNextSegment()
Assert.Equal(bufferSegment2, c1.Segment);
}

[Fact]
public void GetPositionDoesNotCrossOutsideBuffer()
{
var bufferSegment1 = new BufferSegment();
bufferSegment1.SetMemory(new OwnedArray<byte>(new byte[100]), 0, 100);

var bufferSegment2 = new BufferSegment();
bufferSegment2.SetMemory(new OwnedArray<byte>(new byte[100]), 0, 100);

var bufferSegment3 = new BufferSegment();
bufferSegment3.SetMemory(new OwnedArray<byte>(new byte[100]), 0, 0);

bufferSegment1.SetNext(bufferSegment2);
bufferSegment2.SetNext(bufferSegment3);

var readableBuffer = new ReadOnlyBuffer<byte>(bufferSegment1, 0, bufferSegment2, 100);

var c1 = readableBuffer.GetPosition(readableBuffer.Start, 200);

Assert.Equal(100, c1.Index);
Assert.Equal(bufferSegment2, c1.Segment);
}

[Fact]
public void Create_WorksWithArray()
{
Expand Down
29 changes: 29 additions & 0 deletions tests/System.IO.Pipelines.Tests/PipelineReaderWriterFacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -531,5 +531,34 @@ public async Task AdvanceResetsCommitHeadIndex()
awaitable = _pipe.Reader.ReadAsync();
Assert.False(awaitable.IsCompleted);
}

[Fact]
public async Task AdvanceWithGetPositionCrossingIntoWriteHeadWorks()
{
// Create two blocks
var memory = _pipe.Writer.GetMemory(1);
_pipe.Writer.Advance(memory.Length);
memory = _pipe.Writer.GetMemory(1);
_pipe.Writer.Advance(memory.Length);
await _pipe.Writer.FlushAsync();

// Read single block
var readResult = await _pipe.Reader.ReadAsync();

// Allocate more memory
memory = _pipe.Writer.GetMemory(1);

// Create position that would cross into write head
var buffer = readResult.Buffer;
var position = buffer.GetPosition(buffer.Start, buffer.Length);

// Return everything
_pipe.Reader.AdvanceTo(position);

// Advance writer
_pipe.Writer.Advance(memory.Length);
_pipe.Writer.Commit();
}

}
}

0 comments on commit fa5e8b0

Please sign in to comment.