Remove count parameter from ISocketOutput.ProducingComplete

- This makes the calling code cleaner with a (hopefully) minimal pref impact
This commit is contained in:
Stephen Halter 2015-12-01 11:47:39 -08:00
parent dff3a4f231
commit d0dca75241
9 changed files with 144 additions and 151 deletions

View File

@ -42,7 +42,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Filter
return new MemoryPoolIterator2(_producingBlock); return new MemoryPoolIterator2(_producingBlock);
} }
public void ProducingComplete(MemoryPoolIterator2 end, int count) public void ProducingComplete(MemoryPoolIterator2 end)
{ {
var block = _producingBlock; var block = _producingBlock;
while (block != end.Block) while (block != end.Block)

View File

@ -674,12 +674,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
_responseHeaders.SetRawConnection("keep-alive", _bytesConnectionKeepAlive); _responseHeaders.SetRawConnection("keep-alive", _bytesConnectionKeepAlive);
} }
count += end.CopyFrom(_httpVersion == HttpVersionType.Http1_1 ? _bytesHttpVersion1_1 : _bytesHttpVersion1_0); end.CopyFrom(_httpVersion == HttpVersionType.Http1_1 ? _bytesHttpVersion1_1 : _bytesHttpVersion1_0);
count += end.CopyFrom(statusBytes); end.CopyFrom(statusBytes);
count += _responseHeaders.CopyTo(ref end); _responseHeaders.CopyTo(ref end);
count += end.CopyFrom(_bytesEndHeaders, 0, _bytesEndHeaders.Length); end.CopyFrom(_bytesEndHeaders, 0, _bytesEndHeaders.Length);
SocketOutput.ProducingComplete(end, count); SocketOutput.ProducingComplete(end);
if (immediate) if (immediate)
{ {

View File

@ -7821,16 +7821,15 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
((ICollection<KeyValuePair<string, StringValues>>)MaybeUnknown)?.CopyTo(array, arrayIndex); ((ICollection<KeyValuePair<string, StringValues>>)MaybeUnknown)?.CopyTo(array, arrayIndex);
} }
protected int CopyToFast(ref MemoryPoolIterator2 output) protected void CopyToFast(ref MemoryPoolIterator2 output)
{ {
var count = 0;
if (((_bits & 1L) != 0)) if (((_bits & 1L) != 0))
{ {
foreach(var value in _CacheControl) foreach(var value in _CacheControl)
{ {
count += output.CopyFrom(_headerBytes, 0, 17); output.CopyFrom(_headerBytes, 0, 17);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -7838,12 +7837,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
if (_rawConnection != null) if (_rawConnection != null)
{ {
count += output.CopyFrom(_rawConnection, 0, _rawConnection.Length); output.CopyFrom(_rawConnection, 0, _rawConnection.Length);
} else } else
foreach(var value in _Connection) foreach(var value in _Connection)
{ {
count += output.CopyFrom(_headerBytes, 17, 14); output.CopyFrom(_headerBytes, 17, 14);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -7851,12 +7850,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
if (_rawDate != null) if (_rawDate != null)
{ {
count += output.CopyFrom(_rawDate, 0, _rawDate.Length); output.CopyFrom(_rawDate, 0, _rawDate.Length);
} else } else
foreach(var value in _Date) foreach(var value in _Date)
{ {
count += output.CopyFrom(_headerBytes, 31, 8); output.CopyFrom(_headerBytes, 31, 8);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -7864,8 +7863,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _KeepAlive) foreach(var value in _KeepAlive)
{ {
count += output.CopyFrom(_headerBytes, 39, 14); output.CopyFrom(_headerBytes, 39, 14);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -7873,8 +7872,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _Pragma) foreach(var value in _Pragma)
{ {
count += output.CopyFrom(_headerBytes, 53, 10); output.CopyFrom(_headerBytes, 53, 10);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -7882,8 +7881,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _Trailer) foreach(var value in _Trailer)
{ {
count += output.CopyFrom(_headerBytes, 63, 11); output.CopyFrom(_headerBytes, 63, 11);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -7891,12 +7890,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
if (_rawTransferEncoding != null) if (_rawTransferEncoding != null)
{ {
count += output.CopyFrom(_rawTransferEncoding, 0, _rawTransferEncoding.Length); output.CopyFrom(_rawTransferEncoding, 0, _rawTransferEncoding.Length);
} else } else
foreach(var value in _TransferEncoding) foreach(var value in _TransferEncoding)
{ {
count += output.CopyFrom(_headerBytes, 74, 21); output.CopyFrom(_headerBytes, 74, 21);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -7904,8 +7903,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _Upgrade) foreach(var value in _Upgrade)
{ {
count += output.CopyFrom(_headerBytes, 95, 11); output.CopyFrom(_headerBytes, 95, 11);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -7913,8 +7912,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _Via) foreach(var value in _Via)
{ {
count += output.CopyFrom(_headerBytes, 106, 7); output.CopyFrom(_headerBytes, 106, 7);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -7922,8 +7921,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _Warning) foreach(var value in _Warning)
{ {
count += output.CopyFrom(_headerBytes, 113, 11); output.CopyFrom(_headerBytes, 113, 11);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -7931,8 +7930,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _Allow) foreach(var value in _Allow)
{ {
count += output.CopyFrom(_headerBytes, 124, 9); output.CopyFrom(_headerBytes, 124, 9);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -7940,12 +7939,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
if (_rawContentLength != null) if (_rawContentLength != null)
{ {
count += output.CopyFrom(_rawContentLength, 0, _rawContentLength.Length); output.CopyFrom(_rawContentLength, 0, _rawContentLength.Length);
} else } else
foreach(var value in _ContentLength) foreach(var value in _ContentLength)
{ {
count += output.CopyFrom(_headerBytes, 133, 18); output.CopyFrom(_headerBytes, 133, 18);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -7953,8 +7952,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _ContentType) foreach(var value in _ContentType)
{ {
count += output.CopyFrom(_headerBytes, 151, 16); output.CopyFrom(_headerBytes, 151, 16);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -7962,8 +7961,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _ContentEncoding) foreach(var value in _ContentEncoding)
{ {
count += output.CopyFrom(_headerBytes, 167, 20); output.CopyFrom(_headerBytes, 167, 20);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -7971,8 +7970,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _ContentLanguage) foreach(var value in _ContentLanguage)
{ {
count += output.CopyFrom(_headerBytes, 187, 20); output.CopyFrom(_headerBytes, 187, 20);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -7980,8 +7979,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _ContentLocation) foreach(var value in _ContentLocation)
{ {
count += output.CopyFrom(_headerBytes, 207, 20); output.CopyFrom(_headerBytes, 207, 20);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -7989,8 +7988,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _ContentMD5) foreach(var value in _ContentMD5)
{ {
count += output.CopyFrom(_headerBytes, 227, 15); output.CopyFrom(_headerBytes, 227, 15);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -7998,8 +7997,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _ContentRange) foreach(var value in _ContentRange)
{ {
count += output.CopyFrom(_headerBytes, 242, 17); output.CopyFrom(_headerBytes, 242, 17);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -8007,8 +8006,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _Expires) foreach(var value in _Expires)
{ {
count += output.CopyFrom(_headerBytes, 259, 11); output.CopyFrom(_headerBytes, 259, 11);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -8016,8 +8015,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _LastModified) foreach(var value in _LastModified)
{ {
count += output.CopyFrom(_headerBytes, 270, 17); output.CopyFrom(_headerBytes, 270, 17);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -8025,8 +8024,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _AcceptRanges) foreach(var value in _AcceptRanges)
{ {
count += output.CopyFrom(_headerBytes, 287, 17); output.CopyFrom(_headerBytes, 287, 17);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -8034,8 +8033,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _Age) foreach(var value in _Age)
{ {
count += output.CopyFrom(_headerBytes, 304, 7); output.CopyFrom(_headerBytes, 304, 7);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -8043,8 +8042,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _ETag) foreach(var value in _ETag)
{ {
count += output.CopyFrom(_headerBytes, 311, 8); output.CopyFrom(_headerBytes, 311, 8);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -8052,8 +8051,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _Location) foreach(var value in _Location)
{ {
count += output.CopyFrom(_headerBytes, 319, 12); output.CopyFrom(_headerBytes, 319, 12);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -8061,8 +8060,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _ProxyAutheticate) foreach(var value in _ProxyAutheticate)
{ {
count += output.CopyFrom(_headerBytes, 331, 21); output.CopyFrom(_headerBytes, 331, 21);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -8070,8 +8069,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _RetryAfter) foreach(var value in _RetryAfter)
{ {
count += output.CopyFrom(_headerBytes, 352, 15); output.CopyFrom(_headerBytes, 352, 15);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -8079,12 +8078,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
if (_rawServer != null) if (_rawServer != null)
{ {
count += output.CopyFrom(_rawServer, 0, _rawServer.Length); output.CopyFrom(_rawServer, 0, _rawServer.Length);
} else } else
foreach(var value in _Server) foreach(var value in _Server)
{ {
count += output.CopyFrom(_headerBytes, 367, 10); output.CopyFrom(_headerBytes, 367, 10);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -8092,8 +8091,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _SetCookie) foreach(var value in _SetCookie)
{ {
count += output.CopyFrom(_headerBytes, 377, 14); output.CopyFrom(_headerBytes, 377, 14);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -8101,8 +8100,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _Vary) foreach(var value in _Vary)
{ {
count += output.CopyFrom(_headerBytes, 391, 8); output.CopyFrom(_headerBytes, 391, 8);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
@ -8110,12 +8109,11 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
foreach(var value in _WWWAuthenticate) foreach(var value in _WWWAuthenticate)
{ {
count += output.CopyFrom(_headerBytes, 399, 20); output.CopyFrom(_headerBytes, 399, 20);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
return count;
} }
public unsafe void Append(byte[] keyBytes, int keyOffset, int keyLength, string value) public unsafe void Append(byte[] keyBytes, int keyOffset, int keyLength, string value)
{ {

View File

@ -30,23 +30,22 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
return GetEnumerator(); return GetEnumerator();
} }
public int CopyTo(ref MemoryPoolIterator2 output) public void CopyTo(ref MemoryPoolIterator2 output)
{ {
var count = CopyToFast(ref output); CopyToFast(ref output);
if (MaybeUnknown != null) if (MaybeUnknown != null)
{ {
foreach (var kv in MaybeUnknown) foreach (var kv in MaybeUnknown)
{ {
foreach (var value in kv.Value) foreach (var value in kv.Value)
{ {
count += output.CopyFrom(_CrLf, 0, 2); output.CopyFrom(_CrLf, 0, 2);
count += output.CopyFromAscii(kv.Key); output.CopyFromAscii(kv.Key);
count += output.CopyFrom(_colonSpace, 0, 2); output.CopyFrom(_colonSpace, 0, 2);
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
} }
} }
} }
return count;
} }
public partial struct Enumerator : IEnumerator<KeyValuePair<string, StringValues>> public partial struct Enumerator : IEnumerator<KeyValuePair<string, StringValues>>

View File

@ -30,7 +30,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
/// or <see cref="WriteAsync(ArraySegment{byte}, bool, CancellationToken)"/> is called afterwards. /// or <see cref="WriteAsync(ArraySegment{byte}, bool, CancellationToken)"/> is called afterwards.
/// </summary> /// </summary>
/// <param name="end">Points to the end of the committed data.</param> /// <param name="end">Points to the end of the committed data.</param>
/// <param name="count">The number of bytes added to the response.</param> void ProducingComplete(MemoryPoolIterator2 end);
void ProducingComplete(MemoryPoolIterator2 end, int count);
} }
} }

View File

@ -19,6 +19,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
private const int _initialTaskQueues = 64; private const int _initialTaskQueues = 64;
private static WaitCallback _returnBlocks = (state) => ReturnBlocks((MemoryPoolBlock2)state); private static WaitCallback _returnBlocks = (state) => ReturnBlocks((MemoryPoolBlock2)state);
private static MemoryPoolIterator2 _defaultIterator;
private readonly KestrelThread _thread; private readonly KestrelThread _thread;
private readonly UvStreamHandle _socket; private readonly UvStreamHandle _socket;
@ -34,8 +35,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
private MemoryPoolBlock2 _head; private MemoryPoolBlock2 _head;
private MemoryPoolBlock2 _tail; private MemoryPoolBlock2 _tail;
private bool _isProducing; private MemoryPoolIterator2 _lastStart;
private MemoryPoolBlock2 _returnFromOnProducingComplete;
// This locks access to to all of the below fields // This locks access to to all of the below fields
private readonly object _contextLock = new object(); private readonly object _contextLock = new object();
@ -83,7 +83,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
var tail = ProducingStart(); var tail = ProducingStart();
tail.CopyFrom(buffer); tail.CopyFrom(buffer);
// We do our own accounting below // We do our own accounting below
ProducingComplete(tail, count: 0); ProducingCompleteNoPreComplete(tail);
} }
TaskCompletionSource<object> tcs = null; TaskCompletionSource<object> tcs = null;
@ -165,54 +165,57 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
lock (_returnLock) lock (_returnLock)
{ {
Debug.Assert(!_isProducing); Debug.Assert(_lastStart.IsDefault);
_isProducing = true;
if (_tail == null) if (_tail == null)
{ {
throw new IOException("The socket has been closed."); throw new IOException("The socket has been closed.");
} }
return new MemoryPoolIterator2(_tail, _tail.End); _lastStart = new MemoryPoolIterator2(_tail, _tail.End);
return _lastStart;
} }
} }
public void ProducingComplete(MemoryPoolIterator2 end, int count) public void ProducingComplete(MemoryPoolIterator2 end)
{
Debug.Assert(!_lastStart.IsDefault);
int bytesProduced, buffersIncluded;
BytesBetween(_lastStart, end, out bytesProduced, out buffersIncluded);
lock (_contextLock)
{
_numBytesPreCompleted += bytesProduced;
}
ProducingCompleteNoPreComplete(end);
}
private void ProducingCompleteNoPreComplete(MemoryPoolIterator2 end)
{ {
var decreasePreCompleted = false;
MemoryPoolBlock2 blockToReturn = null; MemoryPoolBlock2 blockToReturn = null;
lock (_returnLock) lock (_returnLock)
{ {
Debug.Assert(_isProducing); Debug.Assert(!_lastStart.IsDefault);
_isProducing = false;
if (_returnFromOnProducingComplete == null) // If the socket has been closed, return the produced blocks
// instead of advancing the now non-existent tail.
if (_tail != null)
{ {
_tail = end.Block; _tail = end.Block;
_tail.End = end.Index; _tail.End = end.Index;
if (count != 0)
{
decreasePreCompleted = true;
}
} }
else else
{ {
blockToReturn = _returnFromOnProducingComplete; blockToReturn = _lastStart.Block;
_returnFromOnProducingComplete = null;
} }
}
if (decreasePreCompleted) _lastStart = _defaultIterator;
{
lock (_contextLock)
{
_numBytesPreCompleted += count;
}
} }
if (blockToReturn != null) if (blockToReturn != null)
{ {
ThreadPool.QueueUserWorkItem(_returnBlocks, blockToReturn); ThreadPool.QueueUserWorkItem(_returnBlocks, blockToReturn);
@ -354,11 +357,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
returnBlock.Pool?.Return(returnBlock); returnBlock.Pool?.Return(returnBlock);
} }
if (_isProducing) // Only return the _tail if we aren't between ProducingStart/Complete calls
{ if (_lastStart.IsDefault)
_returnFromOnProducingComplete = _tail;
}
else
{ {
_tail.Pool?.Return(_tail); _tail.Pool?.Return(_tail);
} }
@ -387,6 +387,28 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
return WriteAsync(buffer, immediate); return WriteAsync(buffer, immediate);
} }
private static void BytesBetween(MemoryPoolIterator2 start, MemoryPoolIterator2 end, out int bytes, out int buffers)
{
if (start.Block == end.Block)
{
bytes = end.Index - start.Index;
buffers = 1;
return;
}
bytes = start.Block.Data.Offset + start.Block.Data.Count - start.Index;
buffers = 1;
for (var block = start.Block.Next; block != end.Block; block = block.Next)
{
bytes += block.Data.Count;
buffers++;
}
bytes += end.Index - end.Block.Data.Offset;
buffers++;
}
private class WriteContext private class WriteContext
{ {
private static WaitCallback _returnWrittenBlocks = (state) => ReturnWrittenBlocks((MemoryPoolBlock2)state); private static WaitCallback _returnWrittenBlocks = (state) => ReturnWrittenBlocks((MemoryPoolBlock2)state);
@ -535,24 +557,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
_lockedStart = new MemoryPoolIterator2(head, head.Start); _lockedStart = new MemoryPoolIterator2(head, head.Start);
_lockedEnd = new MemoryPoolIterator2(tail, tail.End); _lockedEnd = new MemoryPoolIterator2(tail, tail.End);
if (_lockedStart.Block == _lockedEnd.Block) BytesBetween(_lockedStart, _lockedEnd, out _byteCount, out _bufferCount);
{
_byteCount = _lockedEnd.Index - _lockedStart.Index;
_bufferCount = 1;
return;
}
_byteCount = _lockedStart.Block.Data.Offset + _lockedStart.Block.Data.Count - _lockedStart.Index;
_bufferCount = 1;
for (var block = _lockedStart.Block.Next; block != _lockedEnd.Block; block = block.Next)
{
_byteCount += block.Data.Count;
_bufferCount++;
}
_byteCount += _lockedEnd.Index - _lockedEnd.Block.Data.Offset;
_bufferCount++;
} }
} }
} }

View File

@ -532,17 +532,17 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure
} }
} }
public int CopyFrom(byte[] data) public void CopyFrom(byte[] data)
{ {
return CopyFrom(new ArraySegment<byte>(data)); CopyFrom(new ArraySegment<byte>(data));
} }
public int CopyFrom(byte[] data, int offset, int count) public void CopyFrom(byte[] data, int offset, int count)
{ {
return CopyFrom(new ArraySegment<byte>(data, offset, count)); CopyFrom(new ArraySegment<byte>(data, offset, count));
} }
public int CopyFrom(ArraySegment<byte> buffer) public void CopyFrom(ArraySegment<byte> buffer)
{ {
Debug.Assert(_block != null); Debug.Assert(_block != null);
Debug.Assert(_block.Pool != null); Debug.Assert(_block.Pool != null);
@ -582,11 +582,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure
_block = block; _block = block;
_index = blockIndex; _index = blockIndex;
return buffer.Count;
} }
public unsafe int CopyFromAscii(string data) public unsafe void CopyFromAscii(string data)
{ {
Debug.Assert(_block != null); Debug.Assert(_block != null);
Debug.Assert(_block.Pool != null); Debug.Assert(_block.Pool != null);
@ -649,8 +647,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure
_block = block; _block = block;
_index = blockIndex; _index = blockIndex;
return length;
} }
} }
} }

View File

@ -309,17 +309,15 @@ namespace Microsoft.AspNet.Server.KestrelTests
// block 1 // block 1
var start = socketOutput.ProducingStart(); var start = socketOutput.ProducingStart();
start.Block.End = start.Block.Data.Offset + start.Block.Data.Count; start.Block.End = start.Block.Data.Offset + start.Block.Data.Count;
var totalBytes = start.Block.Data.Count;
// block 2 // block 2
var block2 = memory.Lease(); var block2 = memory.Lease();
block2.End = block2.Data.Offset + block2.Data.Count; block2.End = block2.Data.Offset + block2.Data.Count;
start.Block.Next = block2; start.Block.Next = block2;
totalBytes += block2.Data.Count;
var end = new MemoryPoolIterator2(block2, block2.End); var end = new MemoryPoolIterator2(block2, block2.End);
socketOutput.ProducingComplete(end, totalBytes); socketOutput.ProducingComplete(end);
// A call to Write is required to ensure a write is scheduled // A call to Write is required to ensure a write is scheduled
socketOutput.WriteAsync(default(ArraySegment<byte>)); socketOutput.WriteAsync(default(ArraySegment<byte>));

View File

@ -380,24 +380,22 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
((ICollection<KeyValuePair<string, StringValues>>)MaybeUnknown)?.CopyTo(array, arrayIndex); ((ICollection<KeyValuePair<string, StringValues>>)MaybeUnknown)?.CopyTo(array, arrayIndex);
}} }}
{(loop.ClassName == "FrameResponseHeaders" ? $@" {(loop.ClassName == "FrameResponseHeaders" ? $@"
protected int CopyToFast(ref MemoryPoolIterator2 output) protected void CopyToFast(ref MemoryPoolIterator2 output)
{{ {{
var count = 0;
{Each(loop.Headers, header => $@" {Each(loop.Headers, header => $@"
if ({header.TestBit()}) if ({header.TestBit()})
{{ {(header.EnhancedSetter == false ? "" : $@" {{ {(header.EnhancedSetter == false ? "" : $@"
if (_raw{header.Identifier} != null) if (_raw{header.Identifier} != null)
{{ {{
count += output.CopyFrom(_raw{header.Identifier}, 0, _raw{header.Identifier}.Length); output.CopyFrom(_raw{header.Identifier}, 0, _raw{header.Identifier}.Length);
}} else ")} }} else ")}
foreach(var value in _{header.Identifier}) foreach(var value in _{header.Identifier})
{{ {{
count += output.CopyFrom(_headerBytes, {header.BytesOffset}, {header.BytesCount}); output.CopyFrom(_headerBytes, {header.BytesOffset}, {header.BytesCount});
count += output.CopyFromAscii(value); output.CopyFromAscii(value);
}} }}
}} }}
")} ")}
return count;
}}" : "")} }}" : "")}
public unsafe void Append(byte[] keyBytes, int keyOffset, int keyLength, string value) public unsafe void Append(byte[] keyBytes, int keyOffset, int keyLength, string value)
{{ {{