/// <summary> /// Extract the first available entry from the pool or (unless restrained) a new one /// </summary> [CanBeNull] public T Retain() { T instance = null; for (int index = 0; index < m_Size; ++index) { instance = m_Pool[index]; if (instance == null) { continue; } if (Interlocked.CompareExchange(ref m_Pool[index], null, instance) == instance) { Interlocked.Decrement(ref m_Stored); break; } instance = null; } bool reuse = instance != null; if (!reuse) { instance = RetainDefault; } // Special treatment of PoolItem - marking as live, issuing callback PoolItem poolItem = instance as PoolItem; if (poolItem != null) { poolItem.Live = 1; poolItem.OnRetained(reuse); } return(instance); }
/// <summary> /// Release pool item, adding it the pool if it fits /// </summary> /// <returns>Whether the released item was added to the pool</returns> public bool Release(T instance) { if (instance == null) { return(false); } // Special treatment of PoolItem - taking special care to not double-release, issuing callback PoolItem poolItem = instance as PoolItem; if (poolItem != null) { if (0 == Interlocked.CompareExchange(ref poolItem.Live, 0, 1)) // If we were already not live, we should do nothing here { return(true); } poolItem.OnRelease(); } return(Add(instance)); }