diff --git a/Lidgren.Network/NetPeer.LatencySimulation.cs b/Lidgren.Network/NetPeer.LatencySimulation.cs index ae15197..7497b31 100644 --- a/Lidgren.Network/NetPeer.LatencySimulation.cs +++ b/Lidgren.Network/NetPeer.LatencySimulation.cs @@ -17,6 +17,8 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH USE OR OTHER DEALINGS IN THE SOFTWARE. */ +//#define USE_RELEASE_STATISTICS + using System; using System.Collections.Generic; using System.Net; @@ -228,6 +230,9 @@ namespace Lidgren.Network // internal void SendPacket(int numBytes, IPEndPoint target, int numMessages, out bool connectionReset) { +#if USE_RELEASE_STATISTICS + m_statistics.PacketSent(numBytes, numMessages); +#endif connectionReset = false; try { diff --git a/Lidgren.Network/NetPeer.MessagePools.cs b/Lidgren.Network/NetPeer.MessagePools.cs index 29fcca5..5ad3225 100644 --- a/Lidgren.Network/NetPeer.MessagePools.cs +++ b/Lidgren.Network/NetPeer.MessagePools.cs @@ -55,19 +55,18 @@ namespace Lidgren.Network if (m_storagePool == null) return; - int len = storage.Length; lock (m_storagePool) { - for (int i = 0; i < m_storagePool.Count; i++) + m_storagePoolBytes += storage.Length; + int cnt = m_storagePool.Count; + for (int i = 0; i < cnt; i++) { if (m_storagePool[i] == null) { - m_storagePoolBytes += storage.Length; m_storagePool[i] = storage; return; } } - m_storagePoolBytes += storage.Length; m_storagePool.Add(storage); } } @@ -156,18 +155,33 @@ namespace Lidgren.Network if (m_incomingMessagesPool == null) return; - foreach (var msg in toRecycle) + // first recycle the storage of each message + if (m_storagePool != null) { -#if DEBUG - if (m_incomingMessagesPool.Contains(msg)) - throw new NetException("Recyling already recycled message! Thread race?"); -#endif - byte[] storage = msg.m_data; - msg.m_data = null; - Recycle(storage); - msg.Reset(); - m_incomingMessagesPool.Enqueue(msg); + lock (m_storagePool) + { + foreach (var msg in toRecycle) + { + var storage = msg.m_data; + msg.m_data = null; + m_storagePoolBytes += storage.Length; + int cnt = m_storagePool.Count; + for (int i = 0; i < cnt; i++) + { + if (m_storagePool[i] == null) + { + m_storagePool[i] = storage; + return; + } + } + msg.Reset(); + m_storagePool.Add(storage); + } + } } + + // then recycle the message objects + m_incomingMessagesPool.Enqueue(toRecycle); } internal void Recycle(NetOutgoingMessage msg) diff --git a/Lidgren.Network/NetPeerStatistics.cs b/Lidgren.Network/NetPeerStatistics.cs index c622792..9c245fc 100644 --- a/Lidgren.Network/NetPeerStatistics.cs +++ b/Lidgren.Network/NetPeerStatistics.cs @@ -146,8 +146,13 @@ namespace Lidgren.Network { StringBuilder bdr = new StringBuilder(); bdr.AppendLine(m_peer.ConnectionsCount.ToString() + " connections"); +#if DEBUG || USE_RELEASE_STATISTICS bdr.AppendLine("Sent " + m_sentBytes + " bytes in " + m_sentMessages + " messages in " + m_sentPackets + " packets"); bdr.AppendLine("Received " + m_receivedBytes + " bytes in " + m_receivedMessages + " messages in " + m_receivedPackets + " packets"); +#else + bdr.AppendLine("Sent (n/a) bytes in (n/a) messages in (n/a) packets"); + bdr.AppendLine("Received (n/a) bytes in (n/a) messages in (n/a) packets"); +#endif bdr.AppendLine("Storage allocated " + m_bytesAllocated + " bytes"); bdr.AppendLine("Recycled pool " + m_peer.m_storagePoolBytes + " bytes"); return bdr.ToString(); diff --git a/Lidgren.Network/NetQueue.cs b/Lidgren.Network/NetQueue.cs index 1ad0f1e..524a35c 100644 --- a/Lidgren.Network/NetQueue.cs +++ b/Lidgren.Network/NetQueue.cs @@ -21,6 +21,8 @@ using System; using System.Diagnostics; using System.Collections.Generic; +// @TODO: examine performance characteristics of using SpinLock when using .Net 4.0 + namespace Lidgren.Network { /// @@ -83,6 +85,25 @@ namespace Lidgren.Network } } + /// + /// Adds an item last/tail of the queue + /// + public void Enqueue(IEnumerable items) + { + lock (m_lock) + { + foreach (var item in items) + { + if (m_size == m_items.Length) + SetCapacity(m_items.Length + 8); // @TODO move this out of loop + + int slot = (m_head + m_size) % m_items.Length; + m_items[slot] = item; + m_size++; + } + } + } + /// /// Places an item first, at the head of the queue /// diff --git a/Samples/LibraryTestSamples/ManySample/ManyClients/Client.cs b/Samples/LibraryTestSamples/ManySample/ManyClients/Client.cs index 878d995..e79ba47 100644 --- a/Samples/LibraryTestSamples/ManySample/ManyClients/Client.cs +++ b/Samples/LibraryTestSamples/ManySample/ManyClients/Client.cs @@ -80,7 +80,7 @@ namespace ManyClients private void button1_Click(object sender, EventArgs e) { var om = Net.CreateMessage(); - om.Write("Hi!"); + om.Write("Manual hi!"); Net.SendMessage(om, NetDeliveryMethod.ReliableOrdered); }