Skip to content

Commit

Permalink
change lockfree to locks because of possible ABA problem
Browse files Browse the repository at this point in the history
  • Loading branch information
RevenantX committed May 18, 2021
1 parent e96bb61 commit 4a67b09
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 27 deletions.
24 changes: 12 additions & 12 deletions LiteNetLib/NetManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ private struct IncomingData
private int _lastPeerId;
private readonly Queue<int> _peerIds;
private byte _channelsCount = 1;
private readonly object _eventLock = new object();

internal readonly NetPacketPool NetPacketPool;

Expand Down Expand Up @@ -572,15 +573,14 @@ private void CreateEvent(
else if (type == NetEvent.EType.MessageDelivered)
unsyncEvent = UnsyncedDeliveryEvent;

do
lock(_eventLock)
{
evt = _netEventPoolHead;
if (evt == null)
{
evt = new NetEvent(this);
break;
}
} while (evt != Interlocked.CompareExchange(ref _netEventPoolHead, evt.Next, evt));
else
_netEventPoolHead = evt.Next;
}

evt.Type = type;
evt.DataReader.SetSource(readerSource, readerSource == null ? 0 : readerSource.GetHeaderSize());
Expand Down Expand Up @@ -657,10 +657,11 @@ internal void RecycleEvent(NetEvent evt)
evt.ErrorCode = 0;
evt.RemoteEndPoint = null;
evt.ConnectionRequest = null;
do
lock(_eventLock)
{
evt.Next = _netEventPoolHead;
} while (evt.Next != Interlocked.CompareExchange(ref _netEventPoolHead, evt, evt.Next));
_netEventPoolHead = evt;
}
}

//Update function
Expand Down Expand Up @@ -1131,15 +1132,14 @@ private void DataReceived(NetPacket packet, IPEndPoint remoteEndPoint)
internal void CreateReceiveEvent(NetPacket packet, DeliveryMethod method, int headerSize, NetPeer fromPeer)
{
NetEvent evt;
do
lock (_eventLock)
{
evt = _netEventPoolHead;
if (evt == null)
{
evt = new NetEvent(this);
break;
}
} while (evt != Interlocked.CompareExchange(ref _netEventPoolHead, evt.Next, evt));
else
_netEventPoolHead = evt.Next;
}
evt.Type = NetEvent.EType.Receive;
evt.DataReader.SetSource(packet, headerSize);
evt.Peer = fromPeer;
Expand Down
22 changes: 7 additions & 15 deletions LiteNetLib/NetPacketPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ internal sealed class NetPacketPool
{
private NetPacket _head;
private int _count;
private readonly object _lock = new object();

public NetPacket GetWithData(PacketProperty property, byte[] data, int start, int length)
{
Expand Down Expand Up @@ -38,16 +39,13 @@ public NetPacket GetPacket(int size)
return new NetPacket(size);

NetPacket packet;
do
lock (_lock)
{
packet = _head;
if (packet == null)
return new NetPacket(size);
} while (packet != Interlocked.CompareExchange(ref _head, packet.Next, packet));

#if DEBUG_REFCOUNT
Interlocked.Increment(ref packet.RefCount);
#endif
_head = _head.Next;
}

Interlocked.Decrement(ref _count);
packet.Size = size;
Expand All @@ -64,21 +62,15 @@ public void Recycle(NetPacket packet)
return;
}

#if DEBUG_REFCOUNT
int result = Interlocked.Decrement(ref packet.RefCount);
if (result != 0)
NetDebug.WriteError("PacketRefCount invalid: {0}, {1}", result, Environment.StackTrace);
#endif

Interlocked.Increment(ref _count);

//Clean fragmented flag
packet.RawData[0] = 0;

do
lock (_lock)
{
packet.Next = _head;
} while (packet.Next != Interlocked.CompareExchange(ref _head, packet, packet.Next));
_head = packet;
}
}
}
}

0 comments on commit 4a67b09

Please sign in to comment.