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.