diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 4844336e31..cebe905f18 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -382,14 +382,20 @@ namespace OpenSim.Framework.Monitoring
public class PercentageStat : Stat
{
- public int Antecedent { get; set; }
- public int Consequent { get; set; }
+ public long Antecedent { get; set; }
+ public long Consequent { get; set; }
public override double Value
{
get
{
- int c = Consequent;
+ // Asking for an update here means that the updater cannot access this value without infinite recursion.
+ // XXX: A slightly messy but simple solution may be to flick a flag so we can tell if this is being
+ // called by the pull action and just return the value.
+ if (StatType == StatType.Pull)
+ PullAction(this);
+
+ long c = Consequent;
// Avoid any chance of a multi-threaded divide-by-zero
if (c == 0)
@@ -400,7 +406,7 @@ namespace OpenSim.Framework.Monitoring
set
{
- throw new Exception("Cannot set value on a PercentageStat");
+ throw new InvalidOperationException("Cannot set value on a PercentageStat");
}
}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index f8391d77bd..fcc69c0a4e 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -469,6 +469,60 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_scene = (Scene)scene;
m_location = new Location(m_scene.RegionInfo.RegionHandle);
+
+ // XXX: These stats are also pool stats but we register them separately since they are currently not
+ // turned on and off by EnablePools()/DisablePools()
+ StatsManager.RegisterStat(
+ new PercentageStat(
+ "PacketsReused",
+ "Packets reused",
+ "Number of packets reused out of all requests to the packet pool",
+ "clientstack",
+ m_scene.Name,
+ StatType.Pull,
+ stat =>
+ { PercentageStat pstat = (PercentageStat)stat;
+ pstat.Consequent = PacketPool.Instance.PacketsRequested;
+ pstat.Antecedent = PacketPool.Instance.PacketsReused; },
+ StatVerbosity.Debug));
+
+ StatsManager.RegisterStat(
+ new PercentageStat(
+ "PacketDataBlocksReused",
+ "Packet data blocks reused",
+ "Number of data blocks reused out of all requests to the packet pool",
+ "clientstack",
+ m_scene.Name,
+ StatType.Pull,
+ stat =>
+ { PercentageStat pstat = (PercentageStat)stat;
+ pstat.Consequent = PacketPool.Instance.BlocksRequested;
+ pstat.Antecedent = PacketPool.Instance.BlocksReused; },
+ StatVerbosity.Debug));
+
+ StatsManager.RegisterStat(
+ new Stat(
+ "PacketsPoolCount",
+ "Objects within the packet pool",
+ "The number of objects currently stored within the packet pool",
+ "",
+ "clientstack",
+ m_scene.Name,
+ StatType.Pull,
+ stat => stat.Value = PacketPool.Instance.PacketsPooled,
+ StatVerbosity.Debug));
+
+ StatsManager.RegisterStat(
+ new Stat(
+ "PacketDataBlocksPoolCount",
+ "Objects within the packet data block pool",
+ "The number of objects currently stored within the packet data block pool",
+ "",
+ "clientstack",
+ m_scene.Name,
+ StatType.Pull,
+ stat => stat.Value = PacketPool.Instance.BlocksPooled,
+ StatVerbosity.Debug));
// We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by
// scene name
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 808d177dfa..3f7ca2b941 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -334,4 +334,4 @@ namespace OpenMetaverse
catch (ObjectDisposedException) { }
}
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
index 9f22fb48ec..1fdc410430 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
@@ -41,29 +41,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private static readonly PacketPool instance = new PacketPool();
- private bool packetPoolEnabled = true;
- private bool dataBlockPoolEnabled = true;
-
- private PercentageStat m_packetsReusedStat = new PercentageStat(
- "PacketsReused",
- "Packets reused",
- "Number of packets reused out of all requests to the packet pool",
- "clientstack",
- "packetpool",
- StatType.Push,
- null,
- StatVerbosity.Debug);
-
- private PercentageStat m_blocksReusedStat = new PercentageStat(
- "PacketDataBlocksReused",
- "Packet data blocks reused",
- "Number of data blocks reused out of all requests to the packet pool",
- "clientstack",
- "packetpool",
- StatType.Push,
- null,
- StatVerbosity.Debug);
-
///
/// Pool of packets available for reuse.
///
@@ -76,46 +53,59 @@ namespace OpenSim.Region.ClientStack.LindenUDP
get { return instance; }
}
- public bool RecyclePackets
+ public bool RecyclePackets { get; set; }
+
+ public bool RecycleDataBlocks { get; set; }
+
+ ///
+ /// The number of packets pooled
+ ///
+ public int PacketsPooled
{
- set { packetPoolEnabled = value; }
- get { return packetPoolEnabled; }
+ get
+ {
+ lock (pool)
+ return pool.Count;
+ }
}
- public bool RecycleDataBlocks
+ ///
+ /// The number of blocks pooled.
+ ///
+ public int BlocksPooled
{
- set { dataBlockPoolEnabled = value; }
- get { return dataBlockPoolEnabled; }
+ get
+ {
+ lock (DataBlocks)
+ return DataBlocks.Count;
+ }
}
+ ///
+ /// Number of packets requested.
+ ///
+ public long PacketsRequested { get; private set; }
+
+ ///
+ /// Number of packets reused.
+ ///
+ public long PacketsReused { get; private set; }
+
+ ///
+ /// Number of packet blocks requested.
+ ///
+ public long BlocksRequested { get; private set; }
+
+ ///
+ /// Number of packet blocks reused.
+ ///
+ public long BlocksReused { get; private set; }
+
private PacketPool()
{
- StatsManager.RegisterStat(m_packetsReusedStat);
- StatsManager.RegisterStat(m_blocksReusedStat);
-
- StatsManager.RegisterStat(
- new Stat(
- "PacketsPoolCount",
- "Objects within the packet pool",
- "The number of objects currently stored within the packet pool",
- "",
- "clientstack",
- "packetpool",
- StatType.Pull,
- stat => { lock (pool) { stat.Value = pool.Count; } },
- StatVerbosity.Debug));
-
- StatsManager.RegisterStat(
- new Stat(
- "PacketDataBlocksPoolCount",
- "Objects within the packet data block pool",
- "The number of objects currently stored within the packet data block pool",
- "",
- "clientstack",
- "packetpool",
- StatType.Pull,
- stat => { lock (DataBlocks) { stat.Value = DataBlocks.Count; } },
- StatVerbosity.Debug));
+ // defaults
+ RecyclePackets = true;
+ RecycleDataBlocks = true;
}
///
@@ -125,11 +115,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// Guaranteed to always return a packet, whether from the pool or newly constructed.
public Packet GetPacket(PacketType type)
{
- m_packetsReusedStat.Consequent++;
+ PacketsRequested++;
Packet packet;
- if (!packetPoolEnabled)
+ if (!RecyclePackets)
return Packet.BuildPacket(type);
lock (pool)
@@ -146,7 +136,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// m_log.DebugFormat("[PACKETPOOL]: Pulling {0} packet", type);
// Recycle old packages
- m_packetsReusedStat.Antecedent++;
+ PacketsReused++;
packet = pool[type].Pop();
}
@@ -215,7 +205,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
///
public void ReturnPacket(Packet packet)
{
- if (dataBlockPoolEnabled)
+ if (RecycleDataBlocks)
{
switch (packet.Type)
{
@@ -239,7 +229,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
}
- if (packetPoolEnabled)
+ if (RecyclePackets)
{
switch (packet.Type)
{
@@ -277,7 +267,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
lock (DataBlocks)
{
- m_blocksReusedStat.Consequent++;
+ BlocksRequested++;
Stack