Merge pull request #335 from benaadams/used-pool-array
Consume body without allocating or reading
This commit is contained in:
commit
e3a62ff09f
|
|
@ -85,7 +85,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Filter
|
|||
|
||||
private Task<int> ReadAsync(ArraySegment<byte> buffer)
|
||||
{
|
||||
return _input.ReadAsync(buffer);
|
||||
return _input.ReadAsync(buffer.Array, buffer.Offset, buffer.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -234,10 +234,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
|
||||
await ProduceEnd();
|
||||
|
||||
while (await RequestBody.ReadAsync(_nullBuffer, 0, _nullBuffer.Length) != 0)
|
||||
{
|
||||
// Finish reading the request body in case the app did not.
|
||||
}
|
||||
// Finish reading the request body in case the app did not.
|
||||
await MessageBody.Consume();
|
||||
}
|
||||
|
||||
terminated = !_keepAlive;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,37 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
return result;
|
||||
}
|
||||
|
||||
public async Task Consume(CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
Task<int> result;
|
||||
var send100checked = false;
|
||||
do
|
||||
{
|
||||
result = ReadAsyncImplementation(default(ArraySegment<byte>), cancellationToken);
|
||||
if (!result.IsCompleted)
|
||||
{
|
||||
if (!send100checked)
|
||||
{
|
||||
if (Interlocked.Exchange(ref _send100Continue, 0) == 1)
|
||||
{
|
||||
_context.FrameControl.ProduceContinue();
|
||||
}
|
||||
send100checked = true;
|
||||
}
|
||||
}
|
||||
else if (result.GetAwaiter().GetResult() == 0)
|
||||
{
|
||||
// Completed Task, end of stream
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Completed Task, get next Task rather than await
|
||||
continue;
|
||||
}
|
||||
} while (await result != 0);
|
||||
}
|
||||
|
||||
public abstract Task<int> ReadAsyncImplementation(ArraySegment<byte> buffer, CancellationToken cancellationToken);
|
||||
|
||||
public static MessageBody For(
|
||||
|
|
@ -108,7 +139,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
|
||||
public override Task<int> ReadAsyncImplementation(ArraySegment<byte> buffer, CancellationToken cancellationToken)
|
||||
{
|
||||
return _context.SocketInput.ReadAsync(buffer);
|
||||
return _context.SocketInput.ReadAsync(buffer.Array, buffer.Offset, buffer.Array == null ? 8192 : buffer.Count);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -129,14 +160,13 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
{
|
||||
var input = _context.SocketInput;
|
||||
|
||||
var limit = Math.Min(buffer.Count, _inputLength);
|
||||
var limit = buffer.Array == null ? _inputLength : Math.Min(buffer.Count, _inputLength);
|
||||
if (limit == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var limitedBuffer = new ArraySegment<byte>(buffer.Array, buffer.Offset, limit);
|
||||
var actual = await _context.SocketInput.ReadAsync(limitedBuffer);
|
||||
var actual = await _context.SocketInput.ReadAsync(buffer.Array, buffer.Offset, limit);
|
||||
_inputLength -= actual;
|
||||
|
||||
if (actual == 0)
|
||||
|
|
@ -189,7 +219,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
}
|
||||
while (_mode == Mode.ChunkData)
|
||||
{
|
||||
var limit = Math.Min(buffer.Count, _inputLength);
|
||||
var limit = buffer.Array == null ? _inputLength : Math.Min(buffer.Count, _inputLength);
|
||||
if (limit != 0)
|
||||
{
|
||||
await input;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
{
|
||||
public static class SocketInputExtensions
|
||||
{
|
||||
public static async Task<int> ReadAsync(this SocketInput input, ArraySegment<byte> buffer)
|
||||
public static async Task<int> ReadAsync(this SocketInput input, byte[] buffer, int offset, int count)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
|
|
@ -16,7 +16,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
|
||||
var begin = input.ConsumingStart();
|
||||
int actual;
|
||||
var end = begin.CopyTo(buffer.Array, buffer.Offset, buffer.Count, out actual);
|
||||
var end = begin.CopyTo(buffer, offset, count, out actual);
|
||||
input.ConsumingComplete(end, end);
|
||||
|
||||
if (actual != 0)
|
||||
|
|
|
|||
|
|
@ -600,18 +600,27 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure
|
|||
if (remaining <= following)
|
||||
{
|
||||
actual = count;
|
||||
Buffer.BlockCopy(block.Array, index, array, offset, remaining);
|
||||
if (array != null)
|
||||
{
|
||||
Buffer.BlockCopy(block.Array, index, array, offset, remaining);
|
||||
}
|
||||
return new MemoryPoolIterator2(block, index + remaining);
|
||||
}
|
||||
else if (block.Next == null)
|
||||
{
|
||||
actual = count - remaining + following;
|
||||
Buffer.BlockCopy(block.Array, index, array, offset, following);
|
||||
if (array != null)
|
||||
{
|
||||
Buffer.BlockCopy(block.Array, index, array, offset, following);
|
||||
}
|
||||
return new MemoryPoolIterator2(block, index + following);
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer.BlockCopy(block.Array, index, array, offset, following);
|
||||
if (array != null)
|
||||
{
|
||||
Buffer.BlockCopy(block.Array, index, array, offset, following);
|
||||
}
|
||||
offset += following;
|
||||
remaining -= following;
|
||||
block = block.Next;
|
||||
|
|
|
|||
Loading…
Reference in New Issue