Skip to content

Commit 951eb6d

Browse files
authored
Managed SNI prevent orphaned active packets being GC'ed without clear (#888)
1 parent 9e3f0d6 commit 951eb6d

File tree

2 files changed

+29
-9
lines changed

2 files changed

+29
-9
lines changed

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIPacket.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
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-
// #define TRACE_HISTORY // this is used for advanced debugging when you need to trace the entire lifetime of a single packet, be very careful with it
5+
// #define TRACE_HISTORY // this is used for advanced debugging when you need to trace the entire lifetime of a single packet, be very careful with it
66

77
using System;
88
using System.Buffers;
@@ -41,15 +41,15 @@ internal struct History
4141
{
4242
public enum Direction
4343
{
44-
Rent=0,
45-
Return=1,
44+
Rent = 0,
45+
Return = 1,
4646
}
4747

4848
public Direction Action;
4949
public int RefCount;
5050
public string Stack;
5151
}
52-
52+
5353
internal List<History> _history = null;
5454

5555
/// <summary>
@@ -62,7 +62,7 @@ public SNIPacket(SNIHandle owner,int id)
6262
: this()
6363
{
6464
#if TRACE_HISTORY
65-
_history = new List<Activity>();
65+
_history = new List<History>();
6666
#endif
6767
_id = id;
6868
_owner = owner;

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,34 @@ internal override void AssignPendingDNSInfo(string userProtocol, string DNSCache
7171

7272
internal void ReadAsyncCallback(SNIPacket packet, uint error)
7373
{
74-
ReadAsyncCallback(IntPtr.Zero, PacketHandle.FromManagedPacket(packet), error);
75-
_sessionHandle?.ReturnPacket(packet);
74+
SNIHandle sessionHandle = _sessionHandle;
75+
if (sessionHandle != null)
76+
{
77+
ReadAsyncCallback(IntPtr.Zero, PacketHandle.FromManagedPacket(packet), error);
78+
sessionHandle?.ReturnPacket(packet);
79+
}
80+
else
81+
{
82+
// clear the packet and drop it to GC because we no longer know how to return it to the correct owner
83+
// this can only happen if a packet is in-flight when the _sessionHandle is cleared
84+
packet.Release();
85+
}
7686
}
7787

7888
internal void WriteAsyncCallback(SNIPacket packet, uint sniError)
7989
{
80-
WriteAsyncCallback(IntPtr.Zero, PacketHandle.FromManagedPacket(packet), sniError);
81-
_sessionHandle?.ReturnPacket(packet);
90+
SNIHandle sessionHandle = _sessionHandle;
91+
if (sessionHandle != null)
92+
{
93+
WriteAsyncCallback(IntPtr.Zero, PacketHandle.FromManagedPacket(packet), sniError);
94+
sessionHandle?.ReturnPacket(packet);
95+
}
96+
else
97+
{
98+
// clear the packet and drop it to GC because we no longer know how to return it to the correct owner
99+
// this can only happen if a packet is in-flight when the _sessionHandle is cleared
100+
packet.Release();
101+
}
82102
}
83103

84104
protected override void RemovePacketFromPendingList(PacketHandle packet)

0 commit comments

Comments
 (0)