You've already forked lidgren-network-gen3
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:
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user