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.
72 lines
2.1 KiB
72 lines
2.1 KiB
5 years ago
|
// Needed for NET40
|
||
|
#if !NET_4_6
|
||
|
using System;
|
||
|
using LinqInternal.Threading;
|
||
|
|
||
|
namespace LinqInternal.Collections.ThreadSafe
|
||
|
{
|
||
|
internal class Pool<T>
|
||
|
where T : class
|
||
|
{
|
||
|
private readonly RuntimeUniqueIdProdiver.UniqueId _id;
|
||
|
private readonly FixedSizeQueue<T> _entries;
|
||
|
private readonly Action<T> _recycler;
|
||
|
|
||
|
public Pool(int capacity)
|
||
|
{
|
||
|
_id = RuntimeUniqueIdProdiver.GetNextId();
|
||
|
_entries = new FixedSizeQueue<T>(capacity);
|
||
|
_recycler = GC.KeepAlive;
|
||
|
}
|
||
|
|
||
|
public Pool(int capacity, Action<T> recycler)
|
||
|
{
|
||
|
if (recycler == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("recycler");
|
||
|
}
|
||
|
_id = RuntimeUniqueIdProdiver.GetNextId();
|
||
|
_entries = new FixedSizeQueue<T>(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
|