* Stop the sim stats reporter reusing the same SimStatsPacket for all clients

* I believe this was the cause of the remaining packet_out_of_order messages in the Linden client logs
* There were race conditions where multiple clientstacks would overwrite each other's sequence numbers
0.6.0-stable
Justin Clarke Casey 2008-10-06 19:52:54 +00:00
parent a1f3409032
commit cb7a9eaa09
8 changed files with 154 additions and 54 deletions

View File

@ -722,7 +722,13 @@ namespace OpenSim.Framework
void SendImagePart(ushort numParts, UUID ImageUUID, uint ImageSize, byte[] ImageData, byte imageCodec); void SendImagePart(ushort numParts, UUID ImageUUID, uint ImageSize, byte[] ImageData, byte imageCodec);
void SendShutdownConnectionNotice(); void SendShutdownConnectionNotice();
void SendSimStats(Packet pack);
/// <summary>
/// Send statistical information about the sim to the client.
/// </summary>
/// <param name="stats"></param>
void SendSimStats(SimStats stats);
void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID,
uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask, uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask,
uint NextOwnerMask, int OwnershipCost, byte SaleType, int SalePrice, uint Category, uint NextOwnerMask, int OwnershipCost, byte SaleType, int SalePrice, uint Category,

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using OpenMetaverse.Packets;
namespace OpenSim.Framework
{
/// <summary>
/// Enapsulate statistics for a simulator/scene.
///
/// TODO: This looks very much like the OpenMetaverse SimStatsPacket. It should be much more generic stats
/// storage.
/// </summary>
public class SimStats
{
public uint RegionX
{
get { return m_regionX; }
}
private uint m_regionX;
public uint RegionY
{
get { return m_regionY; }
}
private uint m_regionY;
public SimStatsPacket.RegionBlock RegionBlock
{
get { return m_regionBlock; }
}
private SimStatsPacket.RegionBlock m_regionBlock;
public SimStatsPacket.StatBlock[] StatsBlock
{
get { return m_statsBlock; }
}
private SimStatsPacket.StatBlock[] m_statsBlock;
public uint RegionFlags
{
get { return m_regionFlags; }
}
private uint m_regionFlags;
public uint ObjectCapacity
{
get { return m_objectCapacity; }
}
private uint m_objectCapacity;
public SimStats(
uint regionX, uint regionY, uint regionFlags, uint objectCapacity,
SimStatsPacket.RegionBlock regionBlock, SimStatsPacket.StatBlock[] statsBlock)
{
m_regionX = regionX;
m_regionY = regionY;
m_regionFlags = regionFlags;
m_objectCapacity = objectCapacity;
m_regionBlock = regionBlock;
m_statsBlock = statsBlock;
}
}
}

View File

@ -216,31 +216,31 @@ namespace OpenSim.Framework.Statistics
/// client purposes) sends information to listeners. /// client purposes) sends information to listeners.
/// </summary> /// </summary>
/// <param name="pack"></param> /// <param name="pack"></param>
public void ReceiveClassicSimStatsPacket(SimStatsPacket statsPacket) public void ReceiveClassicSimStatsPacket(SimStats stats)
{ {
// FIXME: Really shouldn't rely on the probably arbitrary order in which // FIXME: SimStats shouldn't allow an arbitrary stat packing order (which is inherited from the original
// stats are packed into the packet // SimStatsPacket that was being used).
timeDilation = statsPacket.Stat[0].StatValue; timeDilation = stats.StatsBlock[0].StatValue;
simFps = statsPacket.Stat[1].StatValue; simFps = stats.StatsBlock[1].StatValue;
physicsFps = statsPacket.Stat[2].StatValue; physicsFps = stats.StatsBlock[2].StatValue;
agentUpdates = statsPacket.Stat[3].StatValue; agentUpdates = stats.StatsBlock[3].StatValue;
rootAgents = statsPacket.Stat[4].StatValue; rootAgents = stats.StatsBlock[4].StatValue;
childAgents = statsPacket.Stat[5].StatValue; childAgents = stats.StatsBlock[5].StatValue;
totalPrims = statsPacket.Stat[6].StatValue; totalPrims = stats.StatsBlock[6].StatValue;
activePrims = statsPacket.Stat[7].StatValue; activePrims = stats.StatsBlock[7].StatValue;
totalFrameTime = statsPacket.Stat[8].StatValue; totalFrameTime = stats.StatsBlock[8].StatValue;
netFrameTime = statsPacket.Stat[9].StatValue; netFrameTime = stats.StatsBlock[9].StatValue;
physicsFrameTime = statsPacket.Stat[10].StatValue; physicsFrameTime = stats.StatsBlock[10].StatValue;
otherFrameTime = statsPacket.Stat[11].StatValue; otherFrameTime = stats.StatsBlock[11].StatValue;
imageFrameTime = statsPacket.Stat[12].StatValue; imageFrameTime = stats.StatsBlock[12].StatValue;
inPacketsPerSecond = statsPacket.Stat[13].StatValue; inPacketsPerSecond = stats.StatsBlock[13].StatValue;
outPacketsPerSecond = statsPacket.Stat[14].StatValue; outPacketsPerSecond = stats.StatsBlock[14].StatValue;
unackedBytes = statsPacket.Stat[15].StatValue; unackedBytes = stats.StatsBlock[15].StatValue;
agentFrameTime = statsPacket.Stat[16].StatValue; agentFrameTime = stats.StatsBlock[16].StatValue;
pendingDownloads = statsPacket.Stat[17].StatValue; pendingDownloads = stats.StatsBlock[17].StatValue;
pendingUploads = statsPacket.Stat[18].StatValue; pendingUploads = stats.StatsBlock[18].StatValue;
activeScripts = statsPacket.Stat[19].StatValue; activeScripts = stats.StatsBlock[19].StatValue;
scriptLinesPerSecond = statsPacket.Stat[20].StatValue; scriptLinesPerSecond = stats.StatsBlock[20].StatValue;
} }
/// <summary> /// <summary>

View File

@ -2610,9 +2610,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OutPacket(PacketPool.Instance.GetPacket(PacketType.DisableSimulator), ThrottleOutPacketType.Unknown); OutPacket(PacketPool.Instance.GetPacket(PacketType.DisableSimulator), ThrottleOutPacketType.Unknown);
} }
public void SendSimStats(Packet pack) public void SendSimStats(SimStats stats)
{ {
SimStatsPacket pack = new SimStatsPacket();
pack.Region.RegionX = stats.RegionX;
pack.Region.RegionY = stats.RegionY;
pack.Region.RegionFlags = stats.RegionFlags;
pack.Region.ObjectCapacity = stats.ObjectCapacity;
pack.Region = stats.RegionBlock;
pack.Stat = stats.StatsBlock;
pack.Header.Reliable = false; pack.Header.Reliable = false;
OutPacket(pack, ThrottleOutPacketType.Task); OutPacket(pack, ThrottleOutPacketType.Task);
} }

View File

@ -706,7 +706,7 @@ namespace OpenSim.Region.Environment.Modules.World.NPC
{ {
} }
public void SendSimStats(Packet pack) public void SendSimStats(SimStats stats)
{ {
} }

View File

@ -837,14 +837,14 @@ namespace OpenSim.Region.Environment.Scenes
} }
} }
private void SendSimStatsPackets(SimStatsPacket pack) private void SendSimStatsPackets(SimStats stats)
{ {
List<ScenePresence> StatSendAgents = GetScenePresences(); List<ScenePresence> StatSendAgents = GetScenePresences();
foreach (ScenePresence agent in StatSendAgents) foreach (ScenePresence agent in StatSendAgents)
{ {
if (!agent.IsChildAgent) if (!agent.IsChildAgent)
{ {
agent.ControllingClient.SendSimStats(pack); agent.ControllingClient.SendSimStats(stats);
} }
} }
} }

View File

@ -36,7 +36,7 @@ namespace OpenSim.Region.Environment.Scenes
{ {
public class SimStatsReporter public class SimStatsReporter
{ {
public delegate void SendStatResult(SimStatsPacket pack); public delegate void SendStatResult(SimStats stats);
public event SendStatResult OnSendStatsResult; public event SendStatResult OnSendStatsResult;
@ -100,12 +100,6 @@ namespace OpenSim.Region.Environment.Scenes
private int objectCapacity = 45000; private int objectCapacity = 45000;
SimStatsPacket.StatBlock[] sb = new SimStatsPacket.StatBlock[21];
SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock();
SimStatsPacket statpack = (SimStatsPacket)PacketPool.Instance.GetPacket(PacketType.SimStats);
private Scene m_scene; private Scene m_scene;
private RegionInfo ReportingRegion; private RegionInfo ReportingRegion;
@ -118,10 +112,7 @@ namespace OpenSim.Region.Environment.Scenes
statsUpdateFactor = (float)(statsUpdatesEveryMS / 1000); statsUpdateFactor = (float)(statsUpdatesEveryMS / 1000);
m_scene = scene; m_scene = scene;
ReportingRegion = scene.RegionInfo; ReportingRegion = scene.RegionInfo;
for (int i = 0; i<21;i++)
{
sb[i] = new SimStatsPacket.StatBlock();
}
m_report.AutoReset = true; m_report.AutoReset = true;
m_report.Interval = statsUpdatesEveryMS; m_report.Interval = statsUpdatesEveryMS;
m_report.Elapsed += new ElapsedEventHandler(statsHeartBeat); m_report.Elapsed += new ElapsedEventHandler(statsHeartBeat);
@ -140,26 +131,24 @@ namespace OpenSim.Region.Environment.Scenes
private void statsHeartBeat(object sender, EventArgs e) private void statsHeartBeat(object sender, EventArgs e)
{ {
SimStatsPacket.StatBlock[] sb = new SimStatsPacket.StatBlock[21];
SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock();
// Know what's not thread safe in Mono... modifying timers. // Know what's not thread safe in Mono... modifying timers.
// System.Console.WriteLine("Firing Stats Heart Beat"); // System.Console.WriteLine("Firing Stats Heart Beat");
lock (m_report) lock (m_report)
{ {
// Packet is already initialized and ready for data insert uint regionFlags = 0;
statpack.Region = rb;
statpack.Region.RegionX = ReportingRegion.RegionLocX;
statpack.Region.RegionY = ReportingRegion.RegionLocY;
try try
{ {
IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>(); IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>();
statpack.Region.RegionFlags = estateModule != null ? estateModule.GetRegionFlags() : (uint) 0; regionFlags = estateModule != null ? estateModule.GetRegionFlags() : (uint) 0;
} }
catch (Exception) catch (Exception)
{ {
statpack.Region.RegionFlags = (uint) 0; // leave region flags at 0
} }
statpack.Region.ObjectCapacity = (uint) objectCapacity;
#region various statistic googly moogly #region various statistic googly moogly
@ -190,6 +179,11 @@ namespace OpenSim.Region.Environment.Scenes
// / 10 divides the value by the number of times the sim heartbeat runs (10fps) // / 10 divides the value by the number of times the sim heartbeat runs (10fps)
// Then we divide the whole amount by the amount of seconds pass in between stats updates. // Then we divide the whole amount by the amount of seconds pass in between stats updates.
for (int i = 0; i<21;i++)
{
sb[i] = new SimStatsPacket.StatBlock();
}
sb[0].StatID = (uint) Stats.TimeDilation; sb[0].StatID = (uint) Stats.TimeDilation;
sb[0].StatValue = m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor)); sb[0].StatValue = m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor));
@ -253,12 +247,14 @@ namespace OpenSim.Region.Environment.Scenes
sb[20].StatID = (uint)Stats.ScriptLinesPerSecond; sb[20].StatID = (uint)Stats.ScriptLinesPerSecond;
sb[20].StatValue = m_scriptLinesPerSecond / statsUpdateFactor; sb[20].StatValue = m_scriptLinesPerSecond / statsUpdateFactor;
statpack.Stat = sb; SimStats simStats
= new SimStats(
ReportingRegion.RegionLocX, ReportingRegion.RegionLocY, regionFlags, (uint)objectCapacity, rb, sb);
handlerSendStatResult = OnSendStatsResult; handlerSendStatResult = OnSendStatsResult;
if (handlerSendStatResult != null) if (handlerSendStatResult != null)
{ {
handlerSendStatResult(statpack); handlerSendStatResult(simStats);
} }
resetvalues(); resetvalues();
} }

View File

@ -625,7 +625,7 @@ namespace OpenSim.Region.Examples.SimpleModule
{ {
} }
public void SendSimStats(Packet pack) public void SendSimStats(SimStats stats)
{ {
} }