1+ using System ;
12using System . Collections . Generic ;
3+ using System . Runtime . CompilerServices ;
24using System . Threading ;
35using Microsoft . Extensions . ObjectPool ;
46
@@ -14,17 +16,36 @@ public ConcurrentObjectPool() : base(new())
1416
1517 internal class ConcurrentObjectPool < T , TPoolPolicy > : ObjectPool < T > where T : class where TPoolPolicy : IPooledObjectPolicy < T >
1618 {
17- private readonly ThreadLocal < Stack < T > > _objects = new ( ( ) => new ( ) ) ;
19+ private static int NextPoolId = - 1 ;
1820
21+ private readonly int _poolId = Interlocked . Increment ( ref NextPoolId ) ;
1922 private readonly TPoolPolicy _policy ;
2023
2124 public ConcurrentObjectPool ( TPoolPolicy policy ) => _policy = policy ;
2225
2326 public int MaxPoolSize { get ; set ; } = int . MaxValue ;
2427
28+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
29+ private Stack < T > GetStack ( )
30+ {
31+ var poolId = _poolId ;
32+ var stacks = PerThreadStack . Stacks ;
33+ if ( stacks is null )
34+ {
35+ stacks = PerThreadStack . Stacks = new Stack < T > [ poolId + 1 ] ;
36+ }
37+ else if ( ( uint ) poolId >= ( uint ) stacks . Length )
38+ {
39+ Array . Resize ( ref stacks , Math . Max ( poolId + 1 , stacks . Length * 2 ) ) ;
40+ PerThreadStack . Stacks = stacks ;
41+ }
42+
43+ return stacks [ poolId ] ??= new ( ) ;
44+ }
45+
2546 public override T Get ( )
2647 {
27- var stack = _objects . Value ;
48+ var stack = GetStack ( ) ;
2849 if ( stack . TryPop ( out var result ) )
2950 {
3051 return result ;
@@ -37,12 +58,19 @@ public override void Return(T obj)
3758 {
3859 if ( _policy . Return ( obj ) )
3960 {
40- var stack = _objects . Value ;
61+ var stack = GetStack ( ) ;
4162 if ( stack . Count < MaxPoolSize )
4263 {
4364 stack . Push ( obj ) ;
4465 }
4566 }
4667 }
68+
69+ // Thread-static stacks are indexed by pool instance to avoid sharing state between pools with different policies.
70+ private static class PerThreadStack
71+ {
72+ [ ThreadStatic ]
73+ internal static Stack < T > [ ] Stacks ;
74+ }
4775 }
4876}
0 commit comments