Skip to content

Commit e2b9615

Browse files
committed
Refactoring pool state and cross-instance access.
1 parent 306efa5 commit e2b9615

File tree

6 files changed

+42
-38
lines changed

6 files changed

+42
-38
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@
8383
<Compile Include="$(CommonSourceRoot)Microsoft\Data\ProviderBase\DbConnectionPool.cs">
8484
<Link>Microsoft\Data\ProviderBase\DbConnectionPool.cs</Link>
8585
</Compile>
86+
<Compile Include="$(CommonSourceRoot)Microsoft\Data\ProviderBase\DbConnectionPoolState.cs">
87+
<Link>Microsoft\Data\ProviderBase\DbConnectionPoolState.cs</Link>
88+
</Compile>
8689
<Compile Include="$(CommonSourceRoot)Microsoft\Data\ProviderBase\DbConnectionInternal.cs">
8790
<Link>Microsoft\Data\ProviderBase\DbConnectionInternal.cs</Link>
8891
</Compile>

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,9 @@
271271
<Compile Include="$(CommonSourceRoot)Microsoft\Data\ProviderBase\DbConnectionPool.cs">
272272
<Link>Microsoft\Data\ProviderBase\DbConnectionPool.cs</Link>
273273
</Compile>
274+
<Compile Include="$(CommonSourceRoot)Microsoft\Data\ProviderBase\DbConnectionPoolState.cs">
275+
<Link>Microsoft\Data\ProviderBase\DbConnectionPoolState.cs</Link>
276+
</Compile>
274277
<Compile Include="$(CommonSourceRoot)Microsoft\Data\ProviderBase\DbConnectionPoolAuthenticationContext.cs">
275278
<Link>Microsoft\Data\ProviderBase\DbConnectionPoolAuthenticationContext.cs</Link>
276279
</Compile>

src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs

Lines changed: 14 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,12 @@
1515
using System.Transactions;
1616
using Microsoft.Data.Common;
1717
using Microsoft.Data.SqlClient;
18+
using static Microsoft.Data.ProviderBase.DbConnectionPoolState;
1819

1920
namespace Microsoft.Data.ProviderBase
2021
{
21-
internal sealed class DbConnectionPool : IDbConnectionPool
22+
internal sealed class WaitHandleDbConnectionPool : DbConnectionPool
2223
{
23-
private enum State
24-
{
25-
Initializing,
26-
Running,
27-
ShuttingDown,
28-
}
29-
3024
// This class is a way to stash our cloned Tx key for later disposal when it's no longer needed.
3125
// We can't get at the key in the dictionary without enumerating entries, so we stash an extra
3226
// copy as part of the value.
@@ -390,8 +384,6 @@ internal WaitHandle[] GetHandles(bool withCreate)
390384
/// </summary>
391385
private readonly ConcurrentDictionary<DbConnectionPoolAuthenticationContextKey, DbConnectionPoolAuthenticationContext> _pooledDbAuthenticationContexts;
392386

393-
private State _state;
394-
395387
private readonly ConcurrentStack<DbConnectionInternal> _stackOld = new ConcurrentStack<DbConnectionInternal>();
396388
private readonly ConcurrentStack<DbConnectionInternal> _stackNew = new ConcurrentStack<DbConnectionInternal>();
397389

@@ -417,7 +409,7 @@ internal WaitHandle[] GetHandles(bool withCreate)
417409
private int _totalObjects;
418410

419411
// only created by DbConnectionPoolGroup.GetConnectionPool
420-
internal DbConnectionPool(
412+
internal WaitHandleDbConnectionPool(
421413
DbConnectionFactory connectionFactory,
422414
DbConnectionPoolGroup connectionPoolGroup,
423415
DbConnectionPoolIdentity identity,
@@ -430,7 +422,7 @@ internal DbConnectionPool(
430422
throw ADP.InternalError(ADP.InternalErrorCode.AttemptingToPoolOnRestrictedToken);
431423
}
432424

433-
_state = State.Initializing;
425+
State = Initializing;
434426

435427
lock (s_random)
436428
{
@@ -457,7 +449,7 @@ internal DbConnectionPool(
457449
_transactedConnectionPool = new TransactedConnectionPool(this);
458450

459451
_poolCreateRequest = new WaitCallback(PoolCreateRequest); // used by CleanupCallback
460-
_state = State.Running;
452+
State = Running;
461453
SqlClientEventSource.Log.TryPoolerTraceEvent("<prov.DbConnectionPool.DbConnectionPool|RES|CPOOL> {0}, Constructed.", ObjectID);
462454

463455
//_cleanupTimer & QueuePoolCreateRequest is delayed until DbConnectionPoolGroup calls
@@ -498,7 +490,7 @@ private bool NeedToReplenish
498490
{
499491
get
500492
{
501-
if (State.Running != _state) // Don't allow connection create when not running.
493+
if (State != Running) // Don't allow connection create when not running.
502494
return false;
503495

504496
int totalObjects = Count;
@@ -524,7 +516,7 @@ internal override DbConnectionPoolIdentity Identity
524516

525517
internal override bool IsRunning
526518
{
527-
get { return State.Running == _state; }
519+
get { return State == Running; }
528520
}
529521

530522
private int MaxPoolSize
@@ -812,20 +804,6 @@ private DbConnectionInternal CreateObject(DbConnection owningObject, DbConnectio
812804
#endif
813805
}
814806

815-
// If the old connection belonged to another pool, we need to remove it from that
816-
if (oldConnection != null)
817-
{
818-
var oldConnectionPool = oldConnection.Pool;
819-
if (oldConnectionPool != null && oldConnectionPool != this)
820-
{
821-
Debug.Assert(oldConnectionPool._state == State.ShuttingDown, "Old connections pool should be shutting down");
822-
lock (oldConnectionPool._objectList)
823-
{
824-
oldConnectionPool._objectList.Remove(oldConnection);
825-
oldConnectionPool._totalObjects = oldConnectionPool._objectList.Count;
826-
}
827-
}
828-
}
829807
SqlClientEventSource.Log.TryPoolerTraceEvent("<prov.DbConnectionPool.CreateObject|RES|CPOOL> {0}, Connection {1}, Added to pool.", ObjectID, newObj?.ObjectID);
830808

831809
// Reset the error wait:
@@ -913,7 +891,7 @@ private void DeactivateObject(DbConnectionInternal obj)
913891
{
914892
// NOTE: constructor should ensure that current state cannot be State.Initializing, so it can only
915893
// be State.Running or State.ShuttingDown
916-
Debug.Assert(_state == State.Running || _state == State.ShuttingDown);
894+
Debug.Assert(State == Running || State == ShuttingDown);
917895

918896
lock (obj)
919897
{
@@ -923,7 +901,7 @@ private void DeactivateObject(DbConnectionInternal obj)
923901
// transaction object will ensure that it is owned (not lost),
924902
// and it will be certain to put it back into the pool.
925903

926-
if (_state == State.ShuttingDown)
904+
if (State == ShuttingDown)
927905
{
928906
if (obj.IsTransactionRoot)
929907
{
@@ -1237,7 +1215,7 @@ internal override bool TryGetConnection(DbConnection owningObject, TaskCompletio
12371215
allowCreate = true;
12381216
}
12391217

1240-
if (_state != State.Running)
1218+
if (State != Running)
12411219
{
12421220
SqlClientEventSource.Log.TryPoolerTraceEvent("<prov.DbConnectionPool.GetConnection|RES|CPOOL> {0}, DbConnectionInternal State != Running.", ObjectID);
12431221
connection = null;
@@ -1615,7 +1593,7 @@ private void PoolCreateRequest(object state)
16151593
long scopeID = SqlClientEventSource.Log.TryPoolerScopeEnterEvent("<prov.DbConnectionPool.PoolCreateRequest|RES|INFO|CPOOL> {0}", ObjectID);
16161594
try
16171595
{
1618-
if (State.Running == _state)
1596+
if (State == Running)
16191597
{
16201598
// in case WaitForPendingOpen ever failed with no subsequent OpenAsync calls,
16211599
// start it back up again
@@ -1804,7 +1782,7 @@ internal override void PutObjectFromTransactedPool(DbConnectionInternal obj)
18041782
// done and all transactions are ended.
18051783
SqlClientEventSource.Log.TryPoolerTraceEvent("<prov.DbConnectionPool.PutObjectFromTransactedPool|RES|CPOOL> {0}, Connection {1}, Transaction has ended.", ObjectID, obj.ObjectID);
18061784

1807-
if (_state == State.Running && obj.CanBePooled)
1785+
if (State == Running && obj.CanBePooled)
18081786
{
18091787
PutNewObject(obj);
18101788
}
@@ -1817,7 +1795,7 @@ internal override void PutObjectFromTransactedPool(DbConnectionInternal obj)
18171795

18181796
private void QueuePoolCreateRequest()
18191797
{
1820-
if (State.Running == _state)
1798+
if (State == Running)
18211799
{
18221800
// Make sure we're at quota by posting a callback to the threadpool.
18231801
ThreadPool.QueueUserWorkItem(_poolCreateRequest);
@@ -1908,7 +1886,7 @@ internal override void Startup()
19081886
internal override void Shutdown()
19091887
{
19101888
SqlClientEventSource.Log.TryPoolerTraceEvent("<prov.DbConnectionPool.Shutdown|RES|INFO|CPOOL> {0}", ObjectID);
1911-
_state = State.ShuttingDown;
1889+
State = ShuttingDown;
19121890

19131891
// deactivate timer callbacks
19141892
Timer t = _cleanupTimer;

src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionPoolGroup.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ internal DbConnectionPool GetConnectionPool(DbConnectionFactory connectionFactor
187187
if (!_poolCollection.TryGetValue(currentIdentity, out pool))
188188
{
189189
DbConnectionPoolProviderInfo connectionPoolProviderInfo = connectionFactory.CreateConnectionPoolProviderInfo(ConnectionOptions);
190-
DbConnectionPool newPool = new(connectionFactory, this, currentIdentity, connectionPoolProviderInfo);
190+
DbConnectionPool newPool = new WaitHandleDbConnectionPool(connectionFactory, this, currentIdentity, connectionPoolProviderInfo);
191191

192192
if (MarkPoolGroupAsActive())
193193
{
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
namespace Microsoft.Data.ProviderBase
6+
{
7+
internal enum DbConnectionPoolState
8+
{
9+
Initializing,
10+
Running,
11+
ShuttingDown,
12+
}
13+
}

src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/IDbConnectionPool.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
namespace Microsoft.Data.ProviderBase
1313
{
14-
internal abstract class IDbConnectionPool
14+
internal abstract class DbConnectionPool
1515
{
1616
private static int _objectTypeCount; // EventSource counter
1717
internal readonly int _objectID = System.Threading.Interlocked.Increment(ref _objectTypeCount);
@@ -24,6 +24,13 @@ internal int ObjectID
2424
}
2525
}
2626

27+
private DbConnectionPoolState _state;
28+
internal DbConnectionPoolState State
29+
{
30+
get => _state;
31+
set => _state = value;
32+
}
33+
2734
#region Abstract Properties
2835
internal abstract int Count
2936
{

0 commit comments

Comments
 (0)