From 44776fea723774f0674881d69855af9657398d18 Mon Sep 17 00:00:00 2001 From: James J Greensky Date: Wed, 30 Sep 2009 17:30:28 -0700 Subject: [PATCH] Fixing LLClientView memory leak Fixing LLClientView memory leak by disposing of all timers utilized in LLClientView as they contain references to the callback method. This required the use of the Terminate and Close infrastructure that was already in place but was not being utilized. --- OpenSim/Framework/BlockingQueue.cs | 5 +++- OpenSim/Framework/IClientAPI.cs | 1 - .../ClientStack/LindenUDP/ILLPacketHandler.cs | 3 +-- .../ClientStack/LindenUDP/LLClientView.cs | 23 +++++++++++++++---- .../ClientStack/LindenUDP/LLPacketHandler.cs | 3 ++- .../ClientStack/LindenUDP/LLPacketQueue.cs | 8 ++++++- 6 files changed, 33 insertions(+), 10 deletions(-) diff --git a/OpenSim/Framework/BlockingQueue.cs b/OpenSim/Framework/BlockingQueue.cs index e03229b6ac..857930aaef 100644 --- a/OpenSim/Framework/BlockingQueue.cs +++ b/OpenSim/Framework/BlockingQueue.cs @@ -66,7 +66,9 @@ namespace OpenSim.Framework if (m_pqueue.Count > 0) return m_pqueue.Dequeue(); - return m_queue.Dequeue(); + if (m_queue.Count > 0) + return m_queue.Dequeue(); + return default(T); } } @@ -119,6 +121,7 @@ namespace OpenSim.Framework { m_pqueue.Clear(); m_queue.Clear(); + Monitor.Pulse(m_queueSync); } } } diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 430cbd734d..91a5d5c938 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -1127,7 +1127,6 @@ namespace OpenSim.Framework void SetClientOption(string option, string value); string GetClientOption(string option); - void Terminate(); void SendSetFollowCamProperties(UUID objectID, SortedDictionary parameters); void SendClearFollowCamProperties(UUID objectID); diff --git a/OpenSim/Region/ClientStack/LindenUDP/ILLPacketHandler.cs b/OpenSim/Region/ClientStack/LindenUDP/ILLPacketHandler.cs index 665c77381d..09edc949a5 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/ILLPacketHandler.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/ILLPacketHandler.cs @@ -40,7 +40,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Interface to a class that handles all the activity involved with maintaining the client circuit (handling acks, /// resends, pings, etc.) /// - public interface ILLPacketHandler + public interface ILLPacketHandler : IDisposable { event PacketStats OnPacketStats; event PacketDrop OnPacketDrop; @@ -70,7 +70,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP void OutPacket(Packet NewPack, ThrottleOutPacketType throttlePacketType, Object id); LLPacketQueue PacketQueue { get; } - void Stop(); void Flush(); void Clear(); ClientInfo GetClientInfo(); diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 9788f4031c..460f94edae 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -633,6 +633,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP // of the client thread regardless of where Close() is called. KillEndDone(); } + + Terminate(); } /// @@ -737,16 +739,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP } - public void Terminate() + private void Terminate() { + IsActive = false; + + m_clientPingTimer.Close(); + m_avatarTerseUpdateTimer.Close(); + m_primTerseUpdateTimer.Close(); + m_primFullUpdateTimer.Close(); + m_textureRequestTimer.Close(); + m_PacketHandler.OnPacketStats -= PopulateStats; - m_PacketHandler.Stop(); + m_PacketHandler.Dispose(); // wait for thread stoped - m_clientThread.Join(); + // m_clientThread.Join(); // delete circuit code - m_networkServer.CloseClient(this); + //m_networkServer.CloseClient(this); } #endregion @@ -876,6 +886,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP while (IsActive) { LLQueItem nextPacket = m_PacketHandler.PacketQueue.Dequeue(); + + if (nextPacket == null) { + m_log.DebugFormat("[CLIENT]: PacketQueue return null LLQueItem"); + continue; + } if (nextPacket.Incoming) { diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs index eaf8f603a9..67ece751ae 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs @@ -176,9 +176,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_AckTimer.Start(); } - public void Stop() + public void Dispose() { m_AckTimer.Stop(); + m_AckTimer.Close(); m_PacketQueue.Enqueue(null); m_PacketQueue.Close(); diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs index 798c1e7041..6dd0697d66 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs @@ -39,7 +39,7 @@ using Timer=System.Timers.Timer; namespace OpenSim.Region.ClientStack.LindenUDP { - public class LLPacketQueue : IPullStatsProvider + public class LLPacketQueue : IPullStatsProvider, IDisposable { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -341,12 +341,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP } public void Close() + { + Dispose(); + } + + public void Dispose() { Flush(); WipeClean(); // I'm sure there's a dirty joke in here somewhere. -AFrisby m_enabled = false; throttleTimer.Stop(); + throttleTimer.Close(); if (StatsManager.SimExtraStats != null) {