Skip to content

Commit 0c5155d

Browse files
authored
Merge | TdsParserStateObject PacketHandle usage (#3353)
* Port PacketHandle to netfx * Remove PacketHandle alias shim * Align netfx use of PacketHandle * Add high-level summary of PacketHandle types
1 parent 9ef7f78 commit 0c5155d

File tree

9 files changed

+119
-58
lines changed

9 files changed

+119
-58
lines changed

src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -878,8 +878,8 @@
878878
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\LocalDb\LocalDbApi.Windows.cs">
879879
<Link>Microsoft\Data\SqlClient\LocalDb\LocalDbApi.Windows.cs</Link>
880880
</Compile>
881-
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\PacketHandle.netcore.Windows.cs">
882-
<Link>Microsoft\Data\SqlClient\PacketHandle.netcore.Windows.cs</Link>
881+
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\PacketHandle.Windows.cs">
882+
<Link>Microsoft\Data\SqlClient\PacketHandle.Windows.cs</Link>
883883
</Compile>
884884
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\SessionHandle.Windows.cs">
885885
<Link>Microsoft\Data\SqlClient\SessionHandle.Windows.cs</Link>

src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,9 @@
447447
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\Packet.cs">
448448
<Link>Microsoft\Data\SqlClient\Packet.cs</Link>
449449
</Compile>
450+
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\PacketHandle.Windows.cs">
451+
<Link>Microsoft\Data\SqlClient\PacketHandle.Windows.cs</Link>
452+
</Compile>
450453
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ParameterPeekAheadValue.cs">
451454
<Link>Microsoft\Data\SqlClient\ParameterPeekAheadValue.cs</Link>
452455
</Compile>

src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserStateObject.netfx.cs

Lines changed: 67 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818

1919
namespace Microsoft.Data.SqlClient
2020
{
21-
using PacketHandle = IntPtr;
22-
2321
internal partial class TdsParserStateObject
2422
{
2523
protected SNIHandle _sessionHandle = null; // the SNI handle we're to work on
@@ -138,27 +136,35 @@ internal void CreatePhysicalSNIHandle(
138136
ipPreference, cachedDNSInfo, hostNameInCertificate);
139137
}
140138

141-
internal bool IsPacketEmpty(PacketHandle readPacket) => readPacket == default;
139+
internal bool IsPacketEmpty(PacketHandle readPacket)
140+
{
141+
Debug.Assert(readPacket.Type == PacketHandle.NativePointerType || readPacket.Type == 0, "unexpected packet type when requiring NativePointer");
142+
return IntPtr.Zero == readPacket.NativePointer;
143+
}
142144

143145
internal PacketHandle ReadSyncOverAsync(int timeoutRemaining, out uint error)
144146
{
145147
SNIHandle handle = Handle ?? throw ADP.ClosedConnectionError();
146-
PacketHandle readPacket = default;
147-
error = SniNativeWrapper.SniReadSyncOverAsync(handle, ref readPacket, timeoutRemaining);
148-
return readPacket;
148+
IntPtr readPacketPtr = IntPtr.Zero;
149+
error = SniNativeWrapper.SniReadSyncOverAsync(handle, ref readPacketPtr, timeoutRemaining);
150+
return PacketHandle.FromNativePointer(readPacketPtr);
149151
}
150152

151153
internal PacketHandle ReadAsync(SessionHandle handle, out uint error)
152154
{
153-
PacketHandle readPacket = default;
154-
error = SniNativeWrapper.SniReadAsync(handle.NativeHandle, ref readPacket);
155-
return readPacket;
155+
IntPtr readPacketPtr = IntPtr.Zero;
156+
error = SniNativeWrapper.SniReadAsync(handle.NativeHandle, ref readPacketPtr);
157+
return PacketHandle.FromNativePointer(readPacketPtr);
156158
}
157159

158160
internal uint CheckConnection() => SniNativeWrapper.SniCheckConnection(Handle);
159161

160-
internal void ReleasePacket(PacketHandle syncReadPacket) => SniNativeWrapper.SniPacketRelease(syncReadPacket);
161-
162+
internal void ReleasePacket(PacketHandle syncReadPacket)
163+
{
164+
Debug.Assert(syncReadPacket.Type == PacketHandle.NativePointerType, "unexpected packet type when requiring NativePointer");
165+
SniNativeWrapper.SniPacketRelease(syncReadPacket.NativePointer);
166+
}
167+
162168
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
163169
internal int DecrementPendingCallbacks(bool release)
164170
{
@@ -377,7 +383,13 @@ private void ReadSniError(TdsParserStateObject stateObj, uint error)
377383

378384
private uint GetSniPacket(PacketHandle packet, ref uint dataSize)
379385
{
380-
return SniNativeWrapper.SniPacketGetData(packet, _inBuff, ref dataSize);
386+
return SniPacketGetData(packet, _inBuff, ref dataSize);
387+
}
388+
389+
private uint SniPacketGetData(PacketHandle packet, byte[] _inBuff, ref uint dataSize)
390+
{
391+
Debug.Assert(packet.Type == PacketHandle.NativePointerType, "unexpected packet type when requiring NativePointer");
392+
return SniNativeWrapper.SniPacketGetData(packet.NativePointer, _inBuff, ref dataSize);
381393
}
382394

383395
public void ReadAsyncCallback(IntPtr key, PacketHandle packet, uint error)
@@ -411,7 +423,7 @@ public void ReadAsyncCallback(IntPtr key, PacketHandle packet, uint error)
411423
bool processFinallyBlock = true;
412424
try
413425
{
414-
Debug.Assert(IntPtr.Zero == packet || IntPtr.Zero != packet && source != null, "AsyncResult null on callback");
426+
Debug.Assert(CheckPacket(packet, source), "AsyncResult null on callback");
415427

416428
if (_parser.MARSOn)
417429
{
@@ -481,6 +493,13 @@ public void ReadAsyncCallback(IntPtr key, PacketHandle packet, uint error)
481493
}
482494
}
483495

496+
private bool CheckPacket(PacketHandle packet, TaskCompletionSource<object> source)
497+
{
498+
Debug.Assert(packet.Type == PacketHandle.NativePointerType, "unexpected packet type when requiring NativePointer");
499+
IntPtr ptr = packet.NativePointer;
500+
return IntPtr.Zero == ptr || IntPtr.Zero != ptr && source != null;
501+
}
502+
484503
#pragma warning disable 420 // a reference to a volatile field will not be treated as volatile
485504

486505
public void WriteAsyncCallback(IntPtr key, PacketHandle packet, uint sniError)
@@ -654,7 +673,7 @@ internal Task WritePacket(byte flushMode, bool canAccumulate = false)
654673

655674
#pragma warning disable 420 // a reference to a volatile field will not be treated as volatile
656675

657-
private Task SNIWritePacket(SNIPacket packet, out uint sniError, bool canAccumulate, bool callerHasConnectionLock, bool asyncClose = false)
676+
private Task SNIWritePacket(PacketHandle packet, out uint sniError, bool canAccumulate, bool callerHasConnectionLock, bool asyncClose = false)
658677
{
659678
// Check for a stored exception
660679
Exception delayedException = Interlocked.Exchange(ref _delayedWriteAsyncCallbackException, null);
@@ -696,7 +715,8 @@ private Task SNIWritePacket(SNIPacket packet, out uint sniError, bool canAccumul
696715
}
697716
finally
698717
{
699-
sniError = SniNativeWrapper.SniWritePacket(Handle, packet, sync);
718+
Debug.Assert(packet.Type == PacketHandle.NativePacketType, "unexpected packet type when requiring NativePacket");
719+
sniError = SniNativeWrapper.SniWritePacket(Handle, packet.NativePacket, sync);
700720
}
701721

702722
if (sniError == TdsEnums.SNI_SUCCESS_IO_PENDING)
@@ -790,7 +810,15 @@ private Task SNIWritePacket(SNIPacket packet, out uint sniError, bool canAccumul
790810

791811
#pragma warning restore 420
792812

793-
internal bool IsValidPacket(PacketHandle packetPointer) => packetPointer != default;
813+
internal bool IsValidPacket(PacketHandle packetPointer)
814+
{
815+
Debug.Assert(packetPointer.Type == PacketHandle.NativePointerType || packetPointer.Type == PacketHandle.NativePacketType, "unexpected packet type when requiring NativePointer");
816+
return (
817+
(packetPointer.Type == PacketHandle.NativePointerType && packetPointer.NativePointer != IntPtr.Zero)
818+
||
819+
(packetPointer.Type == PacketHandle.NativePacketType && packetPointer.NativePacket != null)
820+
);
821+
}
794822

795823
// Sends an attention signal - executing thread will consume attn.
796824
internal void SendAttention(bool mustTakeWriteLock = false, bool asyncClose = false)
@@ -805,10 +833,7 @@ internal void SendAttention(bool mustTakeWriteLock = false, bool asyncClose = fa
805833
return;
806834
}
807835

808-
SNIPacket attnPacket = new SNIPacket(Handle);
809-
_sniAsyncAttnPacket = attnPacket;
810-
811-
SniNativeWrapper.SniPacketSetData(attnPacket, SQL.AttentionHeader, TdsEnums.HEADER_LEN, null, null);
836+
PacketHandle attnPacket = CreateAndSetAttentionPacket();
812837

813838
RuntimeHelpers.PrepareConstrainedRegions();
814839
try
@@ -868,11 +893,20 @@ internal void SendAttention(bool mustTakeWriteLock = false, bool asyncClose = fa
868893
}
869894
}
870895

896+
internal PacketHandle CreateAndSetAttentionPacket()
897+
{
898+
SNIPacket attnPacket = new SNIPacket(Handle);
899+
_sniAsyncAttnPacket = attnPacket;
900+
SniNativeWrapper.SniPacketSetData(attnPacket, SQL.AttentionHeader, TdsEnums.HEADER_LEN, null, null);
901+
return PacketHandle.FromNativePacket(attnPacket);
902+
}
903+
871904
private Task WriteSni(bool canAccumulate)
872905
{
873906
// Prepare packet, and write to packet.
874-
SNIPacket packet = GetResetWritePacket();
875-
SniNativeWrapper.SniPacketSetData(packet, _outBuff, _outBytesUsed, _securePasswords, _securePasswordOffsetsInBuffer);
907+
PacketHandle packet = GetResetWritePacket();
908+
SNIPacket nativePacket = packet.NativePacket;
909+
SniNativeWrapper.SniPacketSetData(nativePacket, _outBuff, _outBytesUsed, _securePasswords, _securePasswordOffsetsInBuffer);
876910

877911
Debug.Assert(Parser.Connection._parserLock.ThreadMayHaveLock(), "Thread is writing without taking the connection lock");
878912
Task task = SNIWritePacket(packet, out _, canAccumulate, callerHasConnectionLock: true);
@@ -923,7 +957,7 @@ private Task WriteSni(bool canAccumulate)
923957
return task;
924958
}
925959

926-
internal SNIPacket GetResetWritePacket()
960+
internal PacketHandle GetResetWritePacket()
927961
{
928962
if (_sniPacket != null)
929963
{
@@ -936,7 +970,7 @@ internal SNIPacket GetResetWritePacket()
936970
_sniPacket = _writePacketCache.Take(Handle);
937971
}
938972
}
939-
return _sniPacket;
973+
return PacketHandle.FromNativePacket(_sniPacket);
940974
}
941975

942976
internal void ClearAllWritePackets()
@@ -953,8 +987,10 @@ internal void ClearAllWritePackets()
953987
}
954988
}
955989

956-
private IntPtr AddPacketToPendingList(SNIPacket packet)
990+
private PacketHandle AddPacketToPendingList(PacketHandle packetToAdd)
957991
{
992+
Debug.Assert(packetToAdd.Type == PacketHandle.NativePacketType, "unexpected packet type when requiring NativePacket");
993+
SNIPacket packet = packetToAdd.NativePacket;
958994
Debug.Assert(packet == _sniPacket, "Adding a packet other than the current packet to the pending list");
959995
_sniPacket = null;
960996
IntPtr pointer = packet.DangerousGetHandle();
@@ -964,16 +1000,17 @@ private IntPtr AddPacketToPendingList(SNIPacket packet)
9641000
_pendingWritePackets.Add(pointer, packet);
9651001
}
9661002

967-
return pointer;
1003+
return PacketHandle.FromNativePointer(pointer);
9681004
}
9691005

970-
private void RemovePacketFromPendingList(IntPtr pointer)
1006+
private void RemovePacketFromPendingList(PacketHandle ptr)
9711007
{
972-
SNIPacket recoveredPacket;
1008+
Debug.Assert(ptr.Type == PacketHandle.NativePointerType, "unexpected packet type when requiring NativePointer");
1009+
IntPtr pointer = ptr.NativePointer;
9731010

9741011
lock (_writePacketLockObject)
9751012
{
976-
if (_pendingWritePackets.TryGetValue(pointer, out recoveredPacket))
1013+
if (_pendingWritePackets.TryGetValue(pointer, out SNIPacket recoveredPacket))
9771014
{
9781015
_pendingWritePackets.Remove(pointer);
9791016
_writePacketCache.Add(recoveredPacket);
@@ -1033,6 +1070,6 @@ private void SniWriteStatisticsAndTracing()
10331070
SqlClientEventSource.Log.TryAdvancedTraceBinEvent("TdsParser.WritePacket | INFO | ADV | State Object Id {0}, Packet sent. Out buffer: {1}, Out Bytes Used: {2}", ObjectID, _outBuff, _outBytesUsed);
10341071
}
10351072

1036-
protected PacketHandle EmptyReadPacket => default;
1073+
protected PacketHandle EmptyReadPacket => PacketHandle.FromNativePointer(default);
10371074
}
10381075
}

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netcore.Windows.cs renamed to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.Windows.cs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5-
#if NET
6-
75
using System;
86

97
namespace Microsoft.Data.SqlClient
@@ -20,23 +18,49 @@ namespace Microsoft.Data.SqlClient
2018

2119
internal readonly ref struct PacketHandle
2220
{
21+
/// <summary>
22+
/// PacketHandle is transporting a native pointer. The NativePointer field is valid.
23+
/// A PacketHandle has this type when managed code is referencing a pointer to a
24+
/// packet which has been read from the native SNI layer.
25+
/// </summary>
2326
public const int NativePointerType = 1;
27+
/// <summary>
28+
/// PacketHandle is transporting a native packet. The NativePacket field is valid.
29+
/// A PacketHandle has this type when managed code is directly referencing a packet
30+
/// which is due to be passed to the native SNI layer.
31+
/// </summary>
2432
public const int NativePacketType = 2;
33+
#if NET
34+
/// <summary>
35+
/// PacketHandle is transporting a managed packet. The ManagedPacket field is valid.
36+
/// A PacketHandle used by the managed SNI layer will always have this type.
37+
/// </summary>
2538
public const int ManagedPacketType = 3;
2639

2740
public readonly SNI.SNIPacket ManagedPacket;
41+
#endif
2842
public readonly SNIPacket NativePacket;
2943
public readonly IntPtr NativePointer;
3044
public readonly int Type;
3145

46+
#if NET
3247
private PacketHandle(IntPtr nativePointer, SNIPacket nativePacket, SNI.SNIPacket managedPacket, int type)
3348
{
3449
Type = type;
3550
ManagedPacket = managedPacket;
3651
NativePointer = nativePointer;
3752
NativePacket = nativePacket;
3853
}
54+
#else
55+
private PacketHandle(IntPtr nativePointer, SNIPacket nativePacket, int type)
56+
{
57+
Type = type;
58+
NativePointer = nativePointer;
59+
NativePacket = nativePacket;
60+
}
61+
#endif
3962

63+
#if NET
4064
public static PacketHandle FromManagedPacket(SNI.SNIPacket managedPacket) =>
4165
new PacketHandle(default, default, managedPacket, ManagedPacketType);
4266

@@ -45,9 +69,12 @@ public static PacketHandle FromNativePointer(IntPtr nativePointer) =>
4569

4670
public static PacketHandle FromNativePacket(SNIPacket nativePacket) =>
4771
new PacketHandle(default, nativePacket, default, NativePacketType);
72+
#else
73+
public static PacketHandle FromNativePointer(IntPtr nativePointer) =>
74+
new PacketHandle(nativePointer, default, NativePointerType);
4875

49-
76+
public static PacketHandle FromNativePacket(SNIPacket nativePacket) =>
77+
new PacketHandle(default, nativePacket, NativePacketType);
78+
#endif
5079
}
5180
}
52-
53-
#endif

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netcore.Unix.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,22 @@ namespace Microsoft.Data.SqlClient
1818

1919
internal readonly ref struct PacketHandle
2020
{
21+
/// <summary>
22+
/// PacketHandle is transporting a native pointer. The NativePointer field is valid.
23+
/// A PacketHandle has this type when managed code is referencing a pointer to a
24+
/// packet which has been read from the native SNI layer.
25+
/// </summary>
2126
public const int NativePointerType = 1;
27+
/// <summary>
28+
/// PacketHandle is transporting a native packet. The NativePacket field is valid.
29+
/// A PacketHandle has this type when managed code is directly referencing a packet
30+
/// which is due to be passed to the native SNI layer.
31+
/// </summary>
2232
public const int NativePacketType = 2;
33+
/// <summary>
34+
/// PacketHandle is transporting a managed packet. The ManagedPacket field is valid.
35+
/// A PacketHandle used by the managed SNI layer will always have this type.
36+
/// </summary>
2337
public const int ManagedPacketType = 3;
2438

2539
public readonly SNI.SNIPacket ManagedPacket;

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.Windows.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,7 @@ private static void ReadDispatcher(IntPtr key, IntPtr packet, uint error)
107107

108108
if (stateObj != null)
109109
{
110-
#if NETFRAMEWORK
111-
stateObj.ReadAsyncCallback(IntPtr.Zero, packet, error);
112-
#else
113110
stateObj.ReadAsyncCallback(IntPtr.Zero, PacketHandle.FromNativePointer(packet), error);
114-
#endif // NETFRAMEWORK
115111
}
116112
}
117113
}
@@ -132,11 +128,7 @@ private static void WriteDispatcher(IntPtr key, IntPtr packet, uint error)
132128

133129
if (stateObj != null)
134130
{
135-
#if NETFRAMEWORK
136-
stateObj.WriteAsyncCallback(IntPtr.Zero, packet, error);
137-
#else
138131
stateObj.WriteAsyncCallback(IntPtr.Zero, PacketHandle.FromNativePointer(packet), error);
139-
#endif // NETFRAMEWORK
140132
}
141133
}
142134
}

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.Multiplexer.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77

88
namespace Microsoft.Data.SqlClient
99
{
10-
#if NETFRAMEWORK
11-
using PacketHandle = IntPtr;
12-
#endif
1310
partial class TdsParserStateObject
1411
{
1512
private Packet _partialPacket;
@@ -513,12 +510,7 @@ public void ProcessSniPacketCompat(PacketHandle packet, uint error)
513510
else
514511
{
515512
uint dataSize = 0;
516-
517-
#if NETFRAMEWORK
518-
uint getDataError = SniNativeWrapper.SniPacketGetData(packet, _inBuff, ref dataSize);
519-
#else
520513
uint getDataError = SniPacketGetData(packet, _inBuff, ref dataSize);
521-
#endif
522514

523515
if (getDataError == TdsEnums.SNI_SUCCESS)
524516
{

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
namespace Microsoft.Data.SqlClient
2020
{
2121
#if NETFRAMEWORK
22-
using PacketHandle = IntPtr;
2322
using RuntimeHelpers = System.Runtime.CompilerServices.RuntimeHelpers;
2423
#endif
2524

0 commit comments

Comments
 (0)