diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 89 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | 51 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | 40 |
3 files changed, 166 insertions, 14 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index df4bbb3..b8951d9 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -173,6 +173,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
173 | private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>(); | 173 | private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>(); |
174 | private Pool<IncomingPacket> m_incomingPacketPool; | 174 | private Pool<IncomingPacket> m_incomingPacketPool; |
175 | 175 | ||
176 | private Stat m_incomingPacketPoolStat; | ||
177 | |||
176 | private int m_defaultRTO = 0; | 178 | private int m_defaultRTO = 0; |
177 | private int m_maxRTO = 0; | 179 | private int m_maxRTO = 0; |
178 | private int m_ackTimeout = 0; | 180 | private int m_ackTimeout = 0; |
@@ -217,6 +219,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
217 | 219 | ||
218 | m_circuitManager = circuitManager; | 220 | m_circuitManager = circuitManager; |
219 | int sceneThrottleBps = 0; | 221 | int sceneThrottleBps = 0; |
222 | bool usePools = false; | ||
220 | 223 | ||
221 | IConfig config = configSource.Configs["ClientStack.LindenUDP"]; | 224 | IConfig config = configSource.Configs["ClientStack.LindenUDP"]; |
222 | if (config != null) | 225 | if (config != null) |
@@ -249,7 +252,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
249 | { | 252 | { |
250 | PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true); | 253 | PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true); |
251 | PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true); | 254 | PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true); |
252 | UsePools = packetConfig.GetBoolean("RecycleBaseUDPPackets", false); | 255 | usePools = packetConfig.GetBoolean("RecycleBaseUDPPackets", usePools); |
253 | } | 256 | } |
254 | 257 | ||
255 | #region BinaryStats | 258 | #region BinaryStats |
@@ -280,8 +283,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
280 | m_throttle = new TokenBucket(null, sceneThrottleBps); | 283 | m_throttle = new TokenBucket(null, sceneThrottleBps); |
281 | ThrottleRates = new ThrottleRates(configSource); | 284 | ThrottleRates = new ThrottleRates(configSource); |
282 | 285 | ||
283 | if (UsePools) | 286 | if (usePools) |
284 | m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500); | 287 | EnablePools(); |
285 | } | 288 | } |
286 | 289 | ||
287 | public void Start() | 290 | public void Start() |
@@ -334,6 +337,50 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
334 | base.StopInbound(); | 337 | base.StopInbound(); |
335 | } | 338 | } |
336 | 339 | ||
340 | protected override bool EnablePools() | ||
341 | { | ||
342 | if (!UsePools) | ||
343 | { | ||
344 | base.EnablePools(); | ||
345 | |||
346 | m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500); | ||
347 | |||
348 | m_incomingPacketPoolStat | ||
349 | = new Stat( | ||
350 | "IncomingPacketPoolCount", | ||
351 | "Objects within incoming packet pool", | ||
352 | "The number of objects currently stored within the incoming packet pool", | ||
353 | "", | ||
354 | "clientstack", | ||
355 | "packetpool", | ||
356 | StatType.Pull, | ||
357 | stat => stat.Value = m_incomingPacketPool.Count, | ||
358 | StatVerbosity.Debug); | ||
359 | |||
360 | StatsManager.RegisterStat(m_incomingPacketPoolStat); | ||
361 | |||
362 | return true; | ||
363 | } | ||
364 | |||
365 | return false; | ||
366 | } | ||
367 | |||
368 | protected override bool DisablePools() | ||
369 | { | ||
370 | if (UsePools) | ||
371 | { | ||
372 | base.DisablePools(); | ||
373 | |||
374 | StatsManager.DeregisterStat(m_incomingPacketPoolStat); | ||
375 | |||
376 | // We won't null out the pool to avoid a race condition with code that may be in the middle of using it. | ||
377 | |||
378 | return true; | ||
379 | } | ||
380 | |||
381 | return false; | ||
382 | } | ||
383 | |||
337 | /// <summary> | 384 | /// <summary> |
338 | /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging. | 385 | /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging. |
339 | /// </summary> | 386 | /// </summary> |
@@ -400,6 +447,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
400 | MainConsole.Instance.Commands.AddCommand( | 447 | MainConsole.Instance.Commands.AddCommand( |
401 | "Debug", | 448 | "Debug", |
402 | false, | 449 | false, |
450 | "debug lludp pool", | ||
451 | "debug lludp pool <on|off>", | ||
452 | "Turn object pooling within the lludp component on or off.", | ||
453 | HandlePoolCommand); | ||
454 | |||
455 | MainConsole.Instance.Commands.AddCommand( | ||
456 | "Debug", | ||
457 | false, | ||
403 | "debug lludp status", | 458 | "debug lludp status", |
404 | "debug lludp status", | 459 | "debug lludp status", |
405 | "Return status of LLUDP packet processing.", | 460 | "Return status of LLUDP packet processing.", |
@@ -440,6 +495,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
440 | StopOutbound(); | 495 | StopOutbound(); |
441 | } | 496 | } |
442 | 497 | ||
498 | private void HandlePoolCommand(string module, string[] args) | ||
499 | { | ||
500 | if (args.Length != 4) | ||
501 | { | ||
502 | MainConsole.Instance.Output("Usage: debug lludp pool <on|off>"); | ||
503 | return; | ||
504 | } | ||
505 | |||
506 | string enabled = args[3]; | ||
507 | |||
508 | if (enabled == "on") | ||
509 | { | ||
510 | if (EnablePools()) | ||
511 | MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_scene.Name); | ||
512 | } | ||
513 | else if (enabled == "off") | ||
514 | { | ||
515 | if (DisablePools()) | ||
516 | MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_scene.Name); | ||
517 | } | ||
518 | else | ||
519 | { | ||
520 | MainConsole.Instance.Output("Usage: debug lludp pool <on|off>"); | ||
521 | } | ||
522 | } | ||
523 | |||
443 | private void HandleStatusCommand(string module, string[] args) | 524 | private void HandleStatusCommand(string module, string[] args) |
444 | { | 525 | { |
445 | MainConsole.Instance.OutputFormat( | 526 | MainConsole.Instance.OutputFormat( |
@@ -447,6 +528,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
447 | 528 | ||
448 | MainConsole.Instance.OutputFormat( | 529 | MainConsole.Instance.OutputFormat( |
449 | "OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled"); | 530 | "OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled"); |
531 | |||
532 | MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_scene.Name, UsePools ? "on" : "off"); | ||
450 | } | 533 | } |
451 | 534 | ||
452 | public bool HandlesRegion(Location x) | 535 | public bool HandlesRegion(Location x) |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index e7d8a30..8bd3461 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | |||
@@ -31,6 +31,7 @@ using System.Net.Sockets; | |||
31 | using System.Threading; | 31 | using System.Threading; |
32 | using log4net; | 32 | using log4net; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Framework.Monitoring; | ||
34 | 35 | ||
35 | namespace OpenMetaverse | 36 | namespace OpenMetaverse |
36 | { | 37 | { |
@@ -76,6 +77,8 @@ namespace OpenMetaverse | |||
76 | /// <remarks>If IsRunningOut = false, then any request to send a packet is simply dropped.</remarks> | 77 | /// <remarks>If IsRunningOut = false, then any request to send a packet is simply dropped.</remarks> |
77 | public bool IsRunningOutbound { get; private set; } | 78 | public bool IsRunningOutbound { get; private set; } |
78 | 79 | ||
80 | private Stat m_poolCountStat; | ||
81 | |||
79 | /// <summary> | 82 | /// <summary> |
80 | /// Default constructor | 83 | /// Default constructor |
81 | /// </summary> | 84 | /// </summary> |
@@ -106,11 +109,6 @@ namespace OpenMetaverse | |||
106 | /// necessary</remarks> | 109 | /// necessary</remarks> |
107 | public void StartInbound(int recvBufferSize, bool asyncPacketHandling) | 110 | public void StartInbound(int recvBufferSize, bool asyncPacketHandling) |
108 | { | 111 | { |
109 | if (UsePools) | ||
110 | m_pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500); | ||
111 | else | ||
112 | m_pool = null; | ||
113 | |||
114 | m_asyncPacketHandling = asyncPacketHandling; | 112 | m_asyncPacketHandling = asyncPacketHandling; |
115 | 113 | ||
116 | if (!IsRunningInbound) | 114 | if (!IsRunningInbound) |
@@ -176,6 +174,49 @@ namespace OpenMetaverse | |||
176 | IsRunningOutbound = false; | 174 | IsRunningOutbound = false; |
177 | } | 175 | } |
178 | 176 | ||
177 | protected virtual bool EnablePools() | ||
178 | { | ||
179 | if (!UsePools) | ||
180 | { | ||
181 | m_pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500); | ||
182 | |||
183 | m_poolCountStat | ||
184 | = new Stat( | ||
185 | "UDPPacketBufferPoolCount", | ||
186 | "Objects within the UDPPacketBuffer pool", | ||
187 | "The number of objects currently stored within the UDPPacketBuffer pool", | ||
188 | "", | ||
189 | "clientstack", | ||
190 | "packetpool", | ||
191 | StatType.Pull, | ||
192 | stat => stat.Value = m_pool.Count, | ||
193 | StatVerbosity.Debug); | ||
194 | |||
195 | StatsManager.RegisterStat(m_poolCountStat); | ||
196 | |||
197 | UsePools = true; | ||
198 | |||
199 | return true; | ||
200 | } | ||
201 | |||
202 | return false; | ||
203 | } | ||
204 | |||
205 | protected virtual bool DisablePools() | ||
206 | { | ||
207 | if (UsePools) | ||
208 | { | ||
209 | UsePools = false; | ||
210 | StatsManager.DeregisterStat(m_poolCountStat); | ||
211 | |||
212 | // We won't null out the pool to avoid a race condition with code that may be in the middle of using it. | ||
213 | |||
214 | return true; | ||
215 | } | ||
216 | |||
217 | return false; | ||
218 | } | ||
219 | |||
179 | private void AsyncBeginReceive() | 220 | private void AsyncBeginReceive() |
180 | { | 221 | { |
181 | UDPPacketBuffer buf; | 222 | UDPPacketBuffer buf; |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs index 2a3d14f..9f22fb4 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | |||
@@ -47,18 +47,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
47 | private PercentageStat m_packetsReusedStat = new PercentageStat( | 47 | private PercentageStat m_packetsReusedStat = new PercentageStat( |
48 | "PacketsReused", | 48 | "PacketsReused", |
49 | "Packets reused", | 49 | "Packets reused", |
50 | "Number of packets reused out of all requests to the packet pool", | ||
50 | "clientstack", | 51 | "clientstack", |
51 | "packetpool", | 52 | "packetpool", |
52 | StatVerbosity.Debug, | 53 | StatType.Push, |
53 | "Number of packets reused out of all requests to the packet pool"); | 54 | null, |
55 | StatVerbosity.Debug); | ||
54 | 56 | ||
55 | private PercentageStat m_blocksReusedStat = new PercentageStat( | 57 | private PercentageStat m_blocksReusedStat = new PercentageStat( |
56 | "BlocksReused", | 58 | "PacketDataBlocksReused", |
57 | "Blocks reused", | 59 | "Packet data blocks reused", |
60 | "Number of data blocks reused out of all requests to the packet pool", | ||
58 | "clientstack", | 61 | "clientstack", |
59 | "packetpool", | 62 | "packetpool", |
60 | StatVerbosity.Debug, | 63 | StatType.Push, |
61 | "Number of data blocks reused out of all requests to the packet pool"); | 64 | null, |
65 | StatVerbosity.Debug); | ||
62 | 66 | ||
63 | /// <summary> | 67 | /// <summary> |
64 | /// Pool of packets available for reuse. | 68 | /// Pool of packets available for reuse. |
@@ -88,6 +92,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
88 | { | 92 | { |
89 | StatsManager.RegisterStat(m_packetsReusedStat); | 93 | StatsManager.RegisterStat(m_packetsReusedStat); |
90 | StatsManager.RegisterStat(m_blocksReusedStat); | 94 | StatsManager.RegisterStat(m_blocksReusedStat); |
95 | |||
96 | StatsManager.RegisterStat( | ||
97 | new Stat( | ||
98 | "PacketsPoolCount", | ||
99 | "Objects within the packet pool", | ||
100 | "The number of objects currently stored within the packet pool", | ||
101 | "", | ||
102 | "clientstack", | ||
103 | "packetpool", | ||
104 | StatType.Pull, | ||
105 | stat => { lock (pool) { stat.Value = pool.Count; } }, | ||
106 | StatVerbosity.Debug)); | ||
107 | |||
108 | StatsManager.RegisterStat( | ||
109 | new Stat( | ||
110 | "PacketDataBlocksPoolCount", | ||
111 | "Objects within the packet data block pool", | ||
112 | "The number of objects currently stored within the packet data block pool", | ||
113 | "", | ||
114 | "clientstack", | ||
115 | "packetpool", | ||
116 | StatType.Pull, | ||
117 | stat => { lock (DataBlocks) { stat.Value = DataBlocks.Count; } }, | ||
118 | StatVerbosity.Debug)); | ||
91 | } | 119 | } |
92 | 120 | ||
93 | /// <summary> | 121 | /// <summary> |