Skip to content

Commit

Permalink
replace event queue by linked list type of queue. Fixes possible mult…
Browse files Browse the repository at this point in the history
…ithreaded bugs
  • Loading branch information
RevenantX committed Apr 24, 2023
1 parent 329e00b commit 4102c8e
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 26 deletions.
85 changes: 60 additions & 25 deletions LiteNetLib/NetManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ private struct IncomingData
private bool _manualMode;
private readonly AutoResetEvent _updateTriggerEvent = new AutoResetEvent(true);

private Queue<NetEvent> _netEventsProduceQueue = new Queue<NetEvent>();
private Queue<NetEvent> _netEventsConsumeQueue = new Queue<NetEvent>();
private NetEvent _pendingEventHead;
private NetEvent _pendingEventTail;

private NetEvent _netEventPoolHead;
private readonly INetEventListener _netEventListener;
Expand Down Expand Up @@ -530,6 +530,7 @@ private void CreateEvent(
_netEventPoolHead = evt.Next;
}

evt.Next = null;
evt.Type = type;
evt.DataReader.SetSource(readerSource, readerSource?.GetHeaderSize() ?? 0);
evt.Peer = peer;
Expand All @@ -548,8 +549,14 @@ private void CreateEvent(
}
else
{
lock(_netEventsProduceQueue)
_netEventsProduceQueue.Enqueue(evt);
lock (_eventLock)
{
if (_pendingEventTail == null)
_pendingEventHead = evt;
else
_pendingEventTail.Next = evt;
_pendingEventTail = evt;
}
}
}

Expand Down Expand Up @@ -1111,27 +1118,48 @@ private void DebugMessageReceived(NetPacket packet, IPEndPoint remoteEndPoint)
internal void CreateReceiveEvent(NetPacket packet, DeliveryMethod method, byte channelNumber, int headerSize, NetPeer fromPeer)
{
NetEvent evt;
lock (_eventLock)
{
evt = _netEventPoolHead;
if (evt == null)
evt = new NetEvent(this);
else
_netEventPoolHead = evt.Next;
}
evt.Type = NetEvent.EType.Receive;
evt.DataReader.SetSource(packet, headerSize);
evt.Peer = fromPeer;
evt.DeliveryMethod = method;
evt.ChannelNumber = channelNumber;

if (UnsyncedEvents || UnsyncedReceiveEvent || _manualMode)
{
lock (_eventLock)
{
evt = _netEventPoolHead;
if (evt == null)
evt = new NetEvent(this);
else
_netEventPoolHead = evt.Next;
}
evt.Next = null;
evt.Type = NetEvent.EType.Receive;
evt.DataReader.SetSource(packet, headerSize);
evt.Peer = fromPeer;
evt.DeliveryMethod = method;
evt.ChannelNumber = channelNumber;
ProcessEvent(evt);
}
else
{
lock(_netEventsProduceQueue)
_netEventsProduceQueue.Enqueue(evt);
lock (_eventLock)
{
evt = _netEventPoolHead;
if (evt == null)
evt = new NetEvent(this);
else
_netEventPoolHead = evt.Next;

evt.Next = null;
evt.Type = NetEvent.EType.Receive;
evt.DataReader.SetSource(packet, headerSize);
evt.Peer = fromPeer;
evt.DeliveryMethod = method;
evt.ChannelNumber = channelNumber;

if (_pendingEventTail == null)
_pendingEventHead = evt;
else
_pendingEventTail.Next = evt;
_pendingEventTail = evt;
}
}
}

Expand Down Expand Up @@ -1458,13 +1486,20 @@ public void PollEvents()
}
if (UnsyncedEvents)
return;
lock (_netEventsProduceQueue)
NetEvent pendingEvent;
lock (_eventLock)
{
(_netEventsConsumeQueue, _netEventsProduceQueue) = (_netEventsProduceQueue, _netEventsConsumeQueue);
pendingEvent = _pendingEventHead;
_pendingEventHead = null;
_pendingEventTail = null;
}

while(_netEventsConsumeQueue.Count > 0)
ProcessEvent(_netEventsConsumeQueue.Dequeue());
while (pendingEvent != null)
{
var next = pendingEvent.Next;
ProcessEvent(pendingEvent);
pendingEvent = next;
}
}

/// <summary>
Expand Down Expand Up @@ -1608,8 +1643,8 @@ public void Stop(bool sendDisconnectMessages)
_pingSimulationList.Clear();
#endif
_connectedPeersCount = 0;
_netEventsProduceQueue.Clear();
_netEventsConsumeQueue.Clear();
_pendingEventHead = null;
_pendingEventTail = null;
}

/// <summary>
Expand Down
1 change: 0 additions & 1 deletion LiteNetLib/NetPacket.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Net;
using LiteNetLib.Utils;

namespace LiteNetLib
Expand Down

0 comments on commit 4102c8e

Please sign in to comment.