Skip to content

Merge | Move ReliabilitySection / BestEffortCleanup to framework specific files #2984

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@
<Compile Include="Microsoft\Data\SqlClient\SqlInternalConnectionTds.cs" />
<Compile Include="Microsoft\Data\SqlClient\SqlTransaction.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParser.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParser.NetCoreApp.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParser.netcore.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParser.RegisterEncoding.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserStateObject.netcore.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserStateObjectManaged.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,43 +26,10 @@

namespace Microsoft.Data.SqlClient
{

internal struct SNIErrorDetails
{
public string errorMessage;
public uint nativeError;
public uint sniErrorNumber;
public int provider;
public uint lineNumber;
public string function;
public Exception exception;
}

// The TdsParser Object controls reading/writing to the netlib, parsing the tds,
// and surfacing objects to the user.
internal sealed partial class TdsParser
{
internal struct ReliabilitySection
{
/// <summary>
/// This is a no-op in netcore version. Only needed for merging with netfx codebase.
/// </summary>
[Conditional("NETFRAMEWORK")]
internal static void Assert(string message)
{
}

[Conditional("NETFRAMEWORK")]
internal void Start()
{
}

[Conditional("NETFRAMEWORK")]
internal void Stop()
{
}
}

private static int _objectTypeCount; // EventSource counter
private readonly SqlClientLogger _logger = new SqlClientLogger();

Expand Down Expand Up @@ -1959,8 +1926,6 @@ internal void PrepareResetConnection(bool preserveTransaction)
_fPreserveTransaction = preserveTransaction;
}



internal bool Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
{
bool syncOverAsync = stateObj._syncOverAsync;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,38 @@ namespace Microsoft.Data.SqlClient
{
internal sealed partial class TdsParser
{
internal struct SNIErrorDetails
{
public string errorMessage;
public uint nativeError;
public uint sniErrorNumber;
public int provider;
public uint lineNumber;
public string function;
public Exception exception;
}

internal struct ReliabilitySection
{
/// <summary>
/// This is a no-op in netcore version. Only needed for merging with netfx codebase.
/// </summary>
[Conditional("NETFRAMEWORK")]
internal static void Assert(string message)
{
}

[Conditional("NETFRAMEWORK")]
internal void Start()
{
}

[Conditional("NETFRAMEWORK")]
internal void Stop()
{
}
}

internal static void FillGuidBytes(Guid guid, Span<byte> buffer) => guid.TryWriteBytes(buffer);

internal static void FillDoubleBytes(double value, Span<byte> buffer) => BinaryPrimitives.TryWriteInt64LittleEndian(buffer, BitConverter.DoubleToInt64Bits(value));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,7 @@
<Compile Include="Microsoft\Data\SqlClient\SqlSequentialTextReaderSmi.cs" />
<Compile Include="Microsoft\Data\SqlClient\SqlTransaction.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParser.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParser.netfx.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserStateObject.netfx.cs" />
<Compile Include="Microsoft\Data\SqlTypes\SqlStreamChars.cs" />
<Compile Include="Microsoft\Data\SqlTypes\SqlTypeWorkarounds.netfx.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,89 +66,7 @@ internal int ObjectID
/// Verify client encryption possibility.
/// </summary>
private bool ClientOSEncryptionSupport => SNILoadHandle.SingletonInstance.ClientOSEncryptionSupport;

// ReliabilitySection Usage:
//
// #if DEBUG
// TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();
//
// RuntimeHelpers.PrepareConstrainedRegions();
// try {
// tdsReliabilitySection.Start();
// #else
// {
// #endif //DEBUG
//
// // code that requires reliability
//
// }
// #if DEBUG
// finally {
// tdsReliabilitySection.Stop();
// }
// #endif //DEBUG

internal struct ReliabilitySection
{
#if DEBUG
// do not allocate TLS data in RETAIL bits
[ThreadStatic]
private static int s_reliabilityCount; // initialized to 0 by CLR

private bool m_started; // initialized to false (not started) by CLR
#endif //DEBUG

[Conditional("DEBUG")]
internal void Start()
{
#if DEBUG
Debug.Assert(!m_started);

RuntimeHelpers.PrepareConstrainedRegions();
try
{
}
finally
{
++s_reliabilityCount;
m_started = true;
}
#endif //DEBUG
}

[Conditional("DEBUG")]
internal void Stop()
{
#if DEBUG
// cannot assert m_started - ThreadAbortException can be raised before Start is called

if (m_started)
{
Debug.Assert(s_reliabilityCount > 0);

RuntimeHelpers.PrepareConstrainedRegions();
try
{
}
finally
{
--s_reliabilityCount;
m_started = false;
}
}
#endif //DEBUG
}

// you need to setup for a thread abort somewhere before you call this method
[Conditional("DEBUG")]
internal static void Assert(string message)
{
#if DEBUG
Debug.Assert(s_reliabilityCount > 0, message);
#endif //DEBUG
}
}


// Default state object for parser
internal TdsParserStateObject _physicalStateObj = null; // Default stateObj and connection for Dbnetlib and non-MARS SNI.

Expand Down Expand Up @@ -805,60 +723,6 @@ internal void Connect(ServerInfo serverInfo,
return;
}

// Retrieve the IP and port number from native SNI for TCP protocol. The IP information is stored temporarily in the
// pendingSQLDNSObject but not in the DNS Cache at this point. We only add items to the DNS Cache after we receive the
// IsSupported flag as true in the feature ext ack from server.
internal void AssignPendingDNSInfo(string userProtocol, string DNSCacheKey)
{
UInt32 result;
ushort portFromSNI = 0;
string IPStringFromSNI = string.Empty;
IPAddress IPFromSNI;
isTcpProtocol = false;
Provider providerNumber = Provider.INVALID_PROV;

if (string.IsNullOrEmpty(userProtocol))
{

result = SNINativeMethodWrapper.SniGetProviderNumber(_physicalStateObj.Handle, ref providerNumber);
Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetProviderNumber");
isTcpProtocol = (providerNumber == Provider.TCP_PROV);
}
else if (userProtocol == TdsEnums.TCP)
{
isTcpProtocol = true;
}

// serverInfo.UserProtocol could be empty
if (isTcpProtocol)
{
result = SNINativeMethodWrapper.SniGetConnectionPort(_physicalStateObj.Handle, ref portFromSNI);
Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetConnectionPort");


result = SNINativeMethodWrapper.SniGetConnectionIPString(_physicalStateObj.Handle, ref IPStringFromSNI);
Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetConnectionIPString");

_connHandler.pendingSQLDNSObject = new SQLDNSInfo(DNSCacheKey, null, null, portFromSNI.ToString());

if (IPAddress.TryParse(IPStringFromSNI, out IPFromSNI))
{
if (System.Net.Sockets.AddressFamily.InterNetwork == IPFromSNI.AddressFamily)
{
_connHandler.pendingSQLDNSObject.AddrIPv4 = IPStringFromSNI;
}
else if (System.Net.Sockets.AddressFamily.InterNetworkV6 == IPFromSNI.AddressFamily)
{
_connHandler.pendingSQLDNSObject.AddrIPv6 = IPStringFromSNI;
}
}
}
else
{
_connHandler.pendingSQLDNSObject = null;
}
}

internal void RemoveEncryption()
{
Debug.Assert((_encryptionOption & EncryptionOptions.OPTIONS_MASK) == EncryptionOptions.LOGIN, "Invalid encryption option state");
Expand Down Expand Up @@ -989,41 +853,6 @@ internal void PutSession(TdsParserStateObject session)
}
}

// This is called from a ThreadAbort - ensure that it can be run from a CER Catch
internal void BestEffortCleanup()
{
_state = TdsParserState.Broken;

var stateObj = _physicalStateObj;
if (stateObj != null)
{
var stateObjHandle = stateObj.Handle;
if (stateObjHandle != null)
{
stateObjHandle.Dispose();
}
}

if (_fMARS)
{
var sessionPool = _sessionPool;
if (sessionPool != null)
{
sessionPool.BestEffortCleanup();
}

var marsStateObj = _pMarsPhysicalConObj;
if (marsStateObj != null)
{
var marsStateObjHandle = marsStateObj.Handle;
if (marsStateObjHandle != null)
{
marsStateObjHandle.Dispose();
}
}
}
}

private void SendPreLoginHandshake(
byte[] instanceName,
SqlConnectionEncryptOption encrypt,
Expand Down Expand Up @@ -2248,44 +2077,6 @@ internal void PrepareResetConnection(bool preserveTransaction)
_fPreserveTransaction = preserveTransaction;
}

internal bool RunReliably(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
{
RuntimeHelpers.PrepareConstrainedRegions();
try
{
#if DEBUG
TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();
RuntimeHelpers.PrepareConstrainedRegions();
try
{
tdsReliabilitySection.Start();
#endif //DEBUG
return Run(runBehavior, cmdHandler, dataStream, bulkCopyHandler, stateObj);
#if DEBUG
}
finally
{
tdsReliabilitySection.Stop();
}
#endif //DEBUG
}
catch (OutOfMemoryException)
{
_connHandler.DoomThisConnection();
throw;
}
catch (StackOverflowException)
{
_connHandler.DoomThisConnection();
throw;
}
catch (ThreadAbortException)
{
_connHandler.DoomThisConnection();
throw;
}
}

internal bool Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
{
bool syncOverAsync = stateObj._syncOverAsync;
Expand Down
Loading
Loading