diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 8c859cecc3..ed2d274f5c 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -284,7 +284,7 @@ - + @@ -317,7 +317,8 @@ - + + @@ -756,6 +757,7 @@ + True True diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/ConcurrentQueueSemaphore.NetStandard.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/ConcurrentQueueSemaphore.NetStandard.cs index d22b1b9c8c..45b801af51 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/ConcurrentQueueSemaphore.NetStandard.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/ConcurrentQueueSemaphore.NetStandard.cs @@ -11,14 +11,22 @@ internal sealed partial class ConcurrentQueueSemaphore { public Task WaitAsync(CancellationToken cancellationToken) { - var tcs = new TaskCompletionSource(); - _queue.Enqueue(tcs); - _semaphore.WaitAsync().ContinueWith( - continuationAction: s_continuePop, - state: _queue, - cancellationToken: cancellationToken - ); - return tcs.Task; + // try sync wait with 0 which will not block to see if we need to do an async wait + if (_semaphore.Wait(0, cancellationToken)) + { + return Task.CompletedTask; + } + else + { + var tcs = new TaskCompletionSource(); + _queue.Enqueue(tcs); + _semaphore.WaitAsync().ContinueWith( + continuationAction: s_continuePop, + state: _queue, + cancellationToken: cancellationToken + ); + return tcs.Task; + } } } } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.NetStandard.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.Task.cs similarity index 86% rename from src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.NetStandard.cs rename to src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.Task.cs index 0a9ab39d7a..7ca2ee167e 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.NetStandard.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.Task.cs @@ -2,14 +2,17 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Net.Security; -using System.IO; using System.Threading; using System.Threading.Tasks; -using System.Net.Sockets; + namespace Microsoft.Data.SqlClient.SNI { + // NetCore2.1: + // DO NOT OVERRIDE ValueTask versions of ReadAsync and WriteAsync because the underlying SslStream implements them + // by calling the Task versions which are already overridden meaning that if a caller uses Task WriteAsync this would + // call ValueTask WriteAsync which then called TaskWriteAsync introducing a lock cycle and never return + internal sealed partial class SNISslStream { public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.ValueTask.cs similarity index 98% rename from src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.NetCoreApp.cs rename to src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.ValueTask.cs index 6a62e2b9ab..f4fa916d7c 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.NetCoreApp.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.ValueTask.cs @@ -2,16 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Net.Security; -using System.IO; using System.Threading; using System.Threading.Tasks; -using System.Net.Sockets; using System; namespace Microsoft.Data.SqlClient.SNI { - internal sealed partial class SNISslStream { public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)