// Needed for NET40 #if !NET_4_6 using System; using LinqInternal.Threading; namespace LinqInternal.Collections.ThreadSafe { internal class Pool where T : class { private readonly RuntimeUniqueIdProdiver.UniqueId _id; private readonly FixedSizeQueue _entries; private readonly Action _recycler; public Pool(int capacity) { _id = RuntimeUniqueIdProdiver.GetNextId(); _entries = new FixedSizeQueue(capacity); _recycler = GC.KeepAlive; } public Pool(int capacity, Action recycler) { if (recycler == null) { throw new ArgumentNullException("recycler"); } _id = RuntimeUniqueIdProdiver.GetNextId(); _entries = new FixedSizeQueue(capacity); _recycler = recycler; } internal bool Donate(T entry) { // Assume anything could have been set to null, start no sync operation, this could be running during DomainUnload if (entry != null && ReentryGuardHelper.Enter(_id)) { try { var entries = _entries; var recycler = _recycler; if (entries != null && recycler != null) { recycler.Invoke(entry); entries.Add(entry); return true; } return false; } catch (InvalidOperationException exception) { GC.KeepAlive(exception); } catch (NullReferenceException exception) { GC.KeepAlive(exception); } finally { ReentryGuardHelper.Leave(_id); } } return false; } internal bool TryGet(out T result) { return _entries.TryTake(out result); } } } #endif