Optimize SqlClient connection pool performance (dotnet/corefx#33580)
authorWraith2 <Wraith2@users.noreply.github.com>
Tue, 18 Dec 2018 18:12:55 +0000 (18:12 +0000)
committerSaurabh Singh <saurabh.singh@microsoft.com>
Tue, 18 Dec 2018 18:12:55 +0000 (10:12 -0800)
* change pool to fetch user object only once and use direct tostirng
change SSPI login buffers to arraypool allocations

* change rental to keep track of rented array in case the caller reassigns

* address feedback

Commit migrated from https://github.com/dotnet/corefx/commit/9b6618f3883443bd52379471e5e0c1b96ebde2bd

src/libraries/System.Data.SqlClient/src/System/Data/ProviderBase/DbConnectionPoolIdentity.Windows.cs
src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/TdsParser.cs

index 8c398a0..363e79f 100644 (file)
@@ -22,8 +22,9 @@ namespace System.Data.ProviderBase
             using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
             {
                 IntPtr token = identity.AccessToken.DangerousGetHandle();
-                bool isNetwork = identity.User.IsWellKnown(WellKnownSidType.NetworkSid);
-                string sidString = identity.User.Value;
+                SecurityIdentifier user = identity.User;
+                bool isNetwork = user.IsWellKnown(WellKnownSidType.NetworkSid);
+                string sidString = user.Value;
 
                 // Win32NativeMethods.IsTokenRestricted will raise exception if the native call fails
                 bool isRestricted = Win32NativeMethods.IsTokenRestrictedWrapper(token);
index abd90e3..2c23b08 100644 (file)
@@ -3,6 +3,7 @@
 // See the LICENSE file in the project root for more information.
 
 using System.Collections.Generic;
+using System.Buffers;
 using System.Data.Common;
 using System.Data.Sql;
 using System.Data.SqlTypes;
@@ -6203,6 +6204,7 @@ namespace System.Data.SqlClient
             }
 
             // allocate memory for SSPI variables
+            byte[] rentedSSPIBuff = null;
             byte[] outSSPIBuff = null;
             uint outSSPILength = 0;
 
@@ -6220,7 +6222,8 @@ namespace System.Data.SqlClient
                 if (rec.useSSPI)
                 {
                     // now allocate proper length of buffer, and set length
-                    outSSPIBuff = new byte[s_maxSSPILength];
+                    rentedSSPIBuff = ArrayPool<byte>.Shared.Rent((int)s_maxSSPILength);
+                    outSSPIBuff = rentedSSPIBuff;
                     outSSPILength = s_maxSSPILength;
 
                     // Call helper function for SSPI data and actual length.
@@ -6528,6 +6531,11 @@ namespace System.Data.SqlClient
                 throw;
             }
 
+            if (rentedSSPIBuff != null)
+            {
+                ArrayPool<byte>.Shared.Return(rentedSSPIBuff, clearArray: true);
+            }
+
             _physicalStateObj.WritePacket(TdsEnums.HARDFLUSH);
             _physicalStateObj.ResetSecurePasswordsInformation();
             _physicalStateObj._pendingData = true;
@@ -6582,7 +6590,8 @@ namespace System.Data.SqlClient
             if (!result) { throw SQL.SynchronousCallMayNotPend(); }
 
             // allocate send buffer and initialize length
-            byte[] sendBuff = new byte[s_maxSSPILength];
+            byte[] rentedSendBuff = ArrayPool<byte>.Shared.Rent((int)s_maxSSPILength);
+            byte[] sendBuff = rentedSendBuff;
             uint sendLength = s_maxSSPILength;
 
             // make call for SSPI data
@@ -6592,6 +6601,8 @@ namespace System.Data.SqlClient
             // DO NOT SEND LENGTH - TDS DOC INCORRECT!  JUST SEND SSPI DATA!
             _physicalStateObj.WriteByteArray(sendBuff, (int)sendLength, 0);
 
+            ArrayPool<byte>.Shared.Return(rentedSendBuff, clearArray: true);
+
             // set message type so server knows its a SSPI response
             _physicalStateObj._outputMessageType = TdsEnums.MT_SSPI;