EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{2E666815-2EDB-464B-9DF6-380BF4789AD4}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.IO.Pipelines.Performance.Tests", "tests\Performance\System.IO.Pipelines.Performance.Tests.csproj", "{66AE57BA-B56C-4A1E-ACA6-7C18431D416B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.IO.Pipelines.PerformanceTests", "tests\Performance\System.IO.Pipelines.PerformanceTests.csproj", "{66AE57BA-B56C-4A1E-ACA6-7C18431D416B}"
ProjectSection(ProjectDependencies) = postProject
{1032D5F6-5AE7-4002-A0E4-FEBEADFEA977} = {1032D5F6-5AE7-4002-A0E4-FEBEADFEA977}
EndProjectSection
{
internal sealed class BufferSegment : ReadOnlySequenceSegment<byte>
{
- private IMemoryOwner<byte> _memoryOwner;
+ private object _memoryOwner;
private BufferSegment _next;
private int _end;
{
_memoryOwner = memoryOwner;
- AvailableMemory = _memoryOwner.Memory;
+ AvailableMemory = memoryOwner.Memory;
+ RunningIndex = 0;
+ End = 0;
+ NextSegment = null;
+ }
+
+ public void SetMemory(byte[] arrayPoolBuffer)
+ {
+ _memoryOwner = arrayPoolBuffer;
+
+ AvailableMemory = arrayPoolBuffer;
RunningIndex = 0;
End = 0;
NextSegment = null;
public void ResetMemory()
{
- _memoryOwner.Dispose();
+ if (_memoryOwner is IMemoryOwner<byte> owner)
+ {
+ owner.Dispose();
+ }
+ else
+ {
+ ArrayPool<byte>.Shared.Return((byte[])_memoryOwner);
+ }
+
_memoryOwner = null;
AvailableMemory = default;
}
- internal IMemoryOwner<byte> MemoryOwner => _memoryOwner;
+ // Exposed for testing
+ internal object MemoryOwner => _memoryOwner;
public Memory<byte> AvailableMemory { get; private set; }
_readerCompletion = default;
_writerCompletion = default;
- _pool = options.Pool;
+ // If we're using the default pool then mark it as null since we're just going to use the
+ // array pool under the covers
+ _pool = options.Pool == MemoryPool<byte>.Shared ? null : options.Pool;
_minimumSegmentSize = options.MinimumSegmentSize;
_pauseWriterThreshold = options.PauseWriterThreshold;
_resumeWriterThreshold = options.ResumeWriterThreshold;
if (_writingHead == null)
{
// We need to allocate memory to write since nobody has written before
- BufferSegment newSegment = CreateSegmentUnsynchronized();
- newSegment.SetMemory(_pool.Rent(GetSegmentSize(sizeHint)));
+ BufferSegment newSegment = AllocateSegment(sizeHint);
// Set all the pointers
_writingHead = _readHead = _readTail = newSegment;
if (bytesLeftInBuffer == 0 || bytesLeftInBuffer < sizeHint)
{
- BufferSegment newSegment = CreateSegmentUnsynchronized();
- newSegment.SetMemory(_pool.Rent(GetSegmentSize(sizeHint)));
+ BufferSegment newSegment = AllocateSegment(sizeHint);
_writingHead.SetNext(newSegment);
_writingHead = newSegment;
}
}
- private int GetSegmentSize(int sizeHint)
+ private BufferSegment AllocateSegment(int sizeHint)
+ {
+ BufferSegment newSegment = CreateSegmentUnsynchronized();
+
+ if (_pool is null)
+ {
+ newSegment.SetMemory(ArrayPool<byte>.Shared.Rent(GetSegmentSize(sizeHint)));
+ }
+ else
+ {
+ newSegment.SetMemory(_pool.Rent(GetSegmentSize(sizeHint, _pool.MaxBufferSize)));
+ }
+
+ return newSegment;
+ }
+
+ private int GetSegmentSize(int sizeHint, int maxBufferSize = int.MaxValue)
{
// First we need to handle case where hint is smaller than minimum segment size
sizeHint = Math.Max(_minimumSegmentSize, sizeHint);
// After that adjust it to fit into pools max buffer size
- var adjustedToMaximumSize = Math.Min(_pool.MaxBufferSize, sizeHint);
+ var adjustedToMaximumSize = Math.Min(maxBufferSize, sizeHint);
return adjustedToMaximumSize;
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Buffers;
using Xunit;
namespace System.IO.Pipelines.Tests
{
Assert.Equal(16384, PipeOptions.Default.ResumeWriterThreshold);
}
+
+ [Fact]
+ public void DefaultPoolIsSetToShared()
+ {
+ Assert.Equal(MemoryPool<byte>.Shared, PipeOptions.Default.Pool);
+ }
}
}