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 c35899a762..49915ef1e6 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -584,12 +584,6 @@ Microsoft\Data\SqlClient\SqlNotificationType.cs - - Microsoft\Data\SqlClient\SqlObjectPool.cs - - - Microsoft\Data\SqlClient\SqlObjectPools.cs - Microsoft\Data\SqlClient\SqlParameter.cs @@ -647,6 +641,12 @@ Microsoft\Data\SqlClient\SSPI\SSPIContextProvider.cs + + Microsoft\Data\SqlClient\Utilities\ObjectPool.cs + + + Microsoft\Data\SqlClient\Utilities\ObjectPools.cs + Microsoft\Data\SqlClient\TdsEnums.cs @@ -683,6 +683,9 @@ Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProviderBase.cs + + Microsoft\Data\SqlDbTypeExtensions.cs + Microsoft\Data\SQLTypes\SQLResource.cs @@ -699,10 +702,7 @@ Resources\ResDescriptionAttribute.cs - Common\System\Diagnostics\CodeAnalysis.cs - - - Microsoft\Data\SqlDbTypeExtensions.cs + System\Diagnostics\CodeAnalysis.cs diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIPhysicalHandle.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIPhysicalHandle.cs index 3677abe6cd..1acc6a14c8 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIPhysicalHandle.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIPhysicalHandle.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Threading; +using Microsoft.Data.SqlClient.Utilities; namespace Microsoft.Data.SqlClient.SNI { @@ -16,11 +17,11 @@ internal abstract class SNIPhysicalHandle : SNIHandle #if DEBUG private static int s_packetId; #endif - private SqlObjectPool _pool; + private ObjectPool _pool; protected SNIPhysicalHandle(int poolSize = DefaultPoolSize) { - _pool = new SqlObjectPool(poolSize); + _pool = new ObjectPool(poolSize); } public override SNIPacket RentPacket(int headerSize, int dataSize) diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index 20f02e7204..af0e1cf10c 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -350,12 +350,6 @@ Microsoft\Data\Sql\SqlDataSourceEnumerator.cs - - - Microsoft\Data\SqlClient\SqlObjectPool.cs - - - Microsoft\Data\SqlClient\SqlObjectPools.cs Microsoft\Data\SqlClient\AAsyncCallContext.cs @@ -381,9 +375,6 @@ Microsoft\Data\SqlClient\AlwaysEncryptedKeyConverter.cs - - Microsoft\Data\SqlClient\ArrayBufferWriter.cs - Microsoft\Data\SqlClient\AzureAttestationBasedEnclaveProvider.cs @@ -837,6 +828,15 @@ Microsoft\Data\SqlClient\TdsValueSetter.cs + + Microsoft\Data\SqlClient\Utilities\BufferWriterExtensions.netfx.cs + + + Microsoft\Data\SqlClient\Utilities\ObjectPool.cs + + + Microsoft\Data\SqlClient\Utilities\ObjectPools.cs + Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProvider.cs @@ -861,6 +861,9 @@ Resources\ResDescriptionAttribute.cs + + System\Buffers\ArrayBufferWriter.netfx.cs + System\IO\StreamExtensions.netfx.cs @@ -870,7 +873,6 @@ - diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeWrapper.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeWrapper.cs index ae754d9421..c9cbef64a4 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeWrapper.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeWrapper.cs @@ -9,6 +9,7 @@ using System.Text; using Interop.Windows.Sni; using Microsoft.Data.Common; +using Microsoft.Data.SqlClient.Utilities; #if NETFRAMEWORK using System.Runtime.CompilerServices; @@ -259,7 +260,7 @@ internal static unsafe uint SniOpenSyncEx( else { // We have a value of the SPN, so we marshal that and send it to the native layer - var writer = SqlObjectPools.BufferWriter.Rent(); + var writer = ObjectPools.BufferWriter.Rent(); try { @@ -277,7 +278,7 @@ internal static unsafe uint SniOpenSyncEx( } finally { - SqlObjectPools.BufferWriter.Return(writer); + ObjectPools.BufferWriter.Return(writer); } } } @@ -445,7 +446,7 @@ internal static unsafe uint SniSecGenClientContext( ref uint sendLength, string serverUserName) { - var serverWriter = SqlObjectPools.BufferWriter.Rent(); + var serverWriter = ObjectPools.BufferWriter.Rent(); try { @@ -470,7 +471,7 @@ internal static unsafe uint SniSecGenClientContext( } finally { - SqlObjectPools.BufferWriter.Return(serverWriter); + ObjectPools.BufferWriter.Return(serverWriter); } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlObjectPools.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlObjectPools.cs deleted file mode 100644 index 98b980180c..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlObjectPools.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// 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; -using System.Buffers; -using System.Diagnostics; -using System.Text; -using System.Threading; - -namespace Microsoft.Data.SqlClient -{ - // This is a collection of general object pools that can be reused as needed. - internal static class SqlObjectPools - { - private static SqlObjectPool> _bufferWriter; - - internal static SqlObjectPool> BufferWriter - { - get - { - if (_bufferWriter is null) - { - // This is a shared pool that will retain the last 20 writers to be reused. If more than 20 are requested at a time, - // they will not be retained when returned to the pool. - Interlocked.CompareExchange(ref _bufferWriter, new(20, () => new(), a => a.Clear()), null); - } - - return _bufferWriter; - } - } - } - -} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs index 8721b05658..ad8226c7fe 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -1,6 +1,7 @@ using System; using System.Buffers; using System.Diagnostics; +using Microsoft.Data.SqlClient.Utilities; #nullable enable @@ -29,7 +30,7 @@ internal void ProcessSSPI(int receivedLength) } // allocate send buffer and initialize length - var writer = SqlObjectPools.BufferWriter.Rent(); + var writer = ObjectPools.BufferWriter.Rent(); try { @@ -42,7 +43,7 @@ internal void ProcessSSPI(int receivedLength) } finally { - SqlObjectPools.BufferWriter.Return(writer); + ObjectPools.BufferWriter.Return(writer); } } finally @@ -167,7 +168,7 @@ internal void TdsLogin( { if (rec.useSSPI) { - sspiWriter = SqlObjectPools.BufferWriter.Rent(); + sspiWriter = ObjectPools.BufferWriter.Rent(); // Call helper function for SSPI data and actual length. // Since we don't have SSPI data from the server, send null for the @@ -209,7 +210,7 @@ internal void TdsLogin( { if (sspiWriter is not null) { - SqlObjectPools.BufferWriter.Return(sspiWriter); + ObjectPools.BufferWriter.Return(sspiWriter); } } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/BufferWriterExtensions.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Utilities/BufferWriterExtensions.netfx.cs similarity index 69% rename from src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/BufferWriterExtensions.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Utilities/BufferWriterExtensions.netfx.cs index e23cff2dcc..22cbb7cb52 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/BufferWriterExtensions.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Utilities/BufferWriterExtensions.netfx.cs @@ -1,8 +1,14 @@ -using System; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NETFRAMEWORK + +using System; using System.Buffers; using System.Text; -namespace Microsoft.Data.SqlClient +namespace Microsoft.Data.SqlClient.Utilities { internal static class BufferWriterExtensions { @@ -24,3 +30,5 @@ internal static long GetBytes(this Encoding encoding, string str, IBufferWriter< } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlObjectPool.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Utilities/ObjectPool.cs similarity index 92% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlObjectPool.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Utilities/ObjectPool.cs index d5cf2398ec..a3b8c11cff 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlObjectPool.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Utilities/ObjectPool.cs @@ -6,11 +6,11 @@ using System.Diagnostics; using System.Threading; -namespace Microsoft.Data.SqlClient +namespace Microsoft.Data.SqlClient.Utilities { // this is a very simple threadsafe pool derived from the aspnet/extensions default pool implementation // https://github.com/dotnet/extensions/blob/release/3.1/src/ObjectPool/src/DefaultObjectPool.cs - internal sealed class SqlObjectPool where T : class + internal sealed class ObjectPool where T : class { private readonly ObjectWrapper[] _items; private readonly Action _onReturned; @@ -18,7 +18,7 @@ internal sealed class SqlObjectPool where T : class private T _firstItem; - public SqlObjectPool(int maximumRetained, Func onCreate = null, Action onReturned = null) + public ObjectPool(int maximumRetained, Func onCreate = null, Action onReturned = null) { // -1 due to _firstItem _items = new ObjectWrapper[maximumRetained - 1]; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Utilities/ObjectPools.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Utilities/ObjectPools.cs new file mode 100644 index 0000000000..ab046f63bf --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Utilities/ObjectPools.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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; +using System.Buffers; + +namespace Microsoft.Data.SqlClient.Utilities +{ + /// + /// This is a collection of general object pools that can be reused as needed. + /// + internal static class ObjectPools + { + private static readonly Lazy>> s_bufferWriterPool = + new(() => new ObjectPool>( + maximumRetained: 20, + onCreate: () => new ArrayBufferWriter(), + onReturned: bufferWriter => bufferWriter.Clear())); + + internal static ObjectPool> BufferWriter => s_bufferWriterPool.Value; + } + +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ArrayBufferWriter.cs b/src/Microsoft.Data.SqlClient/src/System/Buffers/ArrayBufferWriter.netfx.cs similarity index 97% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ArrayBufferWriter.cs rename to src/Microsoft.Data.SqlClient/src/System/Buffers/ArrayBufferWriter.netfx.cs index dfb4820e28..b23060201b 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ArrayBufferWriter.cs +++ b/src/Microsoft.Data.SqlClient/src/System/Buffers/ArrayBufferWriter.netfx.cs @@ -4,20 +4,20 @@ #if NETFRAMEWORK -using System; -using System.Buffers; using System.Diagnostics; using System.Globalization; -namespace Microsoft.Data.SqlClient +namespace System.Buffers { /// /// Internal implementation of for platforms that don't have it available. /// /// NOTE: This file should not be edited as it is copied from dotnet/runtime and has no tests in this repo. + /// It is only included for netfx version of the driver because this class was not introduced + /// until netstandard 2.1. /// /// - sealed class ArrayBufferWriter : IBufferWriter + internal sealed class ArrayBufferWriter : IBufferWriter { // Copy of Array.MaxLength. // Used by projects targeting .NET Framework. @@ -137,6 +137,8 @@ public void Advance(int count) _index += count; } + + /// /// Returns a to write to that is at least the requested length (specified by ). /// If no is provided (or it's equal to 0), some non-empty buffer is returned.