From a99952d7e73e1028e4c38489fa221e2106fd5ea7 Mon Sep 17 00:00:00 2001
From: xtqqczze <45661989+xtqqczze@users.noreply.github.com>
Date: Tue, 9 May 2023 10:25:30 +0100
Subject: [PATCH 1/3] Use `NativeMemory` in `System.Data.Odbc`
---
.../System/Data/Common/SafeNativeMethods.cs | 28 -------------------
.../System/Data/ProviderBase/DbBuffer.cs | 24 ++++------------
.../src/System.Data.Odbc.csproj | 1 -
3 files changed, 6 insertions(+), 47 deletions(-)
delete mode 100644 src/libraries/System.Data.Odbc/src/Common/System/Data/Common/SafeNativeMethods.cs
diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/SafeNativeMethods.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/SafeNativeMethods.cs
deleted file mode 100644
index 713c692ae4a4df..00000000000000
--- a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/SafeNativeMethods.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Runtime.InteropServices;
-
-namespace System.Data
-{
- internal static partial class SafeNativeMethods
- {
- internal static IntPtr LocalAlloc(nint initialSize)
- {
- var handle = Marshal.AllocHGlobal(initialSize);
- ZeroMemory(handle, (int)initialSize);
- return handle;
- }
-
- internal static void LocalFree(IntPtr ptr)
- {
- Marshal.FreeHGlobal(ptr);
- }
-
- internal static void ZeroMemory(IntPtr ptr, int length)
- {
- var zeroes = new byte[length];
- Marshal.Copy(zeroes, 0, ptr, length);
- }
- }
-}
diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbBuffer.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbBuffer.cs
index 9ef1e0f7b90990..8aee8d41f5f28e 100644
--- a/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbBuffer.cs
+++ b/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbBuffer.cs
@@ -14,21 +14,12 @@ internal abstract class DbBuffer : SafeHandle
{
private readonly int _bufferLength;
- protected DbBuffer(int initialSize) : base(IntPtr.Zero, true)
+ protected unsafe DbBuffer(int initialSize) : base(IntPtr.Zero, true)
{
if (0 < initialSize)
{
_bufferLength = initialSize;
-
- try { }
- finally
- {
- base.handle = SafeNativeMethods.LocalAlloc((IntPtr)initialSize);
- }
- if (IntPtr.Zero == base.handle)
- {
- throw new OutOfMemoryException();
- }
+ base.handle = (IntPtr)NativeMemory.AllocZeroed((uint)initialSize);
}
}
@@ -368,15 +359,12 @@ internal unsafe float ReadSingle(int offset)
return BitConverter.Int32BitsToSingle(value);
}
- protected override bool ReleaseHandle()
+ protected override unsafe bool ReleaseHandle()
{
// NOTE: The SafeHandle class guarantees this will be called exactly once.
IntPtr ptr = base.handle;
base.handle = IntPtr.Zero;
- if (IntPtr.Zero != ptr)
- {
- SafeNativeMethods.LocalFree(ptr);
- }
+ NativeMemory.Free((void*)ptr);
return true;
}
@@ -639,7 +627,7 @@ internal unsafe void WriteSingle(int offset, float value)
WriteInt32(offset, BitConverter.SingleToInt32Bits(value));
}
- internal void ZeroMemory()
+ internal unsafe void ZeroMemory()
{
bool mustRelease = false;
@@ -648,7 +636,7 @@ internal void ZeroMemory()
DangerousAddRef(ref mustRelease);
IntPtr ptr = DangerousGetHandle();
- SafeNativeMethods.ZeroMemory(ptr, Length);
+ NativeMemory.Clear((void*)ptr, (uint)Length);
}
finally
{
diff --git a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj
index 56bcf649fcd4b3..0bcb60c92da190 100644
--- a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj
+++ b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj
@@ -42,7 +42,6 @@ System.Data.Odbc.OdbcTransaction
-
Date: Tue, 9 May 2023 15:31:49 +0100
Subject: [PATCH 2/3] Workaround lack of `NativeMemory.Clear` on .NET 6
---
.../System/Data/Common/SafeNativeMethods.cs | 21 +++++++++++++++++++
.../System/Data/ProviderBase/DbBuffer.cs | 4 ++--
.../src/System.Data.Odbc.csproj | 1 +
3 files changed, 24 insertions(+), 2 deletions(-)
create mode 100644 src/libraries/System.Data.Odbc/src/Common/System/Data/Common/SafeNativeMethods.cs
diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/SafeNativeMethods.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/SafeNativeMethods.cs
new file mode 100644
index 00000000000000..cf868366882b01
--- /dev/null
+++ b/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/SafeNativeMethods.cs
@@ -0,0 +1,21 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace System.Data
+{
+ internal static partial class SafeNativeMethods
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static unsafe void ZeroMemory(IntPtr ptr, int length)
+ {
+#if !NET7_0_OR_GREATER
+ new Span((void*)ptr, length).Clear();
+#else
+ NativeMemory.Clear((void*)ptr, (uint)length);
+#endif
+ }
+ }
+}
diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbBuffer.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbBuffer.cs
index 8aee8d41f5f28e..01be49419818a2 100644
--- a/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbBuffer.cs
+++ b/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbBuffer.cs
@@ -627,7 +627,7 @@ internal unsafe void WriteSingle(int offset, float value)
WriteInt32(offset, BitConverter.SingleToInt32Bits(value));
}
- internal unsafe void ZeroMemory()
+ internal void ZeroMemory()
{
bool mustRelease = false;
@@ -636,7 +636,7 @@ internal unsafe void ZeroMemory()
DangerousAddRef(ref mustRelease);
IntPtr ptr = DangerousGetHandle();
- NativeMemory.Clear((void*)ptr, (uint)Length);
+ SafeNativeMethods.ZeroMemory(ptr, Length);
}
finally
{
diff --git a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj
index 0bcb60c92da190..56bcf649fcd4b3 100644
--- a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj
+++ b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj
@@ -42,6 +42,7 @@ System.Data.Odbc.OdbcTransaction
+
Date: Tue, 9 May 2023 21:23:18 +0100
Subject: [PATCH 3/3] Use `Unsafe.InitBlock`
---
.../System/Data/Common/SafeNativeMethods.cs | 21 -------------------
.../System/Data/ProviderBase/DbBuffer.cs | 6 ++++--
.../src/System.Data.Odbc.csproj | 1 -
3 files changed, 4 insertions(+), 24 deletions(-)
delete mode 100644 src/libraries/System.Data.Odbc/src/Common/System/Data/Common/SafeNativeMethods.cs
diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/SafeNativeMethods.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/SafeNativeMethods.cs
deleted file mode 100644
index cf868366882b01..00000000000000
--- a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/SafeNativeMethods.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-namespace System.Data
-{
- internal static partial class SafeNativeMethods
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static unsafe void ZeroMemory(IntPtr ptr, int length)
- {
-#if !NET7_0_OR_GREATER
- new Span((void*)ptr, length).Clear();
-#else
- NativeMemory.Clear((void*)ptr, (uint)length);
-#endif
- }
- }
-}
diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbBuffer.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbBuffer.cs
index 01be49419818a2..541f1516eff598 100644
--- a/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbBuffer.cs
+++ b/src/libraries/System.Data.Odbc/src/Common/System/Data/ProviderBase/DbBuffer.cs
@@ -16,6 +16,8 @@ internal abstract class DbBuffer : SafeHandle
protected unsafe DbBuffer(int initialSize) : base(IntPtr.Zero, true)
{
+ Debug.Assert(initialSize % IntPtr.Size == 0, $"Expected aligned {nameof(initialSize)}.");
+
if (0 < initialSize)
{
_bufferLength = initialSize;
@@ -627,7 +629,7 @@ internal unsafe void WriteSingle(int offset, float value)
WriteInt32(offset, BitConverter.SingleToInt32Bits(value));
}
- internal void ZeroMemory()
+ internal unsafe void ZeroMemory()
{
bool mustRelease = false;
@@ -636,7 +638,7 @@ internal void ZeroMemory()
DangerousAddRef(ref mustRelease);
IntPtr ptr = DangerousGetHandle();
- SafeNativeMethods.ZeroMemory(ptr, Length);
+ Unsafe.InitBlock((void*)ptr, 0, (uint)Length);
}
finally
{
diff --git a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj
index 56bcf649fcd4b3..0bcb60c92da190 100644
--- a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj
+++ b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj
@@ -42,7 +42,6 @@ System.Data.Odbc.OdbcTransaction
-