From 1a262bdde75ab87867b8cf96f12852d219a1b719 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 15 Dec 2012 00:45:27 +0000 Subject: [PATCH] Make WebStatsModule properly handle scenes added or removed after initial startup. This may have been the cause of the DivByZero in http://opensimulator.org/mantis/view.php?id=6460 --- .../Region/UserStatistics/WebStatsModule.cs | 45 +++++++++++++------ 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index b08233c7aa..64cb577350 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -94,8 +94,6 @@ namespace OpenSim.Region.UserStatistics if (!enabled) return; - AddEventHandlers(); - if (Util.IsWindows()) Util.LoadArchSpecificWindowsDll("sqlite3.dll"); @@ -143,10 +141,14 @@ namespace OpenSim.Region.UserStatistics lock (m_scenes) { m_scenes.Add(scene); - if (m_simstatsCounters.ContainsKey(scene.RegionInfo.RegionID)) - m_simstatsCounters.Remove(scene.RegionInfo.RegionID); + updateLogMod = m_scenes.Count * 2; m_simstatsCounters.Add(scene.RegionInfo.RegionID, new USimStatsData(scene.RegionInfo.RegionID)); + + scene.EventManager.OnRegisterCaps += OnRegisterCaps; + scene.EventManager.OnDeregisterCaps += OnDeRegisterCaps; + scene.EventManager.OnClientClosed += OnClientClosed; + scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; scene.StatsReporter.OnSendStatsResult += ReceiveClassicSimStatsPacket; } } @@ -157,6 +159,15 @@ namespace OpenSim.Region.UserStatistics public void RemoveRegion(Scene scene) { + if (!enabled) + return; + + lock (m_scenes) + { + m_scenes.Remove(scene); + updateLogMod = m_scenes.Count * 2; + m_simstatsCounters.Remove(scene.RegionInfo.RegionID); + } } public virtual void Close() @@ -187,9 +198,7 @@ namespace OpenSim.Region.UserStatistics private void ReceiveClassicSimStatsPacket(SimStats stats) { if (!enabled) - { return; - } try { @@ -198,17 +207,25 @@ namespace OpenSim.Region.UserStatistics if (concurrencyCounter > 0 || System.Environment.TickCount - lastHit > 30000) return; - if ((updateLogCounter++ % updateLogMod) == 0) + // We will conduct this under lock so that fields such as updateLogCounter do not potentially get + // confused if a scene is removed. + // XXX: Possibly the scope of this lock could be reduced though it's not critical. + lock (m_scenes) { - m_loglines = readLogLines(10); - if (updateLogCounter > 10000) updateLogCounter = 1; - } + if (updateLogMod != 0 && updateLogCounter++ % updateLogMod == 0) + { + m_loglines = readLogLines(10); - USimStatsData ss = m_simstatsCounters[stats.RegionUUID]; + if (updateLogCounter > 10000) + updateLogCounter = 1; + } - if ((++ss.StatsCounter % updateStatsMod) == 0) - { - ss.ConsumeSimStats(stats); + USimStatsData ss = m_simstatsCounters[stats.RegionUUID]; + + if ((++ss.StatsCounter % updateStatsMod) == 0) + { + ss.ConsumeSimStats(stats); + } } } catch (KeyNotFoundException)