diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP')
7 files changed, 348 insertions, 59 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 7427c59..4fd81fa 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -817,8 +817,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
817 | OutPacket(mov, ThrottleOutPacketType.Unknown); | 817 | OutPacket(mov, ThrottleOutPacketType.Unknown); |
818 | } | 818 | } |
819 | 819 | ||
820 | public void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName, | 820 | public void SendChatMessage( |
821 | UUID fromAgentID, byte source, byte audible) | 821 | string message, byte type, Vector3 fromPos, string fromName, |
822 | UUID fromAgentID, UUID ownerID, byte source, byte audible) | ||
822 | { | 823 | { |
823 | ChatFromSimulatorPacket reply = (ChatFromSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.ChatFromSimulator); | 824 | ChatFromSimulatorPacket reply = (ChatFromSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.ChatFromSimulator); |
824 | reply.ChatData.Audible = audible; | 825 | reply.ChatData.Audible = audible; |
@@ -827,7 +828,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
827 | reply.ChatData.SourceType = source; | 828 | reply.ChatData.SourceType = source; |
828 | reply.ChatData.Position = fromPos; | 829 | reply.ChatData.Position = fromPos; |
829 | reply.ChatData.FromName = Util.StringToBytes256(fromName); | 830 | reply.ChatData.FromName = Util.StringToBytes256(fromName); |
830 | reply.ChatData.OwnerID = fromAgentID; | 831 | reply.ChatData.OwnerID = ownerID; |
831 | reply.ChatData.SourceID = fromAgentID; | 832 | reply.ChatData.SourceID = fromAgentID; |
832 | 833 | ||
833 | OutPacket(reply, ThrottleOutPacketType.Task); | 834 | OutPacket(reply, ThrottleOutPacketType.Task); |
@@ -5218,8 +5219,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5218 | AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); | 5219 | AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); |
5219 | AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); | 5220 | AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); |
5220 | AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false); | 5221 | AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false); |
5221 | AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest, false); | 5222 | AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest); |
5222 | AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest, false); | 5223 | AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest); |
5223 | AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage); | 5224 | AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage); |
5224 | AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest); | 5225 | AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest); |
5225 | AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer); | 5226 | AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer); |
@@ -5319,9 +5320,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5319 | AddLocalPacketHandler(PacketType.RemoveTaskInventory, HandleRemoveTaskInventory); | 5320 | AddLocalPacketHandler(PacketType.RemoveTaskInventory, HandleRemoveTaskInventory); |
5320 | AddLocalPacketHandler(PacketType.MoveTaskInventory, HandleMoveTaskInventory); | 5321 | AddLocalPacketHandler(PacketType.MoveTaskInventory, HandleMoveTaskInventory); |
5321 | AddLocalPacketHandler(PacketType.RezScript, HandleRezScript); | 5322 | AddLocalPacketHandler(PacketType.RezScript, HandleRezScript); |
5322 | AddLocalPacketHandler(PacketType.MapLayerRequest, HandleMapLayerRequest, false); | 5323 | AddLocalPacketHandler(PacketType.MapLayerRequest, HandleMapLayerRequest); |
5323 | AddLocalPacketHandler(PacketType.MapBlockRequest, HandleMapBlockRequest, false); | 5324 | AddLocalPacketHandler(PacketType.MapBlockRequest, HandleMapBlockRequest); |
5324 | AddLocalPacketHandler(PacketType.MapNameRequest, HandleMapNameRequest, false); | 5325 | AddLocalPacketHandler(PacketType.MapNameRequest, HandleMapNameRequest); |
5325 | AddLocalPacketHandler(PacketType.TeleportLandmarkRequest, HandleTeleportLandmarkRequest); | 5326 | AddLocalPacketHandler(PacketType.TeleportLandmarkRequest, HandleTeleportLandmarkRequest); |
5326 | AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel); | 5327 | AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel); |
5327 | AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest); | 5328 | AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest); |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 419de66..a7628d2 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -70,6 +70,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
70 | public void AddScene(IScene scene) | 70 | public void AddScene(IScene scene) |
71 | { | 71 | { |
72 | m_udpServer.AddScene(scene); | 72 | m_udpServer.AddScene(scene); |
73 | |||
74 | StatsManager.RegisterStat( | ||
75 | new Stat( | ||
76 | "IncomingPacketsProcessedCount", | ||
77 | "Number of inbound UDP packets processed", | ||
78 | "Number of inbound UDP packets processed", | ||
79 | "", | ||
80 | "clientstack", | ||
81 | scene.Name, | ||
82 | StatType.Pull, | ||
83 | MeasuresOfInterest.AverageChangeOverTime, | ||
84 | stat => stat.Value = m_udpServer.IncomingPacketsProcessed, | ||
85 | StatVerbosity.Debug)); | ||
73 | } | 86 | } |
74 | 87 | ||
75 | public bool HandlesRegion(Location x) | 88 | public bool HandlesRegion(Location x) |
@@ -170,6 +183,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
170 | 183 | ||
171 | private Pool<IncomingPacket> m_incomingPacketPool; | 184 | private Pool<IncomingPacket> m_incomingPacketPool; |
172 | 185 | ||
186 | /// <summary> | ||
187 | /// Stat for number of packets in the main pool awaiting use. | ||
188 | /// </summary> | ||
189 | private Stat m_poolCountStat; | ||
190 | |||
191 | /// <summary> | ||
192 | /// Stat for number of packets in the inbound packet pool awaiting use. | ||
193 | /// </summary> | ||
194 | private Stat m_incomingPacketPoolStat; | ||
195 | |||
173 | private int m_defaultRTO = 0; | 196 | private int m_defaultRTO = 0; |
174 | private int m_maxRTO = 0; | 197 | private int m_maxRTO = 0; |
175 | private int m_ackTimeout = 0; | 198 | private int m_ackTimeout = 0; |
@@ -214,6 +237,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
214 | 237 | ||
215 | m_circuitManager = circuitManager; | 238 | m_circuitManager = circuitManager; |
216 | int sceneThrottleBps = 0; | 239 | int sceneThrottleBps = 0; |
240 | bool usePools = false; | ||
217 | 241 | ||
218 | IConfig config = configSource.Configs["ClientStack.LindenUDP"]; | 242 | IConfig config = configSource.Configs["ClientStack.LindenUDP"]; |
219 | if (config != null) | 243 | if (config != null) |
@@ -246,7 +270,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
246 | { | 270 | { |
247 | PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true); | 271 | PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true); |
248 | PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true); | 272 | PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true); |
249 | UsePools = packetConfig.GetBoolean("RecycleBaseUDPPackets", false); | 273 | usePools = packetConfig.GetBoolean("RecycleBaseUDPPackets", usePools); |
250 | } | 274 | } |
251 | 275 | ||
252 | #region BinaryStats | 276 | #region BinaryStats |
@@ -277,8 +301,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
277 | m_throttle = new TokenBucket(null, sceneThrottleBps); | 301 | m_throttle = new TokenBucket(null, sceneThrottleBps); |
278 | ThrottleRates = new ThrottleRates(configSource); | 302 | ThrottleRates = new ThrottleRates(configSource); |
279 | 303 | ||
280 | if (UsePools) | 304 | if (usePools) |
281 | m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500); | 305 | EnablePools(); |
282 | } | 306 | } |
283 | 307 | ||
284 | public void Start() | 308 | public void Start() |
@@ -331,6 +355,83 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
331 | base.StopInbound(); | 355 | base.StopInbound(); |
332 | } | 356 | } |
333 | 357 | ||
358 | protected override bool EnablePools() | ||
359 | { | ||
360 | if (!UsePools) | ||
361 | { | ||
362 | base.EnablePools(); | ||
363 | |||
364 | m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500); | ||
365 | |||
366 | return true; | ||
367 | } | ||
368 | |||
369 | return false; | ||
370 | } | ||
371 | |||
372 | protected override bool DisablePools() | ||
373 | { | ||
374 | if (UsePools) | ||
375 | { | ||
376 | base.DisablePools(); | ||
377 | |||
378 | StatsManager.DeregisterStat(m_incomingPacketPoolStat); | ||
379 | |||
380 | // We won't null out the pool to avoid a race condition with code that may be in the middle of using it. | ||
381 | |||
382 | return true; | ||
383 | } | ||
384 | |||
385 | return false; | ||
386 | } | ||
387 | |||
388 | /// <summary> | ||
389 | /// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene | ||
390 | /// stats. | ||
391 | /// </summary> | ||
392 | private void EnablePoolStats() | ||
393 | { | ||
394 | m_poolCountStat | ||
395 | = new Stat( | ||
396 | "UDPPacketBufferPoolCount", | ||
397 | "Objects within the UDPPacketBuffer pool", | ||
398 | "The number of objects currently stored within the UDPPacketBuffer pool", | ||
399 | "", | ||
400 | "clientstack", | ||
401 | m_scene.Name, | ||
402 | StatType.Pull, | ||
403 | stat => stat.Value = Pool.Count, | ||
404 | StatVerbosity.Debug); | ||
405 | |||
406 | StatsManager.RegisterStat(m_poolCountStat); | ||
407 | |||
408 | m_incomingPacketPoolStat | ||
409 | = new Stat( | ||
410 | "IncomingPacketPoolCount", | ||
411 | "Objects within incoming packet pool", | ||
412 | "The number of objects currently stored within the incoming packet pool", | ||
413 | "", | ||
414 | "clientstack", | ||
415 | m_scene.Name, | ||
416 | StatType.Pull, | ||
417 | stat => stat.Value = m_incomingPacketPool.Count, | ||
418 | StatVerbosity.Debug); | ||
419 | |||
420 | StatsManager.RegisterStat(m_incomingPacketPoolStat); | ||
421 | } | ||
422 | |||
423 | /// <summary> | ||
424 | /// Disables pool stats. | ||
425 | /// </summary> | ||
426 | private void DisablePoolStats() | ||
427 | { | ||
428 | StatsManager.DeregisterStat(m_poolCountStat); | ||
429 | m_poolCountStat = null; | ||
430 | |||
431 | StatsManager.DeregisterStat(m_incomingPacketPoolStat); | ||
432 | m_incomingPacketPoolStat = null; | ||
433 | } | ||
434 | |||
334 | /// <summary> | 435 | /// <summary> |
335 | /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging. | 436 | /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging. |
336 | /// </summary> | 437 | /// </summary> |
@@ -370,6 +471,65 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
370 | m_scene = (Scene)scene; | 471 | m_scene = (Scene)scene; |
371 | m_location = new Location(m_scene.RegionInfo.RegionHandle); | 472 | m_location = new Location(m_scene.RegionInfo.RegionHandle); |
372 | 473 | ||
474 | // XXX: These stats are also pool stats but we register them separately since they are currently not | ||
475 | // turned on and off by EnablePools()/DisablePools() | ||
476 | StatsManager.RegisterStat( | ||
477 | new PercentageStat( | ||
478 | "PacketsReused", | ||
479 | "Packets reused", | ||
480 | "Number of packets reused out of all requests to the packet pool", | ||
481 | "clientstack", | ||
482 | m_scene.Name, | ||
483 | StatType.Pull, | ||
484 | stat => | ||
485 | { PercentageStat pstat = (PercentageStat)stat; | ||
486 | pstat.Consequent = PacketPool.Instance.PacketsRequested; | ||
487 | pstat.Antecedent = PacketPool.Instance.PacketsReused; }, | ||
488 | StatVerbosity.Debug)); | ||
489 | |||
490 | StatsManager.RegisterStat( | ||
491 | new PercentageStat( | ||
492 | "PacketDataBlocksReused", | ||
493 | "Packet data blocks reused", | ||
494 | "Number of data blocks reused out of all requests to the packet pool", | ||
495 | "clientstack", | ||
496 | m_scene.Name, | ||
497 | StatType.Pull, | ||
498 | stat => | ||
499 | { PercentageStat pstat = (PercentageStat)stat; | ||
500 | pstat.Consequent = PacketPool.Instance.BlocksRequested; | ||
501 | pstat.Antecedent = PacketPool.Instance.BlocksReused; }, | ||
502 | StatVerbosity.Debug)); | ||
503 | |||
504 | StatsManager.RegisterStat( | ||
505 | new Stat( | ||
506 | "PacketsPoolCount", | ||
507 | "Objects within the packet pool", | ||
508 | "The number of objects currently stored within the packet pool", | ||
509 | "", | ||
510 | "clientstack", | ||
511 | m_scene.Name, | ||
512 | StatType.Pull, | ||
513 | stat => stat.Value = PacketPool.Instance.PacketsPooled, | ||
514 | StatVerbosity.Debug)); | ||
515 | |||
516 | StatsManager.RegisterStat( | ||
517 | new Stat( | ||
518 | "PacketDataBlocksPoolCount", | ||
519 | "Objects within the packet data block pool", | ||
520 | "The number of objects currently stored within the packet data block pool", | ||
521 | "", | ||
522 | "clientstack", | ||
523 | m_scene.Name, | ||
524 | StatType.Pull, | ||
525 | stat => stat.Value = PacketPool.Instance.BlocksPooled, | ||
526 | StatVerbosity.Debug)); | ||
527 | |||
528 | // We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by | ||
529 | // scene name | ||
530 | if (UsePools) | ||
531 | EnablePoolStats(); | ||
532 | |||
373 | MainConsole.Instance.Commands.AddCommand( | 533 | MainConsole.Instance.Commands.AddCommand( |
374 | "Debug", | 534 | "Debug", |
375 | false, | 535 | false, |
@@ -397,6 +557,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
397 | MainConsole.Instance.Commands.AddCommand( | 557 | MainConsole.Instance.Commands.AddCommand( |
398 | "Debug", | 558 | "Debug", |
399 | false, | 559 | false, |
560 | "debug lludp pool", | ||
561 | "debug lludp pool <on|off>", | ||
562 | "Turn object pooling within the lludp component on or off.", | ||
563 | HandlePoolCommand); | ||
564 | |||
565 | MainConsole.Instance.Commands.AddCommand( | ||
566 | "Debug", | ||
567 | false, | ||
400 | "debug lludp status", | 568 | "debug lludp status", |
401 | "debug lludp status", | 569 | "debug lludp status", |
402 | "Return status of LLUDP packet processing.", | 570 | "Return status of LLUDP packet processing.", |
@@ -437,6 +605,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
437 | StopOutbound(); | 605 | StopOutbound(); |
438 | } | 606 | } |
439 | 607 | ||
608 | private void HandlePoolCommand(string module, string[] args) | ||
609 | { | ||
610 | if (args.Length != 4) | ||
611 | { | ||
612 | MainConsole.Instance.Output("Usage: debug lludp pool <on|off>"); | ||
613 | return; | ||
614 | } | ||
615 | |||
616 | string enabled = args[3]; | ||
617 | |||
618 | if (enabled == "on") | ||
619 | { | ||
620 | if (EnablePools()) | ||
621 | { | ||
622 | EnablePoolStats(); | ||
623 | MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_scene.Name); | ||
624 | } | ||
625 | } | ||
626 | else if (enabled == "off") | ||
627 | { | ||
628 | if (DisablePools()) | ||
629 | { | ||
630 | DisablePoolStats(); | ||
631 | MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_scene.Name); | ||
632 | } | ||
633 | } | ||
634 | else | ||
635 | { | ||
636 | MainConsole.Instance.Output("Usage: debug lludp pool <on|off>"); | ||
637 | } | ||
638 | } | ||
639 | |||
440 | private void HandleStatusCommand(string module, string[] args) | 640 | private void HandleStatusCommand(string module, string[] args) |
441 | { | 641 | { |
442 | MainConsole.Instance.OutputFormat( | 642 | MainConsole.Instance.OutputFormat( |
@@ -444,6 +644,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
444 | 644 | ||
445 | MainConsole.Instance.OutputFormat( | 645 | MainConsole.Instance.OutputFormat( |
446 | "OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled"); | 646 | "OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled"); |
647 | |||
648 | MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_scene.Name, UsePools ? "on" : "off"); | ||
447 | } | 649 | } |
448 | 650 | ||
449 | public bool HandlesRegion(Location x) | 651 | public bool HandlesRegion(Location x) |
@@ -1473,6 +1675,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1473 | private int npacksSent = 0; | 1675 | private int npacksSent = 0; |
1474 | private int npackNotSent = 0; | 1676 | private int npackNotSent = 0; |
1475 | 1677 | ||
1678 | /// <summary> | ||
1679 | /// Number of inbound packets processed since startup. | ||
1680 | /// </summary> | ||
1681 | public long IncomingPacketsProcessed { get; private set; } | ||
1682 | |||
1476 | private void MonitoredClientOutgoingPacketHandler(IClientAPI client) | 1683 | private void MonitoredClientOutgoingPacketHandler(IClientAPI client) |
1477 | { | 1684 | { |
1478 | nticks++; | 1685 | nticks++; |
@@ -1532,7 +1739,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1532 | npacksSent++; | 1739 | npacksSent++; |
1533 | } | 1740 | } |
1534 | else | 1741 | else |
1742 | { | ||
1535 | npackNotSent++; | 1743 | npackNotSent++; |
1744 | } | ||
1536 | 1745 | ||
1537 | watch2.Stop(); | 1746 | watch2.Stop(); |
1538 | avgDequeueTicks = (nticks - 1) / (float)nticks * avgDequeueTicks + (watch2.ElapsedTicks / (float)nticks); | 1747 | avgDequeueTicks = (nticks - 1) / (float)nticks * avgDequeueTicks + (watch2.ElapsedTicks / (float)nticks); |
@@ -1540,7 +1749,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1540 | 1749 | ||
1541 | } | 1750 | } |
1542 | else | 1751 | else |
1752 | { | ||
1543 | m_log.WarnFormat("[LLUDPSERVER]: Client is not connected"); | 1753 | m_log.WarnFormat("[LLUDPSERVER]: Client is not connected"); |
1754 | } | ||
1544 | } | 1755 | } |
1545 | } | 1756 | } |
1546 | catch (Exception ex) | 1757 | catch (Exception ex) |
@@ -1604,6 +1815,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1604 | "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", | 1815 | "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", |
1605 | packet.Type, client.Name, m_scene.RegionInfo.RegionName); | 1816 | packet.Type, client.Name, m_scene.RegionInfo.RegionName); |
1606 | } | 1817 | } |
1818 | |||
1819 | IncomingPacketsProcessed++; | ||
1607 | } | 1820 | } |
1608 | 1821 | ||
1609 | protected void LogoutHandler(IClientAPI client) | 1822 | protected void LogoutHandler(IClientAPI client) |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 6e6b3ef..3f7ca2b 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 | { |
@@ -60,14 +61,14 @@ namespace OpenMetaverse | |||
60 | private bool m_asyncPacketHandling; | 61 | private bool m_asyncPacketHandling; |
61 | 62 | ||
62 | /// <summary> | 63 | /// <summary> |
63 | /// Pool to use for handling data. May be null if UsePools = false; | 64 | /// Are we to use object pool(s) to reduce memory churn when receiving data? |
64 | /// </summary> | 65 | /// </summary> |
65 | protected OpenSim.Framework.Pool<UDPPacketBuffer> m_pool; | 66 | public bool UsePools { get; protected set; } |
66 | 67 | ||
67 | /// <summary> | 68 | /// <summary> |
68 | /// Are we to use object pool(s) to reduce memory churn when receiving data? | 69 | /// Pool to use for handling data. May be null if UsePools = false; |
69 | /// </summary> | 70 | /// </summary> |
70 | public bool UsePools { get; protected set; } | 71 | protected OpenSim.Framework.Pool<UDPPacketBuffer> Pool { get; private set; } |
71 | 72 | ||
72 | /// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary> | 73 | /// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary> |
73 | public bool IsRunningInbound { get; private set; } | 74 | public bool IsRunningInbound { get; private set; } |
@@ -106,11 +107,6 @@ namespace OpenMetaverse | |||
106 | /// necessary</remarks> | 107 | /// necessary</remarks> |
107 | public void StartInbound(int recvBufferSize, bool asyncPacketHandling) | 108 | public void StartInbound(int recvBufferSize, bool asyncPacketHandling) |
108 | { | 109 | { |
109 | if (UsePools) | ||
110 | m_pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500); | ||
111 | else | ||
112 | m_pool = null; | ||
113 | |||
114 | m_asyncPacketHandling = asyncPacketHandling; | 110 | m_asyncPacketHandling = asyncPacketHandling; |
115 | 111 | ||
116 | if (!IsRunningInbound) | 112 | if (!IsRunningInbound) |
@@ -180,12 +176,40 @@ namespace OpenMetaverse | |||
180 | IsRunningOutbound = false; | 176 | IsRunningOutbound = false; |
181 | } | 177 | } |
182 | 178 | ||
179 | protected virtual bool EnablePools() | ||
180 | { | ||
181 | if (!UsePools) | ||
182 | { | ||
183 | Pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500); | ||
184 | |||
185 | UsePools = true; | ||
186 | |||
187 | return true; | ||
188 | } | ||
189 | |||
190 | return false; | ||
191 | } | ||
192 | |||
193 | protected virtual bool DisablePools() | ||
194 | { | ||
195 | if (UsePools) | ||
196 | { | ||
197 | UsePools = false; | ||
198 | |||
199 | // We won't null out the pool to avoid a race condition with code that may be in the middle of using it. | ||
200 | |||
201 | return true; | ||
202 | } | ||
203 | |||
204 | return false; | ||
205 | } | ||
206 | |||
183 | private void AsyncBeginReceive() | 207 | private void AsyncBeginReceive() |
184 | { | 208 | { |
185 | UDPPacketBuffer buf; | 209 | UDPPacketBuffer buf; |
186 | 210 | ||
187 | if (UsePools) | 211 | if (UsePools) |
188 | buf = m_pool.GetObject(); | 212 | buf = Pool.GetObject(); |
189 | else | 213 | else |
190 | buf = new UDPPacketBuffer(); | 214 | buf = new UDPPacketBuffer(); |
191 | 215 | ||
@@ -268,7 +292,7 @@ namespace OpenMetaverse | |||
268 | finally | 292 | finally |
269 | { | 293 | { |
270 | if (UsePools) | 294 | if (UsePools) |
271 | m_pool.ReturnObject(buffer); | 295 | Pool.ReturnObject(buffer); |
272 | 296 | ||
273 | // Synchronous mode waits until the packet callback completes | 297 | // Synchronous mode waits until the packet callback completes |
274 | // before starting the receive to fetch another packet | 298 | // before starting the receive to fetch another packet |
@@ -310,4 +334,4 @@ namespace OpenMetaverse | |||
310 | catch (ObjectDisposedException) { } | 334 | catch (ObjectDisposedException) { } |
311 | } | 335 | } |
312 | } | 336 | } |
313 | } | 337 | } \ 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 2a3d14f..1fdc410 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | |||
@@ -41,25 +41,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
41 | 41 | ||
42 | private static readonly PacketPool instance = new PacketPool(); | 42 | private static readonly PacketPool instance = new PacketPool(); |
43 | 43 | ||
44 | private bool packetPoolEnabled = true; | ||
45 | private bool dataBlockPoolEnabled = true; | ||
46 | |||
47 | private PercentageStat m_packetsReusedStat = new PercentageStat( | ||
48 | "PacketsReused", | ||
49 | "Packets reused", | ||
50 | "clientstack", | ||
51 | "packetpool", | ||
52 | StatVerbosity.Debug, | ||
53 | "Number of packets reused out of all requests to the packet pool"); | ||
54 | |||
55 | private PercentageStat m_blocksReusedStat = new PercentageStat( | ||
56 | "BlocksReused", | ||
57 | "Blocks reused", | ||
58 | "clientstack", | ||
59 | "packetpool", | ||
60 | StatVerbosity.Debug, | ||
61 | "Number of data blocks reused out of all requests to the packet pool"); | ||
62 | |||
63 | /// <summary> | 44 | /// <summary> |
64 | /// Pool of packets available for reuse. | 45 | /// Pool of packets available for reuse. |
65 | /// </summary> | 46 | /// </summary> |
@@ -72,22 +53,59 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
72 | get { return instance; } | 53 | get { return instance; } |
73 | } | 54 | } |
74 | 55 | ||
75 | public bool RecyclePackets | 56 | public bool RecyclePackets { get; set; } |
57 | |||
58 | public bool RecycleDataBlocks { get; set; } | ||
59 | |||
60 | /// <summary> | ||
61 | /// The number of packets pooled | ||
62 | /// </summary> | ||
63 | public int PacketsPooled | ||
76 | { | 64 | { |
77 | set { packetPoolEnabled = value; } | 65 | get |
78 | get { return packetPoolEnabled; } | 66 | { |
67 | lock (pool) | ||
68 | return pool.Count; | ||
69 | } | ||
79 | } | 70 | } |
80 | 71 | ||
81 | public bool RecycleDataBlocks | 72 | /// <summary> |
73 | /// The number of blocks pooled. | ||
74 | /// </summary> | ||
75 | public int BlocksPooled | ||
82 | { | 76 | { |
83 | set { dataBlockPoolEnabled = value; } | 77 | get |
84 | get { return dataBlockPoolEnabled; } | 78 | { |
79 | lock (DataBlocks) | ||
80 | return DataBlocks.Count; | ||
81 | } | ||
85 | } | 82 | } |
86 | 83 | ||
84 | /// <summary> | ||
85 | /// Number of packets requested. | ||
86 | /// </summary> | ||
87 | public long PacketsRequested { get; private set; } | ||
88 | |||
89 | /// <summary> | ||
90 | /// Number of packets reused. | ||
91 | /// </summary> | ||
92 | public long PacketsReused { get; private set; } | ||
93 | |||
94 | /// <summary> | ||
95 | /// Number of packet blocks requested. | ||
96 | /// </summary> | ||
97 | public long BlocksRequested { get; private set; } | ||
98 | |||
99 | /// <summary> | ||
100 | /// Number of packet blocks reused. | ||
101 | /// </summary> | ||
102 | public long BlocksReused { get; private set; } | ||
103 | |||
87 | private PacketPool() | 104 | private PacketPool() |
88 | { | 105 | { |
89 | StatsManager.RegisterStat(m_packetsReusedStat); | 106 | // defaults |
90 | StatsManager.RegisterStat(m_blocksReusedStat); | 107 | RecyclePackets = true; |
108 | RecycleDataBlocks = true; | ||
91 | } | 109 | } |
92 | 110 | ||
93 | /// <summary> | 111 | /// <summary> |
@@ -97,11 +115,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
97 | /// <returns>Guaranteed to always return a packet, whether from the pool or newly constructed.</returns> | 115 | /// <returns>Guaranteed to always return a packet, whether from the pool or newly constructed.</returns> |
98 | public Packet GetPacket(PacketType type) | 116 | public Packet GetPacket(PacketType type) |
99 | { | 117 | { |
100 | m_packetsReusedStat.Consequent++; | 118 | PacketsRequested++; |
101 | 119 | ||
102 | Packet packet; | 120 | Packet packet; |
103 | 121 | ||
104 | if (!packetPoolEnabled) | 122 | if (!RecyclePackets) |
105 | return Packet.BuildPacket(type); | 123 | return Packet.BuildPacket(type); |
106 | 124 | ||
107 | lock (pool) | 125 | lock (pool) |
@@ -118,7 +136,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
118 | // m_log.DebugFormat("[PACKETPOOL]: Pulling {0} packet", type); | 136 | // m_log.DebugFormat("[PACKETPOOL]: Pulling {0} packet", type); |
119 | 137 | ||
120 | // Recycle old packages | 138 | // Recycle old packages |
121 | m_packetsReusedStat.Antecedent++; | 139 | PacketsReused++; |
122 | 140 | ||
123 | packet = pool[type].Pop(); | 141 | packet = pool[type].Pop(); |
124 | } | 142 | } |
@@ -187,7 +205,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
187 | /// <param name="packet"></param> | 205 | /// <param name="packet"></param> |
188 | public void ReturnPacket(Packet packet) | 206 | public void ReturnPacket(Packet packet) |
189 | { | 207 | { |
190 | if (dataBlockPoolEnabled) | 208 | if (RecycleDataBlocks) |
191 | { | 209 | { |
192 | switch (packet.Type) | 210 | switch (packet.Type) |
193 | { | 211 | { |
@@ -211,7 +229,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
211 | } | 229 | } |
212 | } | 230 | } |
213 | 231 | ||
214 | if (packetPoolEnabled) | 232 | if (RecyclePackets) |
215 | { | 233 | { |
216 | switch (packet.Type) | 234 | switch (packet.Type) |
217 | { | 235 | { |
@@ -249,7 +267,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
249 | { | 267 | { |
250 | lock (DataBlocks) | 268 | lock (DataBlocks) |
251 | { | 269 | { |
252 | m_blocksReusedStat.Consequent++; | 270 | BlocksRequested++; |
253 | 271 | ||
254 | Stack<Object> s; | 272 | Stack<Object> s; |
255 | 273 | ||
@@ -257,7 +275,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
257 | { | 275 | { |
258 | if (s.Count > 0) | 276 | if (s.Count > 0) |
259 | { | 277 | { |
260 | m_blocksReusedStat.Antecedent++; | 278 | BlocksReused++; |
261 | return (T)s.Pop(); | 279 | return (T)s.Pop(); |
262 | } | 280 | } |
263 | } | 281 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..af2f6f8 --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs | |||
@@ -0,0 +1,33 @@ | |||
1 | using System.Reflection; | ||
2 | using System.Runtime.CompilerServices; | ||
3 | using System.Runtime.InteropServices; | ||
4 | |||
5 | // General Information about an assembly is controlled through the following | ||
6 | // set of attributes. Change these attribute values to modify the information | ||
7 | // associated with an assembly. | ||
8 | [assembly: AssemblyTitle("OpenSim.Region.ClientStack.LindenUDP")] | ||
9 | [assembly: AssemblyDescription("")] | ||
10 | [assembly: AssemblyConfiguration("")] | ||
11 | [assembly: AssemblyCompany("http://opensimulator.org")] | ||
12 | [assembly: AssemblyProduct("OpenSim")] | ||
13 | [assembly: AssemblyCopyright("OpenSimulator developers")] | ||
14 | [assembly: AssemblyTrademark("")] | ||
15 | [assembly: AssemblyCulture("")] | ||
16 | |||
17 | // Setting ComVisible to false makes the types in this assembly not visible | ||
18 | // to COM components. If you need to access a type in this assembly from | ||
19 | // COM, set the ComVisible attribute to true on that type. | ||
20 | [assembly: ComVisible(false)] | ||
21 | |||
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM | ||
23 | [assembly: Guid("9d3dbc6b-9d85-483b-af48-c1dfc261b7ac")] | ||
24 | |||
25 | // Version information for an assembly consists of the following four values: | ||
26 | // | ||
27 | // Major Version | ||
28 | // Minor Version | ||
29 | // Build Number | ||
30 | // Revision | ||
31 | // | ||
32 | [assembly: AssemblyVersion("0.7.5.*")] | ||
33 | [assembly: AssemblyFileVersion("1.0.0.0")] | ||
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs index 5fcf376..7d9f581 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs | |||
@@ -43,7 +43,7 @@ using OpenSim.Tests.Common.Mock; | |||
43 | namespace OpenSim.Region.ClientStack.LindenUDP.Tests | 43 | namespace OpenSim.Region.ClientStack.LindenUDP.Tests |
44 | { | 44 | { |
45 | [TestFixture] | 45 | [TestFixture] |
46 | public class LLImageManagerTests | 46 | public class LLImageManagerTests : OpenSimTestCase |
47 | { | 47 | { |
48 | private AssetBase m_testImageAsset; | 48 | private AssetBase m_testImageAsset; |
49 | private Scene scene; | 49 | private Scene scene; |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs index 0f88ec6..5f73a94 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs | |||
@@ -39,7 +39,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
39 | /// Tests for the LL packet handler | 39 | /// Tests for the LL packet handler |
40 | /// </summary> | 40 | /// </summary> |
41 | [TestFixture] | 41 | [TestFixture] |
42 | public class PacketHandlerTests | 42 | public class PacketHandlerTests : OpenSimTestCase |
43 | { | 43 | { |
44 | // [Test] | 44 | // [Test] |
45 | // /// <summary> | 45 | // /// <summary> |