From 22f6c48521c66a93a591d4c13508493a0b15f2f5 Mon Sep 17 00:00:00 2001 From: panoskj Date: Sun, 24 Sep 2023 03:15:38 +0300 Subject: [PATCH] 1. Merging "Buffer read" methods of TdsParserStateObject, port #667 to netfx. Replaced Thread.MemoryBarrier usage of netfx with Interlocked.MemoryBarrier. --- .../SqlClient/TdsParserStateObject.netcore.cs | 8 ++++++- .../SqlClient/TdsParserStateObject.netfx.cs | 23 ++++++++----------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.netcore.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.netcore.cs index 9ac485cbbb..a95967c32a 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.netcore.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.netcore.cs @@ -310,6 +310,9 @@ public bool TryReadByteArray(Span buff, int len) // Every time you call this method increment the offset and decrease len by the value of totalRead public bool TryReadByteArray(Span buff, int len, out int totalRead) { +#if NETFRAMEWORK + TdsParser.ReliabilitySection.Assert("unreliable call to ReadByteArray"); // you need to setup for a thread abort somewhere before you call this method +#endif totalRead = 0; #if DEBUG @@ -331,7 +334,7 @@ public bool TryReadByteArray(Span buff, int len, out int totalRead) } #endif - Debug.Assert(buff == null || buff.Length >= len, "Invalid length sent to ReadByteArray()!"); + Debug.Assert(buff.IsEmpty || buff.Length >= len, "Invalid length sent to ReadByteArray()!"); // loop through and read up to array length while (len > 0) @@ -368,6 +371,9 @@ public bool TryReadByteArray(Span buff, int len, out int totalRead) // before the byte is returned. internal bool TryReadByte(out byte value) { +#if NETFRAMEWORK + TdsParser.ReliabilitySection.Assert("unreliable call to ReadByte"); // you need to setup for a thread abort somewhere before you call this method +#endif Debug.Assert(_inBytesUsed >= 0 && _inBytesUsed <= _inBytesRead, "ERROR - TDSParser: _inBytesUsed < 0 or _inBytesUsed > _inBytesRead"); value = 0; diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserStateObject.netfx.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserStateObject.netfx.cs index e64c25c523..59c4f1c511 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserStateObject.netfx.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserStateObject.netfx.cs @@ -404,14 +404,16 @@ public bool TryReadByteArray(Span buff, int len) // Every time you call this method increment the offset and decrease len by the value of totalRead public bool TryReadByteArray(Span buff, int len, out int totalRead) { +#if NETFRAMEWORK TdsParser.ReliabilitySection.Assert("unreliable call to ReadByteArray"); // you need to setup for a thread abort somewhere before you call this method +#endif totalRead = 0; #if DEBUG if (_snapshot != null && _snapshot.DoPend()) { _networkPacketTaskSource = new TaskCompletionSource(); - Thread.MemoryBarrier(); + Interlocked.MemoryBarrier(); if (s_forcePendingReadsToWaitForUser) { @@ -463,7 +465,9 @@ public bool TryReadByteArray(Span buff, int len, out int totalRead) // before the byte is returned. internal bool TryReadByte(out byte value) { +#if NETFRAMEWORK TdsParser.ReliabilitySection.Assert("unreliable call to ReadByte"); // you need to setup for a thread abort somewhere before you call this method +#endif Debug.Assert(_inBytesUsed >= 0 && _inBytesUsed <= _inBytesRead, "ERROR - TDSParser: _inBytesUsed < 0 or _inBytesUsed > _inBytesRead"); value = 0; @@ -471,7 +475,7 @@ internal bool TryReadByte(out byte value) if (_snapshot != null && _snapshot.DoPend()) { _networkPacketTaskSource = new TaskCompletionSource(); - Thread.MemoryBarrier(); + Interlocked.MemoryBarrier(); if (s_forcePendingReadsToWaitForUser) { @@ -510,35 +514,28 @@ internal bool TryReadChar(out char value) { Debug.Assert(_syncOverAsync || !_asyncReadWithoutSnapshot, "This method is not safe to call when doing sync over async"); - byte[] buffer; - int offset; + Span buffer = stackalloc byte[2]; if (((_inBytesUsed + 2) > _inBytesRead) || (_inBytesPacket < 2)) { // If the char isn't fully in the buffer, or if it isn't fully in the packet, // then use ReadByteArray since the logic is there to take care of that. - if (!TryReadByteArray(_bTmp, 2)) + if (!TryReadByteArray(buffer, 2)) { value = '\0'; return false; } - - buffer = _bTmp; - offset = 0; } else { // The entire char is in the packet and in the buffer, so just return it // and take care of the counters. - - buffer = _inBuff; - offset = _inBytesUsed; - + buffer = _inBuff.AsSpan(_inBytesUsed, 2); _inBytesUsed += 2; _inBytesPacket -= 2; } AssertValidState(); - value = (char)((buffer[offset + 1] << 8) + buffer[offset]); + value = (char)((buffer[1] << 8) + buffer[0]); return true; }