// 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 where TNeedle : class, IRecyclableNeedle { private readonly Func _needleFactory; private readonly Pool _pool; public NeedleReservoir(Func needleFactory) { if (needleFactory == null) { throw new ArgumentNullException("needleFactory"); } _needleFactory = needleFactory; _pool = new Pool(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