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.
Zero/ZeroLevel/Services/MemoryPools/DisposableObjectPool.cs

93 lines
2.4 KiB

using System;
using System.Threading;
/*https://github.com/dotnet/aspnetcore/blob/main/src/ObjectPool*/
namespace MemoryPools
{
internal sealed class DisposableObjectPool<T>
: DefaultObjectPool<T>, IDisposable where T : class
{
private volatile bool _isDisposed;
public DisposableObjectPool(IPooledObjectPolicy<T> policy)
: base(policy)
{
}
public DisposableObjectPool(IPooledObjectPolicy<T> policy, int maximumRetained)
: base(policy, maximumRetained)
{
}
public override T Get()
{
if (_isDisposed)
{
ThrowObjectDisposedException();
}
return base.Get();
void ThrowObjectDisposedException()
{
throw new ObjectDisposedException(GetType().Name);
}
}
public override void Return(T obj)
{
// When the pool is disposed or the obj is not returned to the pool, dispose it
if (_isDisposed || !ReturnCore(obj))
{
DisposeItem(obj);
}
}
private bool ReturnCore(T obj)
{
bool returnedTooPool = false;
if (_isDefaultPolicy || (_fastPolicy?.Return(obj) ?? _policy.Return(obj)))
{
if (_firstItem == null && Interlocked.CompareExchange(ref _firstItem, obj, null) == null)
{
returnedTooPool = true;
}
else
{
var items = _items;
for (var i = 0; i < items.Length && !(returnedTooPool = Interlocked.CompareExchange(ref items[i].Element, obj, null) == null); i++)
{
}
}
}
return returnedTooPool;
}
public void Dispose()
{
_isDisposed = true;
DisposeItem(_firstItem);
_firstItem = null;
ObjectWrapper[] items = _items;
for (var i = 0; i < items.Length; i++)
{
DisposeItem(items[i].Element);
items[i].Element = null;
}
}
private static void DisposeItem(T? item)
{
if (item is IDisposable disposable)
{
disposable.Dispose();
}
}
}
}

Powered by TurnKey Linux.