FurinaImpact/FurinaImpact.Kcp/KcpSendReceiveBufferItemCache.cs
2023-12-09 06:45:08 +03:00

73 lines
2.1 KiB
C#

#if NEED_LINKEDLIST_SHIM
using LinkedListOfBufferItem = KcpSharp.NetstandardShim.LinkedList<KcpSharp.KcpSendReceiveBufferItem>;
using LinkedListNodeOfBufferItem = KcpSharp.NetstandardShim.LinkedListNode<KcpSharp.KcpSendReceiveBufferItem>;
#else
using LinkedListNodeOfBufferItem = System.Collections.Generic.LinkedListNode<FurinaImpact.Kcp.KcpSendReceiveBufferItem>;
using LinkedListOfBufferItem = System.Collections.Generic.LinkedList<FurinaImpact.Kcp.KcpSendReceiveBufferItem>;
#endif
namespace FurinaImpact.Kcp
{
internal struct KcpSendReceiveBufferItemCache
{
private LinkedListOfBufferItem _items;
private SpinLock _lock;
public static KcpSendReceiveBufferItemCache Create()
{
return new KcpSendReceiveBufferItemCache
{
_items = new LinkedListOfBufferItem(),
_lock = new SpinLock()
};
}
public LinkedListNodeOfBufferItem Allocate(in KcpSendReceiveBufferItem item)
{
bool lockAcquired = false;
try
{
_lock.Enter(ref lockAcquired);
LinkedListNodeOfBufferItem node = _items.First;
if (node is null)
{
node = new LinkedListNodeOfBufferItem(item);
}
else
{
_items.Remove(node);
node.ValueRef = item;
}
return node;
}
finally
{
if (lockAcquired)
{
_lock.Exit();
}
}
}
public void Return(LinkedListNodeOfBufferItem node)
{
bool lockAcquired = false;
try
{
_lock.Enter(ref lockAcquired);
node.ValueRef = default;
_items.AddLast(node);
}
finally
{
if (lockAcquired)
{
_lock.Exit();
}
}
}
}
}