1
0
mirror of https://github.com/lidgren/lidgren-network-gen3.git synced 2026-05-05 18:01:12 +09:00

Recycling problems hopefully fully fixed now. Library message now also recycled.

This commit is contained in:
Michael Lidgren
2015-02-07 17:25:54 +01:00
parent 6a0abf25c3
commit 44bc4ff06e
9 changed files with 68 additions and 41 deletions

View File

@@ -18,24 +18,24 @@ namespace Lidgren.Network
string token)
{
// send message to client
NetOutgoingMessage msg = CreateMessage(10 + token.Length + 1);
msg.m_messageType = NetMessageType.NatIntroduction;
msg.Write((byte)0);
msg.Write(hostInternal);
msg.Write(hostExternal);
msg.Write(token);
Interlocked.Increment(ref msg.m_recyclingCount);
m_unsentUnconnectedMessages.Enqueue(new NetTuple<IPEndPoint, NetOutgoingMessage>(clientExternal, msg));
NetOutgoingMessage um = CreateMessage(10 + token.Length + 1);
um.m_messageType = NetMessageType.NatIntroduction;
um.Write((byte)0);
um.Write(hostInternal);
um.Write(hostExternal);
um.Write(token);
Interlocked.Increment(ref um.m_recyclingCount);
m_unsentUnconnectedMessages.Enqueue(new NetTuple<IPEndPoint, NetOutgoingMessage>(clientExternal, um));
// send message to host
msg = CreateMessage(10 + token.Length + 1);
msg.m_messageType = NetMessageType.NatIntroduction;
msg.Write((byte)1);
msg.Write(clientInternal);
msg.Write(clientExternal);
msg.Write(token);
Interlocked.Increment(ref msg.m_recyclingCount);
m_unsentUnconnectedMessages.Enqueue(new NetTuple<IPEndPoint, NetOutgoingMessage>(hostExternal, msg));
um = CreateMessage(10 + token.Length + 1);
um.m_messageType = NetMessageType.NatIntroduction;
um.Write((byte)1);
um.Write(clientInternal);
um.Write(clientExternal);
um.Write(token);
Interlocked.Increment(ref um.m_recyclingCount);
m_unsentUnconnectedMessages.Enqueue(new NetTuple<IPEndPoint, NetOutgoingMessage>(hostExternal, um));
}
/// <summary>

View File

@@ -30,7 +30,14 @@ namespace Lidgren.Network
{
internal NetMessageType m_messageType;
internal bool m_isSent;
internal int m_recyclingCount; // when this reaches zero the message is ready to be recycled
// Recycling count is:
// * incremented for each recipient on send
// * incremented, when reliable, in SenderChannel.ExecuteSend()
// * decremented (both reliable and unreliable) in NetConnection.QueueSendMessage()
// * decremented, when reliable, in SenderChannel.DestoreMessage()
// ... when it reaches zero it can be recycled
internal int m_recyclingCount;
internal int m_fragmentGroup; // which group of fragments ths belongs to
internal int m_fragmentGroupTotalBits; // total number of bits in this group

View File

@@ -11,10 +11,10 @@ namespace Lidgren.Network
/// </summary>
public void DiscoverLocalPeers(int serverPort)
{
NetOutgoingMessage om = CreateMessage(0);
om.m_messageType = NetMessageType.Discovery;
Interlocked.Increment(ref om.m_recyclingCount);
m_unsentUnconnectedMessages.Enqueue(new NetTuple<IPEndPoint, NetOutgoingMessage>(new IPEndPoint(IPAddress.Broadcast, serverPort), om));
NetOutgoingMessage um = CreateMessage(0);
um.m_messageType = NetMessageType.Discovery;
Interlocked.Increment(ref um.m_recyclingCount);
m_unsentUnconnectedMessages.Enqueue(new NetTuple<IPEndPoint, NetOutgoingMessage>(new IPEndPoint(IPAddress.Broadcast, serverPort), um));
}
/// <summary>

View File

@@ -158,10 +158,10 @@ namespace Lidgren.Network
/// </summary>
public void Recycle(NetIncomingMessage msg)
{
if (m_incomingMessagesPool == null)
if (m_incomingMessagesPool == null || msg == null)
return;
NetException.Assert(m_incomingMessagesPool.Contains(msg) == false, "Recyling already recycled message! Thread race?");
NetException.Assert(m_incomingMessagesPool.Contains(msg) == false, "Recyling already recycled incoming message! Thread race?");
byte[] storage = msg.m_data;
msg.m_data = null;
@@ -188,7 +188,7 @@ namespace Lidgren.Network
if (m_outgoingMessagesPool == null)
return;
#if DEBUG
NetException.Assert(m_outgoingMessagesPool.Contains(msg) == false, "Recyling already recycled message! Thread race?");
NetException.Assert(m_outgoingMessagesPool.Contains(msg) == false, "Recyling already recycled outgoing message! Thread race?");
if (msg.m_recyclingCount != 0)
LogWarning("Wrong recycling count! should be zero; found " + msg.m_recyclingCount);
#endif

View File

@@ -209,31 +209,35 @@ namespace Lidgren.Network
/// <summary>
/// Send a message to this exact same netpeer (loopback)
/// </summary>
public void SendUnconnectedToSelf(NetOutgoingMessage msg)
public void SendUnconnectedToSelf(NetOutgoingMessage om)
{
if (msg == null)
if (om == null)
throw new ArgumentNullException("msg");
if (msg.m_isSent)
if (om.m_isSent)
throw new NetException("This message has already been sent! Use NetPeer.SendMessage() to send to multiple recipients efficiently");
msg.m_messageType = NetMessageType.Unconnected;
msg.m_isSent = true;
om.m_messageType = NetMessageType.Unconnected;
om.m_isSent = true;
if (m_configuration.IsMessageTypeEnabled(NetIncomingMessageType.UnconnectedData) == false)
{
Interlocked.Decrement(ref msg.m_recyclingCount);
Interlocked.Decrement(ref om.m_recyclingCount);
return; // dropping unconnected message since it's not enabled for receiving
}
NetIncomingMessage om = CreateIncomingMessage(NetIncomingMessageType.UnconnectedData, msg.LengthBytes);
om.Write(msg);
om.m_isFragment = false;
om.m_receiveTime = NetTime.Now;
om.m_senderConnection = null;
om.m_senderEndPoint = m_socket.LocalEndPoint as IPEndPoint;
NetException.Assert(om.m_bitLength == msg.LengthBits);
// convert outgoing to incoming
NetIncomingMessage im = CreateIncomingMessage(NetIncomingMessageType.UnconnectedData, om.LengthBytes);
im.Write(om);
im.m_isFragment = false;
im.m_receiveTime = NetTime.Now;
im.m_senderConnection = null;
im.m_senderEndPoint = m_socket.LocalEndPoint as IPEndPoint;
NetException.Assert(im.m_bitLength == om.LengthBits);
ReleaseMessage(om);
// recycle outgoing message
Recycle(om);
ReleaseMessage(im);
}
}
}

View File

@@ -225,7 +225,7 @@ namespace Lidgren.Network
return added;
}
// send message immediately
// send message immediately and recycle it
internal void SendLibrary(NetOutgoingMessage msg, IPEndPoint recipient)
{
VerifyNetworkThread();
@@ -234,6 +234,10 @@ namespace Lidgren.Network
bool connReset;
int len = msg.Encode(m_sendBuffer, 0, 0);
SendPacket(len, recipient, 1, out connReset);
// no reliability, no multiple recipients - we can just recycle this message immediately
msg.m_recyclingCount = 0;
Recycle(msg);
}
/// <summary>

View File

@@ -118,6 +118,10 @@ namespace Lidgren.Network
int seqNr = m_sendStart;
m_sendStart = (m_sendStart + 1) % NetConstants.NumSequenceNumbers;
// must increment recycle count here, since it's decremented in QueueSendMessage and we want to keep it for the future in case or resends
// we will decrement once more in DestoreMessage for final recycling
Interlocked.Increment(ref message.m_recyclingCount);
m_connection.QueueSendMessage(message, seqNr);
int storeIndex = seqNr % m_windowSize;
@@ -134,6 +138,9 @@ namespace Lidgren.Network
private void DestoreMessage(int storeIndex)
{
NetOutgoingMessage storedMessage = m_storedMessages[storeIndex].Message;
// on each destore; reduce recyclingcount so that when all instances are destored, the outgoing message can be recycled
Interlocked.Decrement(ref storedMessage.m_recyclingCount);
#if DEBUG
if (storedMessage == null)
throw new NetException("m_storedMessages[" + storeIndex + "].Message is null; sent " + m_storedMessages[storeIndex].NumSent + " times, last time " + (NetTime.Now - m_storedMessages[storeIndex].LastSent) + " seconds ago");

View File

@@ -73,7 +73,13 @@ namespace ManyServer
var conns = Server.Connections;
// resend to ONE random connection
Server.SendMessage(outMsg, conns[NetRandom.Instance.Next(0, conns.Count)], NetDeliveryMethod.ReliableOrdered, 0);
//Server.SendMessage(outMsg, conns[NetRandom.Instance.Next(0, conns.Count)], NetDeliveryMethod.ReliableOrdered, 0);
List<NetConnection> rec = new List<NetConnection>();
rec.AddRange(conns);
rec.Remove(inc.SenderConnection);
if (rec.Count > 0)
Server.SendMessage(outMsg, rec, NetDeliveryMethod.ReliableOrdered, 0);
break;
}
}

View File

@@ -49,7 +49,6 @@ namespace UnconnectedSample
break;
case NetIncomingMessageType.UnconnectedData:
MainForm.richTextBox1.AppendText("Received from " + im.SenderEndPoint + ": " + im.ReadString() + Environment.NewLine);
Peer.Recycle(im);
break;
}
Peer.Recycle(im);