Skip to content

Commit

Permalink
make threadsafe NetPeer.Send (fix #109)
Browse files Browse the repository at this point in the history
  • Loading branch information
RevenantX committed Jan 2, 2018
1 parent 29cf44b commit 949cf67
Showing 1 changed file with 34 additions and 27 deletions.
61 changes: 34 additions & 27 deletions LiteNetLib/NetPeer.cs
Expand Up @@ -44,6 +44,7 @@ public sealed class NetPeer
private readonly NetManager _peerListener;
private readonly NetPacketPool _packetPool;
private readonly object _flushLock = new object();
private readonly object _sendLock = new object();

//Channels
private readonly ReliableChannel _reliableOrderedChannel;
Expand Down Expand Up @@ -303,19 +304,23 @@ public void Send(NetDataWriter dataWriter, SendOptions options)
/// <param name="options">Send options (reliable, unreliable, etc.)</param>
public void Send(byte[] data, int start, int length, SendOptions options)
{
if (_connectionState == ConnectionState.Disconnected)
{
return;
}
//Prepare
PacketProperty property = SendOptionsToProperty(options);
int headerSize = NetPacket.GetHeaderSize(property);

int mtu = _mtu;
//Check fragmentation
if (length + headerSize > _mtu)
if (length + headerSize > mtu)
{
if (options == SendOptions.Sequenced || options == SendOptions.Unreliable)
{
throw new Exception("Unreliable packet size > allowed (" + (_mtu - headerSize) + ")");
throw new Exception("Unreliable packet size > allowed (" + (mtu - headerSize) + ")");
}

int packetFullSize = _mtu - headerSize;
int packetFullSize = mtu - headerSize;
int packetDataSize = packetFullSize - NetConstants.FragmentHeaderSize;

int fullPacketsCount = length / packetDataSize;
Expand All @@ -329,38 +334,40 @@ public void Send(byte[] data, int start, int length, SendOptions options)
" packetDataSize: {3}\n" +
" fullPacketsCount: {4}\n" +
" lastPacketSize: {5}\n" +
" totalPackets: {6}",
_mtu, headerSize, packetFullSize, packetDataSize, fullPacketsCount, lastPacketSize, totalPackets);
" totalPackets: {6}",
mtu, headerSize, packetFullSize, packetDataSize, fullPacketsCount, lastPacketSize, totalPackets);

if (totalPackets > ushort.MaxValue)
{
throw new Exception("Too many fragments: " + totalPackets + " > " + ushort.MaxValue);
}

int dataOffset = headerSize + NetConstants.FragmentHeaderSize;
for (ushort i = 0; i < fullPacketsCount; i++)
{
NetPacket p = _packetPool.Get(property, packetFullSize);
p.FragmentId = _fragmentId;
p.FragmentPart = i;
p.FragmentsTotal = (ushort)totalPackets;
p.IsFragmented = true;
Buffer.BlockCopy(data, i * packetDataSize, p.RawData, dataOffset, packetDataSize);
SendPacket(p);
}

if (lastPacketSize > 0)

lock (_sendLock)
{
NetPacket p = _packetPool.Get(property, lastPacketSize + NetConstants.FragmentHeaderSize);
p.FragmentId = _fragmentId;
p.FragmentPart = (ushort)fullPacketsCount; //last
p.FragmentsTotal = (ushort)totalPackets;
p.IsFragmented = true;
Buffer.BlockCopy(data, fullPacketsCount * packetDataSize, p.RawData, dataOffset, lastPacketSize);
SendPacket(p);
for (ushort i = 0; i < fullPacketsCount; i++)
{
NetPacket p = _packetPool.Get(property, packetFullSize);
p.FragmentId = _fragmentId;
p.FragmentPart = i;
p.FragmentsTotal = (ushort)totalPackets;
p.IsFragmented = true;
Buffer.BlockCopy(data, i * packetDataSize, p.RawData, dataOffset, packetDataSize);
SendPacket(p);
}
if (lastPacketSize > 0)
{
NetPacket p = _packetPool.Get(property, lastPacketSize + NetConstants.FragmentHeaderSize);
p.FragmentId = _fragmentId;
p.FragmentPart = (ushort)fullPacketsCount; //last
p.FragmentsTotal = (ushort)totalPackets;
p.IsFragmented = true;
Buffer.BlockCopy(data, fullPacketsCount * packetDataSize, p.RawData, dataOffset, lastPacketSize);
SendPacket(p);
}
_fragmentId++;
}

_fragmentId++;
return;
}

Expand Down

0 comments on commit 949cf67

Please sign in to comment.