85 lines
2.2 KiB
C#
85 lines
2.2 KiB
C#
using System.Threading;
|
|
|
|
#if NEED_LINKEDLIST_SHIM
|
|
using LinkedListOfQueueItem = KcpSharp.NetstandardShim.LinkedList<(KcpSharp.KcpBuffer Data, byte Fragment)>;
|
|
using LinkedListNodeOfQueueItem = KcpSharp.NetstandardShim.LinkedListNode<(KcpSharp.KcpBuffer Data, byte Fragment)>;
|
|
#else
|
|
using LinkedListOfQueueItem = System.Collections.Generic.LinkedList<(KcpSharp.KcpBuffer Data, byte Fragment)>;
|
|
using LinkedListNodeOfQueueItem = System.Collections.Generic.LinkedListNode<(KcpSharp.KcpBuffer Data, byte Fragment)>;
|
|
#endif
|
|
|
|
namespace KcpSharp
|
|
{
|
|
internal sealed class KcpSendReceiveQueueItemCache
|
|
{
|
|
private LinkedListOfQueueItem _list = new();
|
|
private SpinLock _lock;
|
|
|
|
public LinkedListNodeOfQueueItem Rent(in KcpBuffer buffer, byte fragment)
|
|
{
|
|
bool lockTaken = false;
|
|
try
|
|
{
|
|
_lock.Enter(ref lockTaken);
|
|
|
|
LinkedListNodeOfQueueItem? node = _list.First;
|
|
if (node is null)
|
|
{
|
|
node = new LinkedListNodeOfQueueItem((buffer, fragment));
|
|
}
|
|
else
|
|
{
|
|
node.ValueRef = (buffer, fragment);
|
|
_list.RemoveFirst();
|
|
}
|
|
|
|
return node;
|
|
}
|
|
finally
|
|
{
|
|
if (lockTaken)
|
|
{
|
|
_lock.Exit();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Return(LinkedListNodeOfQueueItem node)
|
|
{
|
|
node.ValueRef = default;
|
|
|
|
bool lockTaken = false;
|
|
try
|
|
{
|
|
_lock.Enter(ref lockTaken);
|
|
|
|
_list.AddLast(node);
|
|
}
|
|
finally
|
|
{
|
|
if (lockTaken)
|
|
{
|
|
_lock.Exit();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
bool lockTaken = false;
|
|
try
|
|
{
|
|
_lock.Enter(ref lockTaken);
|
|
|
|
_list.Clear();
|
|
}
|
|
finally
|
|
{
|
|
if (lockTaken)
|
|
{
|
|
_lock.Exit();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|