You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
1.9 KiB
77 lines
1.9 KiB
// Needed for NET35 (ConditionalWeakTable) |
|
#if !NET_4_6 |
|
using System; |
|
using LinqInternal.Threading.Needles; |
|
|
|
namespace LinqInternal.Collections.ThreadSafe |
|
{ |
|
internal static class NeedleReservoir |
|
{ |
|
[ThreadStatic] |
|
internal static int InternalRecycling; |
|
|
|
public static bool Recycling |
|
{ |
|
get { return InternalRecycling > 0; } |
|
} |
|
} |
|
|
|
internal class NeedleReservoir<T, TNeedle> |
|
where TNeedle : class, IRecyclableNeedle<T> |
|
{ |
|
private readonly Func<T, TNeedle> _needleFactory; |
|
private readonly Pool<TNeedle> _pool; |
|
|
|
public NeedleReservoir(Func<T, TNeedle> needleFactory) |
|
{ |
|
if (needleFactory == null) |
|
{ |
|
throw new ArgumentNullException("needleFactory"); |
|
} |
|
_needleFactory = needleFactory; |
|
_pool = new Pool<TNeedle>(64, Recycle); |
|
} |
|
|
|
internal void DonateNeedle(TNeedle donation) |
|
{ |
|
if (!_pool.Donate(donation)) |
|
{ |
|
var disposable = donation as IDisposable; |
|
if (disposable != null) |
|
{ |
|
disposable.Dispose(); |
|
} |
|
} |
|
} |
|
|
|
internal TNeedle GetNeedle(T value) |
|
{ |
|
TNeedle result; |
|
if (_pool.TryGet(out result)) |
|
{ |
|
NeedleReservoir.InternalRecycling++; |
|
result.Value = value; |
|
NeedleReservoir.InternalRecycling--; |
|
} |
|
else |
|
{ |
|
result = _needleFactory(value); |
|
} |
|
return result; |
|
} |
|
|
|
private void Recycle(TNeedle obj) |
|
{ |
|
try |
|
{ |
|
NeedleReservoir.InternalRecycling++; |
|
obj.Free(); |
|
} |
|
finally |
|
{ |
|
NeedleReservoir.InternalRecycling--; |
|
} |
|
} |
|
} |
|
} |
|
#endif |