From de0e00a1f053fd8667cdde37825dd8c5f7ea769b Mon Sep 17 00:00:00 2001 From: Latif Khalifa Date: Fri, 17 Jul 2009 16:54:45 +0000 Subject: [PATCH] LIBOMV-636: Dereference timers so GC can collect GridClient and managers git-svn-id: http://libopenmetaverse.googlecode.com/svn/libopenmetaverse/trunk@2998 52acb1d6-8a22-11de-b505-999d5b087335 --- OpenMetaverse/AgentManagerMovement.cs | 35 +++++++++++++++++++++++---- OpenMetaverse/ObjectManager.cs | 32 +++++++++++++++++------- OpenMetaverse/Simulator.cs | 4 +++ OpenMetaverse/TexturePipeline.cs | 15 +++++++----- 4 files changed, 66 insertions(+), 20 deletions(-) diff --git a/OpenMetaverse/AgentManagerMovement.cs b/OpenMetaverse/AgentManagerMovement.cs index be5646ae..7884434b 100644 --- a/OpenMetaverse/AgentManagerMovement.cs +++ b/OpenMetaverse/AgentManagerMovement.cs @@ -397,12 +397,18 @@ namespace OpenMetaverse { if (value > 0) { - updateTimer.Change(value, value); + if (updateTimer != null) + { + updateTimer.Change(value, value); + } updateInterval = value; } else { - updateTimer.Change(Timeout.Infinite, Timeout.Infinite); + if (updateTimer != null) + { + updateTimer.Change(Timeout.Infinite, Timeout.Infinite); + } updateInterval = 0; } } @@ -467,10 +473,29 @@ namespace OpenMetaverse { Client = client; Camera = new AgentCamera(); - + client.Network.OnConnected += new NetworkManager.ConnectedCallback(Network_OnConnected); + client.Network.OnDisconnected += new NetworkManager.DisconnectedCallback(Network_OnDisconnected); updateInterval = Settings.DEFAULT_AGENT_UPDATE_INTERVAL; - updateTimer = new Timer(new TimerCallback(UpdateTimer_Elapsed), null, Settings.DEFAULT_AGENT_UPDATE_INTERVAL, - Settings.DEFAULT_AGENT_UPDATE_INTERVAL); + } + + private void CleanupTimer() + { + if (updateTimer != null) + { + updateTimer.Dispose(); + updateTimer = null; + } + } + + private void Network_OnDisconnected(NetworkManager.DisconnectType reason, string message) + { + CleanupTimer(); + } + + private void Network_OnConnected(object sender) + { + CleanupTimer(); + updateTimer = new Timer(new TimerCallback(UpdateTimer_Elapsed), null, updateInterval, updateInterval); } /// diff --git a/OpenMetaverse/ObjectManager.cs b/OpenMetaverse/ObjectManager.cs index bcee2e13..20c19acf 100644 --- a/OpenMetaverse/ObjectManager.cs +++ b/OpenMetaverse/ObjectManager.cs @@ -389,6 +389,8 @@ namespace OpenMetaverse protected ObjectManager(GridClient client, bool registerCallbacks) { Client = client; + Client.Network.OnConnected += new NetworkManager.ConnectedCallback(Network_OnConnected); + Client.Network.OnDisconnected += new NetworkManager.DisconnectedCallback(Network_OnDisconnected); if (registerCallbacks) { @@ -396,6 +398,23 @@ namespace OpenMetaverse } } + void Network_OnDisconnected(NetworkManager.DisconnectType reason, string message) + { + if (InterpolationTimer != null) + { + InterpolationTimer.Dispose(); + InterpolationTimer = null; + } + } + + void Network_OnConnected(object sender) + { + if (Settings.USE_INTERPOLATION_TIMER) + { + InterpolationTimer = new Timer(InterpolationTimer_Elapsed, null, Settings.INTERPOLATION_INTERVAL, Timeout.Infinite); + } + } + protected void RegisterCallbacks() { Client.Network.RegisterCallback(PacketType.ObjectUpdate, UpdateHandler); @@ -406,14 +425,6 @@ namespace OpenMetaverse Client.Network.RegisterCallback(PacketType.ObjectPropertiesFamily, ObjectPropertiesFamilyHandler); Client.Network.RegisterCallback(PacketType.ObjectProperties, ObjectPropertiesHandler); Client.Network.RegisterCallback(PacketType.PayPriceReply, PayPriceReplyHandler); - - // If the callbacks aren't registered there's not point in doing client-side path prediction, - // so we set it up here - if (Settings.USE_INTERPOLATION_TIMER) - { - InterpolationTimer = new Timer(InterpolationTimer_Elapsed, null, Settings.INTERPOLATION_INTERVAL, - Timeout.Infinite); - } } #region Action Methods @@ -2952,7 +2963,10 @@ namespace OpenMetaverse // Start the timer again. Use a minimum of a 50ms pause in between calculations int delay = Math.Max(50, Settings.INTERPOLATION_INTERVAL - elapsed); - InterpolationTimer.Change(delay, Timeout.Infinite); + if (InterpolationTimer != null) + { + InterpolationTimer.Change(delay, Timeout.Infinite); + } } } } diff --git a/OpenMetaverse/Simulator.cs b/OpenMetaverse/Simulator.cs index e8936521..cd79dabb 100644 --- a/OpenMetaverse/Simulator.cs +++ b/OpenMetaverse/Simulator.cs @@ -581,6 +581,10 @@ namespace OpenMetaverse if (StatsTimer != null) StatsTimer.Dispose(); if (PingTimer != null) PingTimer.Dispose(); + AckTimer = null; + StatsTimer = null; + PingTimer = null; + // Kill the current CAPS system if (Caps != null) { diff --git a/OpenMetaverse/TexturePipeline.cs b/OpenMetaverse/TexturePipeline.cs index e08b0804..1d94d2ff 100644 --- a/OpenMetaverse/TexturePipeline.cs +++ b/OpenMetaverse/TexturePipeline.cs @@ -136,8 +136,7 @@ namespace OpenMetaverse /// A synchronization object used by the primary thread private object lockerObject = new object(); /// A refresh timer used to increase the priority of stalled requests - private readonly System.Timers.Timer RefreshDownloadsTimer = - new System.Timers.Timer(Settings.PIPELINE_REFRESH_INTERVAL); + private System.Timers.Timer RefreshDownloadsTimer; /// Current number of pending and in-process transfers public int TransferCount { get { return _Transfers.Count; } } @@ -172,8 +171,6 @@ namespace OpenMetaverse downloadMaster = new Thread(DownloadThread); downloadMaster.Name = "TexturePipeline"; downloadMaster.IsBackground = true; - - RefreshDownloadsTimer.Elapsed += RefreshDownloadsTimer_Elapsed; } /// @@ -190,7 +187,12 @@ namespace OpenMetaverse _Client.Network.RegisterCallback(PacketType.ImagePacket, ImagePacketHandler); _Client.Network.RegisterCallback(PacketType.ImageNotInDatabase, ImageNotInDatabaseHandler); downloadMaster.Start(); - RefreshDownloadsTimer.Start(); + if (RefreshDownloadsTimer == null) + { + RefreshDownloadsTimer = new System.Timers.Timer(Settings.PIPELINE_REFRESH_INTERVAL); + RefreshDownloadsTimer.Elapsed += RefreshDownloadsTimer_Elapsed; + RefreshDownloadsTimer.Start(); + } } /// @@ -204,7 +206,8 @@ namespace OpenMetaverse Logger.Log(String.Format("Combined Execution Time: {0}, Network Execution Time {1}, Network {2}K/sec, Image Size {3}", TotalTime, NetworkTime, Math.Round(TotalBytes / NetworkTime.TotalSeconds / 60, 2), TotalBytes), Helpers.LogLevel.Debug); #endif - RefreshDownloadsTimer.Stop(); + RefreshDownloadsTimer.Dispose(); + RefreshDownloadsTimer = null; _Client.Network.UnregisterCallback(PacketType.ImageNotInDatabase, ImageNotInDatabaseHandler); _Client.Network.UnregisterCallback(PacketType.ImageData, ImageDataHandler);