AvailableMemory = arrayPoolBuffer;
}
- public void SetUnownedMemory(Memory<byte> memory)
- {
- AvailableMemory = memory;
- }
-
public void ResetMemory()
{
if (_memoryOwner is IMemoryOwner<byte> owner)
{
owner.Dispose();
}
- else if (_memoryOwner is byte[] array)
+ else
{
- ArrayPool<byte>.Shared.Return(array);
+ byte[] poolArray = (byte[])_memoryOwner;
+ ArrayPool<byte>.Shared.Return(poolArray);
}
// Order of below field clears is significant as it clears in a sequential order
{
BufferSegment newSegment = CreateSegmentUnsynchronized();
- if (_pool is null)
+ if (_pool is null || sizeHint > _pool.MaxBufferSize)
{
// Use the array pool
- newSegment.SetOwnedMemory(ArrayPool<byte>.Shared.Rent(GetSegmentSize(sizeHint)));
- }
- else if (sizeHint <= _pool.MaxBufferSize)
- {
- // Use the specified pool if it fits
- newSegment.SetOwnedMemory(_pool.Rent(GetSegmentSize(sizeHint, _pool.MaxBufferSize)));
+ int sizeToRequest = GetSegmentSize(sizeHint);
+ newSegment.SetOwnedMemory(ArrayPool<byte>.Shared.Rent(sizeToRequest));
}
else
{
- // We can't use the pool so allocate an array
- newSegment.SetUnownedMemory(new byte[sizeHint]);
+ // Use the specified pool as it fits
+ newSegment.SetOwnedMemory(_pool.Rent(GetSegmentSize(sizeHint, _pool.MaxBufferSize)));
}
_writingHeadMemory = newSegment.AvailableMemory;
private int _tailBytesBuffered;
private int _bytesBuffered;
- private MemoryPool<byte> _pool;
+ private readonly MemoryPool<byte> _pool;
private CancellationTokenSource _internalTokenSource;
private bool _isCompleted;
- private object _lockObject = new object();
+ private readonly object _lockObject = new object();
private BufferSegmentStack _bufferSegmentPool;
- private bool _leaveOpen;
+ private readonly bool _leaveOpen;
private CancellationTokenSource InternalTokenSource
{
{
BufferSegment newSegment = CreateSegmentUnsynchronized();
- if (_pool is null)
+ if (_pool is null || sizeHint > _pool.MaxBufferSize)
{
// Use the array pool
- newSegment.SetOwnedMemory(ArrayPool<byte>.Shared.Rent(GetSegmentSize(sizeHint)));
- }
- else if (sizeHint <= _pool.MaxBufferSize)
- {
- // Use the specified pool if it fits
- newSegment.SetOwnedMemory(_pool.Rent(GetSegmentSize(sizeHint, _pool.MaxBufferSize)));
+ int sizeToRequest = GetSegmentSize(sizeHint);
+ newSegment.SetOwnedMemory(ArrayPool<byte>.Shared.Rent(sizeToRequest));
}
else
{
- // We can't use the pool so allocate an array
- newSegment.SetUnownedMemory(new byte[sizeHint]);
+ // Use the specified pool as it fits
+ newSegment.SetOwnedMemory(_pool.Rent(GetSegmentSize(sizeHint, _pool.MaxBufferSize)));
}
_tailMemory = newSegment.AvailableMemory;
Assert.Same(startSegment, endSegment);
- // Null owner implies that the buffer is allocated and wasn't rented from the pool
- Assert.Null(startSegment.MemoryOwner);
+ // Check owner is array rather than a different type
+ Assert.IsType<byte[]>(startSegment.MemoryOwner);
pipe.Reader.AdvanceTo(result.Buffer.End);
pipe.Reader.Complete();
}
[Fact]
- public void GetMemoryBiggerThanPoolSizeAllocatesUnpooledArray()
+ public void GetMemoryBiggerThanPoolSizeAllocatesArrayPoolArray()
{
using (var pool = new DisposeTrackingBufferPool())
{
var options = new StreamPipeWriterOptions(pool);
PipeWriter writer = PipeWriter.Create(stream, options);
Memory<byte> memory = writer.GetMemory(pool.MaxBufferSize + 1);
-
- Assert.Equal(pool.MaxBufferSize + 1, memory.Length);
+ Assert.True(memory.Length > pool.MaxBufferSize + 1);
Assert.Equal(0, pool.CurrentlyRentedBlocks);
Assert.Equal(0, pool.DisposedBlocks);