diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Http/Connection.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Http/Connection.cs
index 814da8143b..add23c4389 100644
--- a/src/Microsoft.AspNetCore.Server.Kestrel/Http/Connection.cs
+++ b/src/Microsoft.AspNetCore.Server.Kestrel/Http/Connection.cs
@@ -253,7 +253,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
var result = _rawSocketInput.IncomingStart();
return handle.Libuv.buf_init(
- result.Pin() + result.End,
+ result.DataArrayPtr + result.End,
result.Data.Offset + result.Data.Count - result.End);
}
diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Http/SocketOutput.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Http/SocketOutput.cs
index f424a7531c..5db2fb3ebc 100644
--- a/src/Microsoft.AspNetCore.Server.Kestrel/Http/SocketOutput.cs
+++ b/src/Microsoft.AspNetCore.Server.Kestrel/Http/SocketOutput.cs
@@ -684,14 +684,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
var end = _lockedEnd.Block;
if (block == end)
{
- end.Unpin();
return;
}
while (block.Next != end)
{
block = block.Next;
- block.Unpin();
}
block.Next = null;
@@ -705,7 +703,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
var returnBlock = block;
block = block.Next;
- returnBlock.Unpin();
returnBlock.Pool.Return(returnBlock);
}
}
diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/MemoryPool.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/MemoryPool.cs
index d5a4e59b7e..6fd37f8a9c 100644
--- a/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/MemoryPool.cs
+++ b/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/MemoryPool.cs
@@ -63,24 +63,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
///
/// Called to take a block from the pool.
///
- /// The block returned must be at least this size. It may be larger than this minimum size, and if so,
- /// the caller may write to the block's entire size rather than being limited to the minumumSize requested.
/// The block that is reserved for the called. It must be passed to Return when it is no longer being used.
- public MemoryPoolBlock Lease(int minimumSize = MaxPooledBlockLength)
+ public MemoryPoolBlock Lease()
{
- if (minimumSize > _blockLength)
- {
- // The requested minimumSize is actually larger then the usable memory of a single block.
- // Because this is the degenerate case, a one-time-use byte[] array and tracking object are allocated.
- // When this block tracking object is returned it is not added to the pool - instead it will be
- // allowed to be garbage collected normally.
- return MemoryPoolBlock.Create(
- new ArraySegment(new byte[minimumSize]),
- dataPtr: IntPtr.Zero,
- pool: this,
- slab: null);
- }
-
MemoryPoolBlock block;
if (_blocks.TryDequeue(out block))
{
diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/MemoryPoolBlock.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/MemoryPoolBlock.cs
index 25cab8c4f4..3badd57fce 100644
--- a/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/MemoryPoolBlock.cs
+++ b/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/MemoryPoolBlock.cs
@@ -11,18 +11,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
///
public class MemoryPoolBlock
{
- ///
- /// If this block represents a one-time-use memory object, this GCHandle will hold that memory object at a fixed address
- /// so it can be used in native operations.
- ///
- private GCHandle _pinHandle;
-
///
/// Native address of the first byte of this block's Data memory. It is null for one-time-use memory, or copied from
/// the Slab's ArrayPtr for a slab-block segment. The byte it points to corresponds to Data.Array[0], and in practice you will always
- /// use the _dataArrayPtr + Start or _dataArrayPtr + End, which point to the start of "active" bytes, or point to just after the "active" bytes.
+ /// use the DataArrayPtr + Start or DataArrayPtr + End, which point to the start of "active" bytes, or point to just after the "active" bytes.
///
- private IntPtr _dataArrayPtr;
+ public readonly IntPtr DataArrayPtr;
+
+ internal unsafe readonly byte* DataFixedPtr;
///
/// The array segment describing the range of memory this block is tracking. The caller which has leased this block may only read and
@@ -33,8 +29,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
///
/// This object cannot be instantiated outside of the static Create method
///
- protected MemoryPoolBlock()
+ unsafe protected MemoryPoolBlock(IntPtr dataArrayPtr)
{
+ DataArrayPtr = dataArrayPtr;
+ DataFixedPtr = (byte*)dataArrayPtr.ToPointer();
}
///
@@ -76,20 +74,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
~MemoryPoolBlock()
{
- Debug.Assert(!_pinHandle.IsAllocated, "Ad-hoc memory block wasn't unpinned");
Debug.Assert(Slab == null || !Slab.IsActive, "Block being garbage collected instead of returned to pool");
- if (_pinHandle.IsAllocated)
- {
- // if this is a one-time-use block, ensure that the GCHandle does not leak
- _pinHandle.Free();
- }
-
if (Slab != null && Slab.IsActive)
{
- Pool.Return(new MemoryPoolBlock
+ Pool.Return(new MemoryPoolBlock(DataArrayPtr)
{
- _dataArrayPtr = _dataArrayPtr,
Data = Data,
Pool = Pool,
Slab = Slab,
@@ -97,49 +87,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
}
}
- ///
- /// Called to ensure that a block is pinned, and return the pointer to the native address
- /// of the first byte of this block's Data memory. Arriving data is read into Pin() + End.
- /// Outgoing data is read from Pin() + Start.
- ///
- ///
- public IntPtr Pin()
- {
- Debug.Assert(!_pinHandle.IsAllocated);
-
- if (_dataArrayPtr != IntPtr.Zero)
- {
- // this is a slab managed block - use the native address of the slab which is always locked
- return _dataArrayPtr;
- }
- else
- {
- // this is one-time-use memory - lock the managed memory until Unpin is called
- _pinHandle = GCHandle.Alloc(Data.Array, GCHandleType.Pinned);
- return _pinHandle.AddrOfPinnedObject();
- }
- }
-
- public void Unpin()
- {
- if (_dataArrayPtr == IntPtr.Zero)
- {
- // this is one-time-use memory - unlock the managed memory
- Debug.Assert(_pinHandle.IsAllocated);
- _pinHandle.Free();
- }
- }
-
- public static MemoryPoolBlock Create(
+ internal static MemoryPoolBlock Create(
ArraySegment data,
IntPtr dataPtr,
MemoryPool pool,
MemoryPoolSlab slab)
{
- return new MemoryPoolBlock
+ return new MemoryPoolBlock(dataPtr)
{
Data = data,
- _dataArrayPtr = dataPtr,
Pool = pool,
Slab = slab,
Start = data.Offset,
diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/MemoryPoolIterator.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/MemoryPoolIterator.cs
index 286862ce4b..0fcfe7f434 100644
--- a/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/MemoryPoolIterator.cs
+++ b/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/MemoryPoolIterator.cs
@@ -175,10 +175,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
}
else if (_block.End - _index >= sizeof(long))
{
- fixed (byte* ptr = &_block.Array[_index])
- {
- return *(long*)(ptr);
- }
+ return *(long*)(_block.DataFixedPtr + _index);
}
else if (_block.Next == null)
{
@@ -194,17 +191,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
return -1;
}
- long blockLong;
- fixed (byte* ptr = &_block.Array[_block.End - sizeof(long)])
- {
- blockLong = *(long*)(ptr);
- }
+ var blockLong = *(long*)(_block.DataFixedPtr + _block.End - sizeof(long));
- long nextLong;
- fixed (byte* ptr = &_block.Next.Array[_block.Next.Start])
- {
- nextLong = *(long*)(ptr);
- }
+ var nextLong = *(long*)(_block.Next.DataFixedPtr + _block.Next.Start);
return (blockLong >> (sizeof(long) - blockBytes) * 8) | (nextLong << (sizeof(long) - nextBytes) * 8);
}
@@ -266,22 +255,20 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
#if !DEBUG
}
#endif
- fixed (byte* ptr = &block.Array[index])
+
+ var pCurrent = (block.DataFixedPtr + index);
+ var pEnd = pCurrent + following;
+ do
{
- var pCurrent = ptr;
- var pEnd = pCurrent + following;
- do
+ if (*pCurrent == byte0)
{
- if (*pCurrent == byte0)
- {
- _block = block;
- _index = index;
- return byte0;
- }
- pCurrent++;
- index++;
- } while (pCurrent < pEnd);
- }
+ _block = block;
+ _index = index;
+ return byte0;
+ }
+ pCurrent++;
+ index++;
+ } while (pCurrent < pEnd);
following = 0;
break;
@@ -367,28 +354,25 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
#if !DEBUG
}
#endif
- fixed (byte* ptr = &block.Array[index])
+ var pCurrent = (block.DataFixedPtr + index);
+ var pEnd = pCurrent + following;
+ do
{
- var pCurrent = ptr;
- var pEnd = pCurrent + following;
- do
+ if (*pCurrent == byte0)
{
- if (*pCurrent == byte0)
- {
- _block = block;
- _index = index;
- return byte0;
- }
- if (*pCurrent == byte1)
- {
- _block = block;
- _index = index;
- return byte1;
- }
- pCurrent++;
- index++;
- } while (pCurrent != pEnd);
- }
+ _block = block;
+ _index = index;
+ return byte0;
+ }
+ if (*pCurrent == byte1)
+ {
+ _block = block;
+ _index = index;
+ return byte1;
+ }
+ pCurrent++;
+ index++;
+ } while (pCurrent != pEnd);
following = 0;
break;
@@ -502,34 +486,31 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
#if !DEBUG
}
#endif
- fixed (byte* ptr = &block.Array[index])
+ var pCurrent = (block.DataFixedPtr + index);
+ var pEnd = pCurrent + following;
+ do
{
- var pCurrent = ptr;
- var pEnd = pCurrent + following;
- do
+ if (*pCurrent == byte0)
{
- if (*pCurrent == byte0)
- {
- _block = block;
- _index = index;
- return byte0;
- }
- if (*pCurrent == byte1)
- {
- _block = block;
- _index = index;
- return byte1;
- }
- if (*pCurrent == byte2)
- {
- _block = block;
- _index = index;
- return byte2;
- }
- pCurrent++;
- index++;
- } while (pCurrent != pEnd);
- }
+ _block = block;
+ _index = index;
+ return byte0;
+ }
+ if (*pCurrent == byte1)
+ {
+ _block = block;
+ _index = index;
+ return byte1;
+ }
+ if (*pCurrent == byte2)
+ {
+ _block = block;
+ _index = index;
+ return byte2;
+ }
+ pCurrent++;
+ index++;
+ } while (pCurrent != pEnd);
following = 0;
break;
@@ -808,30 +789,25 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
bytesLeftInBlockMinusSpan = bytesLeftInBlock - 3;
}
- fixed (byte* pOutput = &block.Data.Array[block.End])
+ var output = (block.DataFixedPtr + block.End);
+ var copied = 0;
+ for (; input < inputEndMinusSpan && copied < bytesLeftInBlockMinusSpan; copied += 4)
{
- //this line is needed to allow output be an register var
- var output = pOutput;
-
- var copied = 0;
- for (; input < inputEndMinusSpan && copied < bytesLeftInBlockMinusSpan; copied += 4)
- {
- *(output) = (byte)*(input);
- *(output + 1) = (byte)*(input + 1);
- *(output + 2) = (byte)*(input + 2);
- *(output + 3) = (byte)*(input + 3);
- output += 4;
- input += 4;
- }
- for (; input < inputEnd && copied < bytesLeftInBlock; copied++)
- {
- *(output++) = (byte)*(input++);
- }
-
- blockIndex += copied;
- bytesLeftInBlockMinusSpan -= copied;
- bytesLeftInBlock -= copied;
+ *(output) = (byte)*(input);
+ *(output + 1) = (byte)*(input + 1);
+ *(output + 2) = (byte)*(input + 2);
+ *(output + 3) = (byte)*(input + 3);
+ output += 4;
+ input += 4;
}
+ for (; input < inputEnd && copied < bytesLeftInBlock; copied++)
+ {
+ *(output++) = (byte)*(input++);
+ }
+
+ blockIndex += copied;
+ bytesLeftInBlockMinusSpan -= copied;
+ bytesLeftInBlock -= copied;
}
}
diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/MemoryPoolIteratorExtensions.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/MemoryPoolIteratorExtensions.cs
index 1f9b3dcd7a..f17dab1394 100644
--- a/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/MemoryPoolIteratorExtensions.cs
+++ b/src/Microsoft.AspNetCore.Server.Kestrel/Infrastructure/MemoryPoolIteratorExtensions.cs
@@ -116,9 +116,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
if (following > 0)
{
- fixed (byte* blockStart = block.Array)
- {
- var input = blockStart + inputOffset;
+ var input = block.DataFixedPtr + inputOffset;
var i = 0;
while (i < following - 11)
{
@@ -167,9 +165,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
output++;
input++;
}
-
+
remaining -= following;
- }
}
if (remaining == 0)
diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Networking/UvWriteReq.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Networking/UvWriteReq.cs
index bf088950a5..bc776767a6 100644
--- a/src/Microsoft.AspNetCore.Server.Kestrel/Networking/UvWriteReq.cs
+++ b/src/Microsoft.AspNetCore.Server.Kestrel/Networking/UvWriteReq.cs
@@ -70,7 +70,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Networking
// create and pin each segment being written
pBuffers[index] = Libuv.buf_init(
- block.Pin() + blockStart,
+ block.DataArrayPtr + blockStart,
blockEnd - blockStart);
block = block.Next;
@@ -89,7 +89,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Networking
var block = start.Block;
for (var index = 0; index < nBuffers; index++)
{
- block.Unpin();
block = block.Next;
}
diff --git a/test/Microsoft.AspNetCore.Server.KestrelTests/AsciiDecoder.cs b/test/Microsoft.AspNetCore.Server.KestrelTests/AsciiDecoder.cs
index 10e95d2e56..634efc65db 100644
--- a/test/Microsoft.AspNetCore.Server.KestrelTests/AsciiDecoder.cs
+++ b/test/Microsoft.AspNetCore.Server.KestrelTests/AsciiDecoder.cs
@@ -14,23 +14,27 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
private void FullByteRangeSupported()
{
var byteRange = Enumerable.Range(0, 256).Select(x => (byte)x).ToArray();
-
- var mem = MemoryPoolBlock.Create(new ArraySegment(byteRange), IntPtr.Zero, null, null);
- mem.End = byteRange.Length;
-
- var begin = mem.GetIterator();
- var end = GetIterator(begin, byteRange.Length);
-
- var s = begin.GetAsciiString(end);
-
- Assert.Equal(s.Length, byteRange.Length);
-
- for (var i = 0; i < byteRange.Length; i++)
+ using (var pool = new MemoryPool())
{
- var sb = (byte)s[i];
- var b = byteRange[i];
+ var mem = pool.Lease();
+ mem.GetIterator().CopyFrom(byteRange);
- Assert.Equal(sb, b);
+ var begin = mem.GetIterator();
+ var end = GetIterator(begin, byteRange.Length);
+
+ var s = begin.GetAsciiString(end);
+
+ Assert.Equal(s.Length, byteRange.Length);
+
+ for (var i = 0; i < byteRange.Length; i++)
+ {
+ var sb = (byte)s[i];
+ var b = byteRange[i];
+
+ Assert.Equal(sb, b);
+ }
+
+ pool.Return(mem);
}
}
@@ -44,32 +48,40 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
.Concat(byteRange)
.ToArray();
- var mem0 = MemoryPoolBlock.Create(new ArraySegment(byteRange), IntPtr.Zero, null, null);
- var mem1 = MemoryPoolBlock.Create(new ArraySegment(byteRange), IntPtr.Zero, null, null);
- var mem2 = MemoryPoolBlock.Create(new ArraySegment(byteRange), IntPtr.Zero, null, null);
- var mem3 = MemoryPoolBlock.Create(new ArraySegment(byteRange), IntPtr.Zero, null, null);
- mem0.End = byteRange.Length;
- mem1.End = byteRange.Length;
- mem2.End = byteRange.Length;
- mem3.End = byteRange.Length;
-
- mem0.Next = mem1;
- mem1.Next = mem2;
- mem2.Next = mem3;
-
- var begin = mem0.GetIterator();
- var end = GetIterator(begin, expectedByteRange.Length);
-
- var s = begin.GetAsciiString(end);
-
- Assert.Equal(s.Length, expectedByteRange.Length);
-
- for (var i = 0; i < expectedByteRange.Length; i++)
+ using (var pool = new MemoryPool())
{
- var sb = (byte)s[i];
- var b = expectedByteRange[i];
+ var mem0 = pool.Lease();
+ var mem1 = pool.Lease();
+ var mem2 = pool.Lease();
+ var mem3 = pool.Lease();
+ mem0.GetIterator().CopyFrom(byteRange);
+ mem1.GetIterator().CopyFrom(byteRange);
+ mem2.GetIterator().CopyFrom(byteRange);
+ mem3.GetIterator().CopyFrom(byteRange);
- Assert.Equal(sb, b);
+ mem0.Next = mem1;
+ mem1.Next = mem2;
+ mem2.Next = mem3;
+
+ var begin = mem0.GetIterator();
+ var end = GetIterator(begin, expectedByteRange.Length);
+
+ var s = begin.GetAsciiString(end);
+
+ Assert.Equal(s.Length, expectedByteRange.Length);
+
+ for (var i = 0; i < expectedByteRange.Length; i++)
+ {
+ var sb = (byte)s[i];
+ var b = expectedByteRange[i];
+
+ Assert.Equal(sb, b);
+ }
+
+ pool.Return(mem0);
+ pool.Return(mem1);
+ pool.Return(mem2);
+ pool.Return(mem3);
}
}
@@ -78,27 +90,45 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
{
var byteRange = Enumerable.Range(0, 16384 + 64).Select(x => (byte)x).ToArray();
var expectedByteRange = byteRange.Concat(byteRange).ToArray();
-
- var mem0 = MemoryPoolBlock.Create(new ArraySegment(byteRange), IntPtr.Zero, null, null);
- var mem1 = MemoryPoolBlock.Create(new ArraySegment(byteRange), IntPtr.Zero, null, null);
- mem0.End = byteRange.Length;
- mem1.End = byteRange.Length;
-
- mem0.Next = mem1;
-
- var begin = mem0.GetIterator();
- var end = GetIterator(begin, expectedByteRange.Length);
-
- var s = begin.GetAsciiString(end);
-
- Assert.Equal(s.Length, expectedByteRange.Length);
-
- for (var i = 0; i < expectedByteRange.Length; i++)
+ using (var pool = new MemoryPool())
{
- var sb = (byte)s[i];
- var b = expectedByteRange[i];
+ var mem0 = pool.Lease();
+ var mem1 = pool.Lease();
+ mem0.GetIterator().CopyFrom(byteRange);
+ mem1.GetIterator().CopyFrom(byteRange);
- Assert.Equal(sb, b);
+ var lastBlock = mem0;
+ while (lastBlock.Next != null)
+ {
+ lastBlock = lastBlock.Next;
+ }
+ lastBlock.Next = mem1;
+
+ var begin = mem0.GetIterator();
+ var end = GetIterator(begin, expectedByteRange.Length);
+
+ var s = begin.GetAsciiString(end);
+
+ Assert.Equal(expectedByteRange.Length, s.Length);
+
+ for (var i = 0; i < expectedByteRange.Length; i++)
+ {
+ var sb = (byte)s[i];
+ var b = expectedByteRange[i];
+
+ Assert.Equal(sb, b);
+ }
+
+ var block = mem0;
+ while (block != null)
+ {
+ var returnBlock = block;
+ block = block.Next;
+ pool.Return(returnBlock);
+ }
+
+ pool.Return(mem0);
+ pool.Return(mem1);
}
}
diff --git a/test/Microsoft.AspNetCore.Server.KestrelTests/MemoryPoolBlockTests.cs b/test/Microsoft.AspNetCore.Server.KestrelTests/MemoryPoolBlockTests.cs
index 73bb3b2ef8..748a0ecf34 100644
--- a/test/Microsoft.AspNetCore.Server.KestrelTests/MemoryPoolBlockTests.cs
+++ b/test/Microsoft.AspNetCore.Server.KestrelTests/MemoryPoolBlockTests.cs
@@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
{
using (var pool = new MemoryPool())
{
- var block = pool.Lease(256);
+ var block = pool.Lease();
foreach (var ch in Enumerable.Range(0, 256).Select(x => (byte)x))
{
block.Array[block.End++] = ch;
@@ -63,9 +63,9 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
using (var pool = new MemoryPool())
{
- var block1 = pool.Lease(256);
- var block2 = block1.Next = pool.Lease(256);
- var block3 = block2.Next = pool.Lease(256);
+ var block1 = pool.Lease();
+ var block2 = block1.Next = pool.Lease();
+ var block3 = block2.Next = pool.Lease();
foreach (var ch in Enumerable.Range(0, 34).Select(x => (byte)x))
{
@@ -123,7 +123,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
{
using (var pool = new MemoryPool())
{
- var block = pool.Lease(256);
+ var block = pool.Lease();
block.End += 256;
TestAllLengths(block, 256);
pool.Return(block);
@@ -132,7 +132,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
for (var fragment = 0; fragment < 256; fragment += 4)
{
var next = block;
- block = pool.Lease(4);
+ block = pool.Lease();
block.Next = next;
block.End += 4;
}
@@ -168,8 +168,8 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
{
using (var pool = new MemoryPool())
{
- var block1 = pool.Lease(256);
- var block2 = block1.Next = pool.Lease(256);
+ var block1 = pool.Lease();
+ var block2 = block1.Next = pool.Lease();
block1.End += 100;
block2.End += 200;
@@ -209,8 +209,8 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
{
using (var pool = new MemoryPool())
{
- var block1 = pool.Lease(128);
- var block2 = block1.Next = pool.Lease(128);
+ var block1 = pool.Lease();
+ var block2 = block1.Next = pool.Lease();
for (int i = 0; i < 128; i++)
{
@@ -247,7 +247,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
{
using (var pool = new MemoryPool())
{
- var block1 = pool.Lease(128);
+ var block1 = pool.Lease();
var start = block1.GetIterator();
var end = start;
var bufferSize = block1.Data.Count * 3;
@@ -289,10 +289,10 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
{
using (var pool = new MemoryPool())
{
- var block1 = pool.Lease(128);
- var block2 = block1.Next = pool.Lease(128);
- var block3 = block2.Next = pool.Lease(128);
- var block4 = block3.Next = pool.Lease(128);
+ var block1 = pool.Lease();
+ var block2 = block1.Next = pool.Lease();
+ var block3 = block2.Next = pool.Lease();
+ var block4 = block3.Next = pool.Lease();
// There is no data in block2 or block4, so IsEnd should be true after 256 bytes are read.
block1.End += 128;
diff --git a/test/Microsoft.AspNetCore.Server.KestrelTests/MemoryPoolIteratorTests.cs b/test/Microsoft.AspNetCore.Server.KestrelTests/MemoryPoolIteratorTests.cs
index 18fdeb5afd..834c99baad 100644
--- a/test/Microsoft.AspNetCore.Server.KestrelTests/MemoryPoolIteratorTests.cs
+++ b/test/Microsoft.AspNetCore.Server.KestrelTests/MemoryPoolIteratorTests.cs
@@ -82,7 +82,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
[InlineData("/localhost:5000/PATH/PATH2/ HTTP/1.1", " %?", ' ', 27)]
public void MemorySeek(string raw, string search, char expectResult, int expectIndex)
{
- var block = _pool.Lease(256);
+ var block = _pool.Lease();
var chars = raw.ToCharArray().Select(c => (byte)c).ToArray();
Buffer.BlockCopy(chars, 0, block.Array, block.Start, chars.Length);
block.End += chars.Length;
@@ -126,7 +126,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
var blocks = new MemoryPoolBlock[4];
for (var i = 0; i < 4; ++i)
{
- blocks[i] = _pool.Lease(16);
+ blocks[i] = _pool.Lease();
blocks[i].End += 16;
for (var j = 0; j < blocks.Length; ++j)
diff --git a/test/Microsoft.AspNetCore.Server.KestrelTests/MultipleLoopTests.cs b/test/Microsoft.AspNetCore.Server.KestrelTests/MultipleLoopTests.cs
index c5b8c30c5b..af50bba928 100644
--- a/test/Microsoft.AspNetCore.Server.KestrelTests/MultipleLoopTests.cs
+++ b/test/Microsoft.AspNetCore.Server.KestrelTests/MultipleLoopTests.cs
@@ -64,11 +64,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
var writeRequest = new UvWriteReq(new KestrelTrace(new TestKestrelTrace()));
writeRequest.Init(loop);
- var block = MemoryPoolBlock.Create(
- new ArraySegment(new byte[] { 1, 2, 3, 4 }),
- dataPtr: IntPtr.Zero,
- pool: null,
- slab: null);
+
+ var pool = new MemoryPool();
+ var block = pool.Lease();
+ block.GetIterator().CopyFrom(new ArraySegment(new byte[] { 1, 2, 3, 4 }));
+
var start = new MemoryPoolIterator(block, 0);
var end = new MemoryPoolIterator(block, block.Data.Count);
writeRequest.Write(
@@ -81,7 +81,8 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
writeRequest.Dispose();
serverConnectionPipe.Dispose();
serverListenPipe.Dispose();
- block.Unpin();
+ pool.Return(block);
+ pool.Dispose();
},
null);
diff --git a/test/Microsoft.AspNetCore.Server.KestrelTests/NetworkingTests.cs b/test/Microsoft.AspNetCore.Server.KestrelTests/NetworkingTests.cs
index c299331818..dd5c5044fc 100644
--- a/test/Microsoft.AspNetCore.Server.KestrelTests/NetworkingTests.cs
+++ b/test/Microsoft.AspNetCore.Server.KestrelTests/NetworkingTests.cs
@@ -177,12 +177,10 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
for (var x = 0; x < 2; x++)
{
var req = new UvWriteReq(new KestrelTrace(new TestKestrelTrace()));
- req.Init(loop);
- var block = MemoryPoolBlock.Create(
- new ArraySegment(new byte[] { 65, 66, 67, 68, 69 }),
- dataPtr: IntPtr.Zero,
- pool: null,
- slab: null);
+ req.Init(loop); var pool = new MemoryPool();
+ var block = pool.Lease();
+ block.GetIterator().CopyFrom(new ArraySegment(new byte[] { 65, 66, 67, 68, 69 }));
+
var start = new MemoryPoolIterator(block, 0);
var end = new MemoryPoolIterator(block, block.Data.Count);
req.Write(
@@ -192,7 +190,8 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
1,
(_1, _2, _3, _4) =>
{
- block.Unpin();
+ pool.Return(block);
+ pool.Dispose();
},
null);
}
diff --git a/test/Microsoft.AspNetCore.Server.KestrelTests/UrlPathDecoder.cs b/test/Microsoft.AspNetCore.Server.KestrelTests/UrlPathDecoder.cs
index 711297fd95..31e1ccdbc9 100644
--- a/test/Microsoft.AspNetCore.Server.KestrelTests/UrlPathDecoder.cs
+++ b/test/Microsoft.AspNetCore.Server.KestrelTests/UrlPathDecoder.cs
@@ -14,13 +14,27 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
[Fact]
public void Empty()
{
- PositiveAssert(string.Empty, string.Empty);
+ using (var pool = new MemoryPool())
+ {
+ var mem = pool.Lease();
+
+ PositiveAssert(mem, string.Empty, string.Empty);
+
+ pool.Return(mem);
+ }
}
[Fact]
public void WhiteSpace()
{
- PositiveAssert(" ", " ");
+ using (var pool = new MemoryPool())
+ {
+ var mem = pool.Lease();
+
+ PositiveAssert(mem, " ", " ");
+
+ pool.Return(mem);
+ }
}
[Theory]
@@ -30,7 +44,14 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
[InlineData("/", "/")]
public void NormalCases(string raw, string expect)
{
- PositiveAssert(raw, expect);
+ using (var pool = new MemoryPool())
+ {
+ var mem = pool.Lease();
+
+ PositiveAssert(mem, raw, expect);
+
+ pool.Return(mem);
+ }
}
[Theory]
@@ -39,7 +60,14 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
[InlineData("/foo%2F%20bar", "/foo%2F bar")]
public void SkipForwardSlash(string raw, string expect)
{
- PositiveAssert(raw, expect);
+ using (var pool = new MemoryPool())
+ {
+ var mem = pool.Lease();
+
+ PositiveAssert(mem, raw, expect);
+
+ pool.Return(mem);
+ }
}
[Theory]
@@ -60,7 +88,14 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
[InlineData("%20", " ")]
public void ValidUTF8(string raw, string expect)
{
- PositiveAssert(raw, expect);
+ using (var pool = new MemoryPool())
+ {
+ var mem = pool.Lease();
+
+ PositiveAssert(mem, raw, expect);
+
+ pool.Return(mem);
+ }
}
[Theory]
@@ -68,7 +103,14 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
[InlineData("%E6%88%91%E8%87%AA%E6%A8%AA%E5%88%80%E5%90%91%E5%A4%A9%E7%AC%91%E5%8E%BB%E7%95%99%E8%82%9D%E8%83%86%E4%B8%A4%E6%98%86%E4%BB%91", "我自横刀向天笑去留肝胆两昆仑")]
public void Internationalized(string raw, string expect)
{
- PositiveAssert(raw, expect);
+ using (var pool = new MemoryPool())
+ {
+ var mem = pool.Lease();
+
+ PositiveAssert(mem, raw, expect);
+
+ pool.Return(mem);
+ }
}
[Theory]
@@ -92,7 +134,14 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
[InlineData("%C0%32%A4", "%C02%A4")]
public void InvalidUTF8(string raw, string expect)
{
- PositiveAssert(raw, expect);
+ using (var pool = new MemoryPool())
+ {
+ var mem = pool.Lease();
+
+ PositiveAssert(mem, raw, expect);
+
+ pool.Return(mem);
+ }
}
[Theory]
@@ -110,21 +159,27 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
[InlineData("%C2%B5%40%C3%9F%C3%B6%C3%A4%C3%BC%C3%A0%C3%A1", 44, "µ@ßöäüà%C3%A", 12)]
public void DecodeWithBoundary(string raw, int rawLength, string expect, int expectLength)
{
- var begin = BuildSample(raw);
- var end = GetIterator(begin, rawLength);
+ using (var pool = new MemoryPool())
+ {
+ var mem = pool.Lease();
- var end2 = UrlPathDecoder.Unescape(begin, end);
- var result = begin.GetUtf8String(end2);
+ var begin = BuildSample(mem, raw);
+ var end = GetIterator(begin, rawLength);
- Assert.Equal(expectLength, result.Length);
- Assert.Equal(expect, result);
+ var end2 = UrlPathDecoder.Unescape(begin, end);
+ var result = begin.GetUtf8String(end2);
+
+ Assert.Equal(expectLength, result.Length);
+ Assert.Equal(expect, result);
+
+ pool.Return(mem);
+ }
}
- private MemoryPoolIterator BuildSample(string data)
+ private MemoryPoolIterator BuildSample(MemoryPoolBlock mem, string data)
{
var store = data.Select(c => (byte)c).ToArray();
- var mem = MemoryPoolBlock.Create(new ArraySegment(store), IntPtr.Zero, null, null);
- mem.End = store.Length;
+ mem.GetIterator().CopyFrom(new ArraySegment(store));
return mem.GetIterator();
}
@@ -140,27 +195,27 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
return result;
}
- private void PositiveAssert(string raw, string expect)
+ private void PositiveAssert(MemoryPoolBlock mem, string raw, string expect)
{
- var begin = BuildSample(raw);
+ var begin = BuildSample(mem, raw);
var end = GetIterator(begin, raw.Length);
var result = UrlPathDecoder.Unescape(begin, end);
Assert.Equal(expect, begin.GetUtf8String(result));
}
- private void PositiveAssert(string raw)
+ private void PositiveAssert(MemoryPoolBlock mem, string raw)
{
- var begin = BuildSample(raw);
+ var begin = BuildSample(mem, raw);
var end = GetIterator(begin, raw.Length);
var result = UrlPathDecoder.Unescape(begin, end);
Assert.NotEqual(raw.Length, begin.GetUtf8String(result).Length);
}
- private void NegativeAssert(string raw)
+ private void NegativeAssert(MemoryPoolBlock mem, string raw)
{
- var begin = BuildSample(raw);
+ var begin = BuildSample(mem, raw);
var end = GetIterator(begin, raw.Length);
var resultEnd = UrlPathDecoder.Unescape(begin, end);