From b4fd011e5b7a4171f18ac6a9b0645fbaffac94fa Mon Sep 17 00:00:00 2001 From: lidgren Date: Fri, 9 Sep 2011 08:11:38 +0000 Subject: [PATCH] - ReadMessages() added to batch read messages. Image sample changed to use the new batch method. --- Lidgren.Network/NetPeer.MessagePools.cs | 22 ++++++++++++++++ Lidgren.Network/NetPeer.cs | 24 +++++++++++++++++- Lidgren.Network/NetQueue.cs | 25 +++++++++++++++++++ .../ImageSample/ImageClient/ImageGetter.cs | 16 ++++++++---- 4 files changed, 81 insertions(+), 6 deletions(-) diff --git a/Lidgren.Network/NetPeer.MessagePools.cs b/Lidgren.Network/NetPeer.MessagePools.cs index 6afb1fe..29fcca5 100644 --- a/Lidgren.Network/NetPeer.MessagePools.cs +++ b/Lidgren.Network/NetPeer.MessagePools.cs @@ -148,6 +148,28 @@ namespace Lidgren.Network m_incomingMessagesPool.Enqueue(msg); } + /// + /// Recycles a list of NetIncomingMessage instances for reuse; taking pressure off the garbage collector + /// + public void Recycle(IEnumerable toRecycle) + { + if (m_incomingMessagesPool == null) + return; + + foreach (var msg in toRecycle) + { +#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); + } + } + internal void Recycle(NetOutgoingMessage msg) { if (m_outgoingMessagesPool == null) diff --git a/Lidgren.Network/NetPeer.cs b/Lidgren.Network/NetPeer.cs index 0b7828f..26d78f3 100644 --- a/Lidgren.Network/NetPeer.cs +++ b/Lidgren.Network/NetPeer.cs @@ -183,7 +183,29 @@ namespace Lidgren.Network } return retval; } - + + /// + /// Read a pending message from any connection, if any + /// + public int ReadMessages(IList addTo) + { + int added = m_releasedIncomingMessages.TryDrain(addTo); + if (added > 0) + { + for (int i = 0; i < added; i++) + { + var index = addTo.Count - added + i; + var nim = addTo[index]; + if (nim.MessageType == NetIncomingMessageType.StatusChanged) + { + NetConnectionStatus status = (NetConnectionStatus)nim.PeekByte(); + nim.SenderConnection.m_visibleStatus = status; + } + } + } + return added; + } + // send message immediately internal void SendLibrary(NetOutgoingMessage msg, IPEndPoint recipient) { diff --git a/Lidgren.Network/NetQueue.cs b/Lidgren.Network/NetQueue.cs index 2b7c59b..1ad0f1e 100644 --- a/Lidgren.Network/NetQueue.cs +++ b/Lidgren.Network/NetQueue.cs @@ -19,6 +19,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Diagnostics; +using System.Collections.Generic; namespace Lidgren.Network { @@ -159,6 +160,30 @@ namespace Lidgren.Network } } + /// + /// Gets an item from the head of the queue, or returns default(T) if empty + /// + public int TryDrain(IList addTo) + { + if (m_size == 0) + return 0; + + lock (m_lock) + { + int added = m_size; + while (m_size > 0) + { + var item = m_items[m_head]; + addTo.Add(item); + + m_items[m_head] = default(T); + m_head = (m_head + 1) % m_items.Length; + m_size--; + } + return added; + } + } + /// /// Returns default(T) if queue is empty /// diff --git a/Samples/ImageSample/ImageClient/ImageGetter.cs b/Samples/ImageSample/ImageClient/ImageGetter.cs index 5942f53..92dc1dd 100644 --- a/Samples/ImageSample/ImageClient/ImageGetter.cs +++ b/Samples/ImageSample/ImageClient/ImageGetter.cs @@ -18,6 +18,7 @@ namespace ImageClient public int NumReceivedSegments; private double m_startedFetching; + private List m_readList; public ImageGetter(string host, NetPeerConfiguration copyConfig) { @@ -25,6 +26,7 @@ namespace ImageClient NetPeerConfiguration config = copyConfig.Clone(); config.EnableMessageType(NetIncomingMessageType.DiscoveryResponse); + m_readList = new List(); Client = new NetClient(config); Client.Start(); @@ -50,8 +52,11 @@ namespace ImageClient public void Heartbeat() { - NetIncomingMessage inc; - while ((inc = Client.ReadMessage()) != null) + int numRead = Client.ReadMessages(m_readList); + if (numRead < 1) + return; + + foreach(var inc in m_readList) { switch(inc.MessageType) { @@ -166,10 +171,11 @@ namespace ImageClient break; } - - // recycle message to avoid garbage - Client.Recycle(inc); } + + // recycle messages to avoid garbage + Client.Recycle(m_readList); + m_readList.Clear(); } } }