From 92a10fefb4532ad7893973b1785436c33200c662 Mon Sep 17 00:00:00 2001 From: Cory Nelson Date: Thu, 11 Jul 2019 23:29:05 -0700 Subject: [PATCH] Move integer read into ProcessPingFrame. Commit migrated from https://github.com/dotnet/corefx/commit/790f53719c3816a0d010966848fbdaeb412928a3 --- .../Net/Http/SocketsHttpHandler/Http2Connection.cs | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs index 4e6881d..0b62ed5 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs @@ -579,11 +579,15 @@ namespace System.Net.Http throw new Http2ConnectionException(Http2ProtocolErrorCode.FrameSizeError); } - // Send PING ACK - // Don't wait for completion, which could happen asynchronously. - LogExceptions(SendPingAckAsync(_incomingBuffer.ActiveMemory.Slice(0, FrameHeader.PingLength))); + // We don't wait for SendPingAckAsync to complete before discarding + // the incoming buffer, so we need to take a copy of the data. Read + // it as a big-endian integer here to avoid allocating an array. + Debug.Assert(sizeof(long) == FrameHeader.PingLength); + ReadOnlySpan pingContent = _incomingBuffer.ActiveSpan.Slice(0, FrameHeader.PingLength); + long pingContentLong = BinaryPrimitives.ReadInt64BigEndian(pingContent); + + LogExceptions(SendPingAckAsync(pingContentLong)); - // SendPingAckAsync copies the buffer for us, so it is safe to not wait for completion. _incomingBuffer.Discard(frameHeader.Length); } @@ -788,14 +792,9 @@ namespace System.Net.Http FinishWrite(mustFlush: true); } - private async Task SendPingAckAsync(ReadOnlyMemory pingContent) + /// The 8-byte ping content to send, read as a big-endian integer. + private async Task SendPingAckAsync(long pingContent) { - Debug.Assert(pingContent.Length == FrameHeader.PingLength); - - // Copy pingContent before we go async so the caller can - // discard their buffer without waiting for us to complete. - long pingContentLong = BitConverter.ToInt64(pingContent.Span); - Memory writeBuffer = await StartWriteAsync(FrameHeader.Size + FrameHeader.PingLength).ConfigureAwait(false); if (NetEventSource.IsEnabled) Trace("Started writing."); @@ -803,7 +802,8 @@ namespace System.Net.Http frameHeader.WriteTo(writeBuffer); writeBuffer = writeBuffer.Slice(FrameHeader.Size); - BitConverter.TryWriteBytes(writeBuffer.Span, pingContentLong); + Debug.Assert(sizeof(long) == FrameHeader.PingLength); + BinaryPrimitives.WriteInt64BigEndian(writeBuffer.Span, pingContent); FinishWrite(mustFlush: false); } -- 2.7.4