Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Commit

Permalink
[release/3.1] Revert async changes in SqlClient to fix deadlock issues (
Browse files Browse the repository at this point in the history
#42776)

* Revert async changes in SqlClient to fix deadlock issues

* Add missing method
  • Loading branch information
cheenamalhotra authored and Anipik committed Jan 14, 2020
1 parent 1ba6a19 commit a9bb325
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 241 deletions.
2 changes: 0 additions & 2 deletions src/System.Data.SqlClient/src/System.Data.SqlClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -286,12 +286,10 @@
<Compile Include="System\Data\SqlClient\SqlConnectionStringBuilder.NetCoreApp.cs" />
<Compile Include="System\Data\SqlClient\SqlDelegatedTransaction.NetCoreApp.cs" />
<Compile Include="System\Data\SqlClient\TdsParser.NetCoreApp.cs" />
<Compile Include="System\Data\SqlClient\SNI\SNIPacket.NetCoreApp.cs" />
</ItemGroup>
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true' AND '$(OSGroup)' != 'AnyOS' AND '$(TargetsNetCoreApp)' != 'true'">
<Compile Include="System\Data\SqlClient\SqlDelegatedTransaction.NetStandard.cs" />
<Compile Include="System\Data\SqlClient\TdsParser.NetStandard.cs" />
<Compile Include="System\Data\SqlClient\SNI\SNIPacket.NetStandard.cs" />
</ItemGroup>
<!-- Manage the SNI toggle for Windows netstandard and UWP -->
<ItemGroup Condition="('$(TargetGroup)' == 'netstandard' OR '$(TargetsNetCoreApp)' == 'true') AND '$(TargetsWindows)' == 'true'">
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@

namespace System.Data.SqlClient.SNI
{
internal sealed partial class SNIPacket
internal sealed class SNIPacket
{
private int _dataLength; // the length of the data in the data segment, advanced by Append-ing data, does not include smux header length
private int _dataCapacity; // the total capacity requested, if the array is rented this may be less than the _data.Length, does not include smux header length
private int _dataOffset; // the start point of the data in the data segment, advanced by Take-ing data
private int _headerLength; // the amount of space at the start of the array reserved for the smux header, this is zeroed in SetHeader
// _headerOffset is not needed because it is always 0
// _headerOffset is not needed because it is always 0
private byte[] _data;
private SNIAsyncCallback _completionCallback;

Expand All @@ -25,6 +25,11 @@ public SNIPacket(int headerSize, int dataSize)
Allocate(headerSize, dataSize);
}

/// <summary>
/// Dispose Packet data
/// </summary>
public void Dispose() => Release();

/// <summary>
/// Length of data left to process
/// </summary>
Expand Down Expand Up @@ -166,6 +171,46 @@ public void Release()
_completionCallback = null;
}

/// <summary>
/// Read data from a stream asynchronously
/// </summary>
/// <param name="stream">Stream to read from</param>
/// <param name="callback">Completion callback</param>
public void ReadFromStreamAsync(Stream stream, SNIAsyncCallback callback)
{
bool error = false;

stream.ReadAsync(_data, 0, _dataCapacity, CancellationToken.None).ContinueWith(t =>
{
Exception e = t.Exception?.InnerException;
if (e != null)
{
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.TCP_PROV, SNICommon.InternalExceptionError, e);
error = true;
}
else
{
_dataLength = t.Result;

if (_dataLength == 0)
{
SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.TCP_PROV, 0, SNICommon.ConnTerminatedError, string.Empty);
error = true;
}
}

if (error)
{
Release();
}

callback(this, error ? TdsEnums.SNI_ERROR : TdsEnums.SNI_SUCCESS);
},
CancellationToken.None,
TaskContinuationOptions.DenyChildAttach,
TaskScheduler.Default);
}

/// <summary>
/// Read data from a stream synchronously
/// </summary>
Expand All @@ -175,6 +220,33 @@ public void ReadFromStream(Stream stream)
_dataLength = stream.Read(_data, _headerLength, _dataCapacity);
}

/// <summary>
/// Write data to a stream asynchronously
/// </summary>
/// <param name="stream">Stream to write to</param>
/// <param name="callback">SNI Asynchronous Callback</param>
/// <param name="provider">SNI provider identifier</param>
/// <param name="disposeAfterWriteAsync">Bool flag to decide whether or not to dispose after Write Async operation</param>
public async void WriteToStreamAsync(Stream stream, SNIAsyncCallback callback, SNIProviders provider, bool disposeAfterWriteAsync = false)
{
uint status = TdsEnums.SNI_SUCCESS;
try
{
await stream.WriteAsync(_data, 0, _dataLength, CancellationToken.None).ConfigureAwait(false);
}
catch (Exception e)
{
SNILoadHandle.SingletonInstance.LastError = new SNIError(provider, SNICommon.InternalExceptionError, e);
status = TdsEnums.SNI_ERROR;
}
callback(this, status);

if (disposeAfterWriteAsync)
{
Dispose();
}
}

/// <summary>
/// Write data to a stream synchronously
/// </summary>
Expand All @@ -183,8 +255,5 @@ public void WriteToStream(Stream stream)
{
stream.Write(_data, _headerLength, _dataLength);
}

}


}

0 comments on commit a9bb325

Please sign in to comment.