From e76b01a201a9b2d45b56cd5dc2a207b08b4529e5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 10 Oct 2012 00:26:43 +0100 Subject: Lock on AgentCircuitData during Scene.AddClient() and RemoveClient() to prevent an inactive connection being left behind if the user closes the viewer whilst the connection is being established. This should remove the need to run the console command "kick user --force" when these connections are left around. --- .../Linden/Caps/EventQueue/EventQueueGetModule.cs | 13 ++----------- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 14 +++++++------- 2 files changed, 9 insertions(+), 18 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 594b229..0dd0904 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden //scene.CommsManager.HttpServer.AddLLSDHandler("/CAPS/EQG/", EventQueueFallBack); - scene.EventManager.OnNewClient += OnNewClient; +// scene.EventManager.OnNewClient += OnNewClient; // TODO: Leaving these open, or closing them when we // become a child is incorrect. It messes up TP in a big @@ -102,6 +102,7 @@ namespace OpenSim.Region.ClientStack.Linden // circuit is there. scene.EventManager.OnClientClosed += ClientClosed; + scene.EventManager.OnMakeChildAgent += MakeChildAgent; scene.EventManager.OnRegisterCaps += OnRegisterCaps; @@ -226,16 +227,6 @@ namespace OpenSim.Region.ClientStack.Linden #endregion - private void OnNewClient(IClientAPI client) - { - //client.OnLogout += ClientClosed; - } - -// private void ClientClosed(IClientAPI client) -// { -// ClientClosed(client.AgentId); -// } - private void ClientClosed(UUID agentID, Scene scene) { // m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index d11fcbf..ab670a7 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1103,20 +1103,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP { IClientAPI client = null; - // In priciple there shouldn't be more than one thread here, ever. - // But in case that happens, we need to synchronize this piece of code - // because it's too important - lock (this) + // We currently synchronize this code across the whole scene to avoid issues such as + // http://opensimulator.org/mantis/view.php?id=5365 However, once locking per agent circuit can be done + // consistently, this lock could probably be removed. + lock (this) { if (!m_scene.TryGetClient(agentID, out client)) { LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO); - + client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); client.OnLogout += LogoutHandler; - + ((LLClientView)client).DisableFacelights = m_disableFacelights; - + client.Start(); } } -- cgit v1.1 From 1f2472d0fcd86a7ae09c01ecb3508eab001ce033 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Oct 2012 23:28:53 +0100 Subject: Extend "show stats" command to "show stats [list|all|]" This allows different categories of stats to be shown, with options to list categories or show all stats. Currently categories are scene and simulator and only a very few stats are currently registered via this mechanism. This commit also adds percentage stats for packets and blocks reused from the packet pool. --- .../Region/ClientStack/Linden/UDP/PacketPool.cs | 43 ++++++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs index fc9406b..3d9f94f 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs @@ -31,6 +31,7 @@ using System.Reflection; using OpenMetaverse; using OpenMetaverse.Packets; using log4net; +using OpenSim.Framework.Monitoring; namespace OpenSim.Region.ClientStack.LindenUDP { @@ -43,17 +44,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP private bool packetPoolEnabled = true; private bool dataBlockPoolEnabled = true; + private PercentageStat m_packetsReusedStat = new PercentageStat( + "PacketsReused", + "Packets reused", + "simulator", + "simulator", + StatVerbosity.Debug, + "Number of packets reused out of all requests to the packet pool"); + + private PercentageStat m_blocksReusedStat = new PercentageStat( + "BlocksReused", + "Blocks reused", + "simulator", + "simulator", + StatVerbosity.Debug, + "Number of data blocks reused out of all requests to the packet pool"); + /// /// Pool of packets available for reuse. /// private readonly Dictionary> pool = new Dictionary>(); - private static Dictionary> DataBlocks = - new Dictionary>(); - - static PacketPool() - { - } + private static Dictionary> DataBlocks = new Dictionary>(); public static PacketPool Instance { @@ -72,8 +84,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP get { return dataBlockPoolEnabled; } } + private PacketPool() + { + StatsManager.RegisterStat(m_packetsReusedStat); + StatsManager.RegisterStat(m_blocksReusedStat); + } + public Packet GetPacket(PacketType type) { + m_packetsReusedStat.Consequent++; + Packet packet; if (!packetPoolEnabled) @@ -89,6 +109,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP else { // Recycle old packages + m_packetsReusedStat.Antecedent++; + packet = (pool[type]).Pop(); } } @@ -211,16 +233,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - public static T GetDataBlock() where T: new() + public T GetDataBlock() where T: new() { lock (DataBlocks) { + m_blocksReusedStat.Consequent++; + Stack s; if (DataBlocks.TryGetValue(typeof(T), out s)) { if (s.Count > 0) + { + m_blocksReusedStat.Antecedent++; return (T)s.Pop(); + } } else { @@ -231,7 +258,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - public static void ReturnDataBlock(T block) where T: new() + public void ReturnDataBlock(T block) where T: new() { if (block == null) return; -- cgit v1.1 From 2e9ef015f7b73a3942011a36a9f94ce59d848dc0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Oct 2012 23:58:37 +0100 Subject: Fix packetpool for ImprovedTerseObjectUpdate packets. These were neither being returned or in many places reused. Getting packets from a pool rather than deallocating and reallocating reduces memory churn which in turn reduces garbage collection time and frequency. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 14 +++++++++++--- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 2 ++ OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | 4 ++-- 3 files changed, 15 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 62f51d9..dc88686 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3922,7 +3922,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP { List blocks = terseAgentUpdateBlocks.Value; - ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); + ImprovedTerseObjectUpdatePacket packet + = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); + packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; packet.RegionData.TimeDilation = timeDilation; packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; @@ -3967,7 +3969,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP { List blocks = terseUpdateBlocks.Value; - ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); + ImprovedTerseObjectUpdatePacket packet + = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket( + PacketType.ImprovedTerseObjectUpdate); + packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; packet.RegionData.TimeDilation = timeDilation; packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; @@ -12286,7 +12291,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f); - ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); + ImprovedTerseObjectUpdatePacket packet + = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket( + PacketType.ImprovedTerseObjectUpdate); + packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; packet.RegionData.TimeDilation = timeDilation; packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index ab670a7..6d2cda5 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -420,6 +420,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP byte[] data = packet.ToBytes(); SendPacketData(udpClient, data, packet.Type, category, method); } + + PacketPool.Instance.ReturnPacket(packet); } /// diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs index 3d9f94f..fd6b0ed 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs @@ -47,7 +47,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP private PercentageStat m_packetsReusedStat = new PercentageStat( "PacketsReused", "Packets reused", - "simulator", + "clientstack", "simulator", StatVerbosity.Debug, "Number of packets reused out of all requests to the packet pool"); @@ -55,7 +55,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP private PercentageStat m_blocksReusedStat = new PercentageStat( "BlocksReused", "Blocks reused", - "simulator", + "clientstack", "simulator", StatVerbosity.Debug, "Number of data blocks reused out of all requests to the packet pool"); -- cgit v1.1 From 8a402850ddbdd9497998774b646c8e0ae6ef1eb8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Oct 2012 00:21:45 +0100 Subject: Enable reuse of data blocks for ImprovedTerseObjectUpdate using existing Packetpool code. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index dc88686..5f9face 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4964,7 +4964,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2; - ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock(); + ImprovedTerseObjectUpdatePacket.ObjectDataBlock block + = PacketPool.Instance.GetDataBlock(); + block.Data = data; if (textureEntry != null && textureEntry.Length > 0) -- cgit v1.1 From 59a17ad676326d5affc2e221ef9c02166a85c6fd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Oct 2012 00:26:15 +0100 Subject: Fix percentage stats to multiply by 100. Adjust container name for packetpool stats. --- OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs index fd6b0ed..a8a1bfe 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs @@ -48,14 +48,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP "PacketsReused", "Packets reused", "clientstack", - "simulator", + "packetpool", StatVerbosity.Debug, "Number of packets reused out of all requests to the packet pool"); private PercentageStat m_blocksReusedStat = new PercentageStat( "BlocksReused", "Blocks reused", - "clientstack", + "packetpool", "simulator", StatVerbosity.Debug, "Number of data blocks reused out of all requests to the packet pool"); -- cgit v1.1 From 21d0cbf7038cfb1b1010310a0f4b455cf9ab700d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Oct 2012 01:39:37 +0100 Subject: Add AgentUpdate to PacketPool. This is the most common inbound packet from viewers. --- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 21 +++++++++++++++++++-- OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | 8 +++++++- .../Linden/UDP/Tests/BasicCircuitTests.cs | 4 ++-- 3 files changed, 28 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 6d2cda5..e3f4679 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -100,9 +100,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// The measured resolution of Environment.TickCount public readonly float TickCountResolution; + /// Number of prim updates to put on the queue each time the /// OnQueueEmpty event is triggered for updates public readonly int PrimUpdatesPerCallback; + /// Number of texture packets to put on the queue each time the /// OnQueueEmpty event is triggered for textures public readonly int TextureSendLimit; @@ -111,6 +113,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP //PacketEventDictionary packetEvents = new PacketEventDictionary(); /// Incoming packets that are awaiting handling private OpenMetaverse.BlockingQueue packetInbox = new OpenMetaverse.BlockingQueue(); + /// //private UDPClientCollection m_clients = new UDPClientCollection(); /// Bandwidth throttle for this UDP server @@ -121,28 +124,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Manages authentication for agent circuits private AgentCircuitManager m_circuitManager; + /// Reference to the scene this UDP server is attached to protected Scene m_scene; + /// The X/Y coordinates of the scene this UDP server is attached to private Location m_location; + /// The size of the receive buffer for the UDP socket. This value /// is passed up to the operating system and used in the system networking /// stack. Use zero to leave this value as the default private int m_recvBufferSize; + /// Flag to process packets asynchronously or synchronously private bool m_asyncPacketHandling; + /// Tracks whether or not a packet was sent each round so we know /// whether or not to sleep private bool m_packetSent; /// Environment.TickCount of the last time that packet stats were reported to the scene private int m_elapsedMSSinceLastStatReport = 0; + /// Environment.TickCount of the last time the outgoing packet handler executed private int m_tickLastOutgoingPacketHandler; + /// Keeps track of the number of elapsed milliseconds since the last time the outgoing packet handler looped private int m_elapsedMSOutgoingPacketHandler; + /// Keeps track of the number of 100 millisecond periods elapsed in the outgoing packet handler executed private int m_elapsed100MSOutgoingPacketHandler; + /// Keeps track of the number of 500 millisecond periods elapsed in the outgoing packet handler executed private int m_elapsed500MSOutgoingPacketHandler; @@ -739,7 +751,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP try { - packet = Packet.BuildPacket(buffer.Data, ref packetEnd, +// packet = Packet.BuildPacket(buffer.Data, ref packetEnd, +// // Only allocate a buffer for zerodecoding if the packet is zerocoded +// ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); + packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd, // Only allocate a buffer for zerodecoding if the packet is zerocoded ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); } @@ -754,11 +769,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP return; // Drop short packet } - catch(Exception e) + catch (Exception e) { if (m_malformedCount < 100) m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString()); + m_malformedCount++; + if ((m_malformedCount % 100000) == 0) m_log.DebugFormat("[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack.", m_malformedCount); } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs index a8a1bfe..052d334 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs @@ -90,6 +90,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP StatsManager.RegisterStat(m_blocksReusedStat); } + /// + /// Gets a packet of the given type. + /// + /// + /// Guaranteed to always return a packet, whether from the pool or newly constructed. public Packet GetPacket(PacketType type) { m_packetsReusedStat.Consequent++; @@ -160,7 +165,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { PacketType type = GetType(bytes); - Array.Clear(zeroBuffer, 0, zeroBuffer.Length); +// Array.Clear(zeroBuffer, 0, zeroBuffer.Length); int i = 0; Packet packet = GetPacket(type); @@ -207,6 +212,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP switch (packet.Type) { // List pooling packets here + case PacketType.AgentUpdate: case PacketType.PacketAck: case PacketType.ObjectUpdate: case PacketType.ImprovedTerseObjectUpdate: diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs index 109a8e1..fa9378c 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs @@ -43,7 +43,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests /// This will contain basic tests for the LindenUDP client stack /// [TestFixture] - public class BasicCircuitTests + public class BasicCircuitTests : OpenSimTestCase { private Scene m_scene; private TestLLUDPServer m_udpServer; @@ -143,7 +143,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests public void TestAddClient() { TestHelpers.InMethod(); -// XmlConfigurator.Configure(); +// TestHelpers.EnableLogging(); AddUdpServer(); -- cgit v1.1 From 8873a4a8fcaa3372713463094f2cfebeaaf45834 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Oct 2012 01:59:47 +0100 Subject: minor: Fix bug in categorization of blocks reused stat from packetpool --- OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs index 052d334..71f6fe1 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs @@ -55,8 +55,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP private PercentageStat m_blocksReusedStat = new PercentageStat( "BlocksReused", "Blocks reused", + "clientstack", "packetpool", - "simulator", StatVerbosity.Debug, "Number of data blocks reused out of all requests to the packet pool"); -- cgit v1.1 From b7e75d467c2edf052b0cf5216043937ebf583ef4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Oct 2012 02:10:30 +0100 Subject: minor: Use && instead of & when deciding whether to print Improve/ObjectUpdate packet out messages when debug is turned on. Practical effect is probably none. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 5f9face..2db8df2 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -11765,7 +11765,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP logPacket = false; if (DebugPacketLevel <= 50 - & (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate)) + && (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate)) logPacket = false; if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily) -- cgit v1.1 From dc460579fd94b2017e334e71ffd20d94a3dec425 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 13 Oct 2012 01:47:10 +0100 Subject: minor: Fix and elaborate on log information printed when an unrecognized estate method is received from the client. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 2db8df2..0d4f09d 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -9063,7 +9063,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - switch (Utils.BytesToString(messagePacket.MethodData.Method)) + string method = Utils.BytesToString(messagePacket.MethodData.Method); + + switch (method) { case "getinfo": if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false)) @@ -9379,7 +9381,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP return true; default: - m_log.Error("EstateOwnerMessage: Unknown method requested\n" + messagePacket); + m_log.WarnFormat( + "[LLCLIENTVIEW]: EstateOwnerMessage: Unknown method {0} requested for {1} in {2}", + method, Name, Scene.Name); + + for (int i = 0; i < messagePacket.ParamList.Length; i++) + { + EstateOwnerMessagePacket.ParamListBlock block = messagePacket.ParamList[i]; + string data = (string)Utils.BytesToString(block.Parameter); + m_log.DebugFormat("[LLCLIENTVIEW]: Param {0}={1}", i, data); + } + return true; } -- cgit v1.1 From 8c2564c05cbf277bef85bba62313f5d5493a4a81 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 16 Oct 2012 00:40:28 +0100 Subject: minor: Comment out the region console caps message for now. --- OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs index 36af55f..17c7270 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs @@ -107,7 +107,7 @@ namespace OpenSim.Region.ClientStack.Linden UUID capID = UUID.Random(); - m_log.DebugFormat("[REGION CONSOLE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); +// m_log.DebugFormat("[REGION CONSOLE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); caps.RegisterHandler( "SimConsoleAsync", new ConsoleHandler("/CAPS/" + capID + "/", "SimConsoleAsync", agentID, this, m_scene)); -- cgit v1.1 From 3ac6a423f7748bf9d5da0d1bd8fc62652ed8e151 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 16 Oct 2012 00:54:25 +0100 Subject: minor: comment out "Registered seed capability" message for "Received SEED caps request" message for now. I think this is more useful right now since it tells us if the viewer requested a seed caps at all in various scenarios (such as when teleporting to a new region). --- .../Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 185f9ce..cc69645 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -163,8 +163,8 @@ namespace OpenSim.Region.ClientStack.Linden m_HostCapsObj.RegisterHandler( "SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null)); - m_log.DebugFormat( - "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID); +// m_log.DebugFormat( +// "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID); //m_capsHandlers["MapLayer"] = // new LLSDStreamhandler("POST", @@ -254,11 +254,12 @@ namespace OpenSim.Region.ClientStack.Linden public string SeedCapRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { -// m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName); + m_log.DebugFormat( + "[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID); if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint)) { - m_log.DebugFormat( + m_log.WarnFormat( "[CAPS]: Unauthorized CAPS client {0} from {1}", m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint); -- cgit v1.1 From 0eb457442d87315810fd8280458ca8c0c3e97d23 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 16 Oct 2012 01:31:38 +0100 Subject: minor: Add missing newlines and spacing to help for "debug eq" console command --- .../ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 0dd0904..47cb049 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -111,10 +111,10 @@ namespace OpenSim.Region.ClientStack.Linden false, "debug eq", "debug eq [0|1|2]", - "Turn on event queue debugging" - + "<= 0 - turns off all event queue logging" - + ">= 1 - turns on outgoing event logging" - + ">= 2 - turns on poll notification", + "Turn on event queue debugging\n" + + " <= 0 - turns off all event queue logging\n" + + " >= 1 - turns on outgoing event logging\n" + + " >= 2 - turns on poll notification", HandleDebugEq); } else -- cgit v1.1 From db4ca57590db44aba7d19530285091c7ea4c082c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 16 Oct 2012 21:55:00 +0100 Subject: Make it possible to separate start and stop lludp packet processing from the console for debug processes. This is controlled via the "debug lludp start " and "debug lludp stop " region console commands. The command "debug lludp status" will show current status. --- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 116 ++++++++++++++++++--- .../ClientStack/Linden/UDP/OpenSimUDPBase.cs | 44 +++++--- 2 files changed, 129 insertions(+), 31 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index e3f4679..fc6dd4d 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -37,6 +37,7 @@ using log4net; using Nini.Config; using OpenMetaverse.Packets; using OpenSim.Framework; +using OpenSim.Framework.Console; using OpenSim.Framework.Monitoring; using OpenSim.Region.Framework.Scenes; using OpenMetaverse; @@ -274,16 +275,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void Start() { - if (m_scene == null) - throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference"); + StartInbound(); + StartOutbound(); + m_elapsedMSSinceLastStatReport = Environment.TickCount; + } + + private void StartInbound() + { m_log.InfoFormat( - "[LLUDPSERVER]: Starting the LLUDP server in {0} mode", + "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode", m_asyncPacketHandling ? "asynchronous" : "synchronous"); - base.Start(m_recvBufferSize, m_asyncPacketHandling); + base.StartInbound(m_recvBufferSize, m_asyncPacketHandling); - // Start the packet processing threads + // This thread will process the packets received that are placed on the packetInbox Watchdog.StartThread( IncomingPacketHandler, string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName), @@ -292,7 +298,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP true, GetWatchdogIncomingAlarmData, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); + } + private void StartOutbound() + { + m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server"); + + base.StartOutbound(); + + // This thread will process the packets received that are placed on the packetInbox Watchdog.StartThread( OutgoingPacketHandler, string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName), @@ -301,8 +315,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP true, GetWatchdogOutgoingAlarmData, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); + } - m_elapsedMSSinceLastStatReport = Environment.TickCount; + public new void Stop() + { + m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName); + base.StopOutbound(); + base.StopInbound(); } /// @@ -327,12 +346,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_currentOutgoingClient != null ? m_currentOutgoingClient.Name : "none"); } - public new void Stop() - { - m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName); - base.Stop(); - } - public void AddScene(IScene scene) { if (m_scene != null) @@ -349,6 +362,81 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_scene = (Scene)scene; m_location = new Location(m_scene.RegionInfo.RegionHandle); + + MainConsole.Instance.Commands.AddCommand( + "Debug", + false, + "debug lludp start", + "debug lludp start ", + "Control LLUDP packet processing.", + "No effect if packet processing has already started.\n" + + "in - start inbound processing.\n" + + "out - start outbound processing.\n" + + "all - start in and outbound processing.\n", + HandleStartCommand); + + MainConsole.Instance.Commands.AddCommand( + "Debug", + false, + "debug lludp stop", + "debug lludp stop ", + "Stop LLUDP packet processing.", + "No effect if packet processing has already stopped.\n" + + "in - stop inbound processing.\n" + + "out - stop outbound processing.\n" + + "all - stop in and outbound processing.\n", + HandleStopCommand); + + MainConsole.Instance.Commands.AddCommand( + "Debug", + false, + "debug lludp status", + "debug lludp status", + "Return status of LLUDP packet processing.", + HandleStatusCommand); + } + + private void HandleStartCommand(string module, string[] args) + { + if (args.Length != 4) + { + MainConsole.Instance.Output("Usage: debug lludp start "); + return; + } + + string subCommand = args[3]; + + if (subCommand == "in" || subCommand == "all") + StartInbound(); + + if (subCommand == "out" || subCommand == "all") + StartOutbound(); + } + + private void HandleStopCommand(string module, string[] args) + { + if (args.Length != 4) + { + MainConsole.Instance.Output("Usage: debug lludp stop "); + return; + } + + string subCommand = args[3]; + + if (subCommand == "in" || subCommand == "all") + StopInbound(); + + if (subCommand == "out" || subCommand == "all") + StopOutbound(); + } + + private void HandleStatusCommand(string module, string[] args) + { + MainConsole.Instance.OutputFormat( + "IN LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningInbound ? "enabled" : "disabled"); + + MainConsole.Instance.OutputFormat( + "OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled"); } public bool HandlesRegion(Location x) @@ -1174,7 +1262,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // on to en-US to avoid number parsing issues Culture.SetCurrentCulture(); - while (base.IsRunning) + while (base.IsRunningInbound) { try { @@ -1216,7 +1304,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Action generic every round Action clientPacketHandler = ClientOutgoingPacketHandler; - while (base.IsRunning) + while (base.IsRunningOutbound) { try { diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 039379d..828c23c 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs @@ -58,11 +58,12 @@ namespace OpenMetaverse /// Flag to process packets asynchronously or synchronously private bool m_asyncPacketHandling; - /// The all important shutdown flag - private volatile bool m_shutdownFlag = true; + /// Returns true if the server is currently listening for inbound packets, otherwise false + public bool IsRunningInbound { get; private set; } - /// Returns true if the server is currently listening, otherwise false - public bool IsRunning { get { return !m_shutdownFlag; } } + /// Returns true if the server is currently sending outbound packets, otherwise false + /// If IsRunningOut = false, then any request to send a packet is simply dropped. + public bool IsRunningOutbound { get; private set; } /// /// Default constructor @@ -76,7 +77,7 @@ namespace OpenMetaverse } /// - /// Start the UDP server + /// Start inbound UDP packet handling. /// /// The size of the receive buffer for /// the UDP socket. This value is passed up to the operating system @@ -91,11 +92,11 @@ namespace OpenMetaverse /// manner (not throwing an exception when the remote side resets the /// connection). This call is ignored on Mono where the flag is not /// necessary - public void Start(int recvBufferSize, bool asyncPacketHandling) + public void StartInbound(int recvBufferSize, bool asyncPacketHandling) { m_asyncPacketHandling = asyncPacketHandling; - if (m_shutdownFlag) + if (!IsRunningInbound) { const int SIO_UDP_CONNRESET = -1744830452; @@ -127,8 +128,7 @@ namespace OpenMetaverse m_udpSocket.Bind(ipep); - // we're not shutting down, we're starting up - m_shutdownFlag = false; + IsRunningInbound = true; // kick off an async receive. The Start() method will return, the // actual receives will occur asynchronously and will be caught in @@ -138,28 +138,38 @@ namespace OpenMetaverse } /// - /// Stops the UDP server + /// Start outbound UDP packet handling. /// - public void Stop() + public void StartOutbound() { - if (!m_shutdownFlag) + IsRunningOutbound = true; + } + + public void StopInbound() + { + if (IsRunningInbound) { // wait indefinitely for a writer lock. Once this is called, the .NET runtime // will deny any more reader locks, in effect blocking all other send/receive - // threads. Once we have the lock, we set shutdownFlag to inform the other + // threads. Once we have the lock, we set IsRunningInbound = false to inform the other // threads that the socket is closed. - m_shutdownFlag = true; + IsRunningInbound = false; m_udpSocket.Close(); } } + public void StopOutbound() + { + IsRunningOutbound = false; + } + private void AsyncBeginReceive() { // allocate a packet buffer //WrappedObject wrappedBuffer = Pool.CheckOut(); UDPPacketBuffer buf = new UDPPacketBuffer(); - if (!m_shutdownFlag) + if (IsRunningInbound) { try { @@ -212,7 +222,7 @@ namespace OpenMetaverse { // Asynchronous receive operations will complete here through the call // to AsyncBeginReceive - if (!m_shutdownFlag) + if (IsRunningInbound) { // Asynchronous mode will start another receive before the // callback for this packet is even fired. Very parallel :-) @@ -252,7 +262,7 @@ namespace OpenMetaverse public void AsyncBeginSend(UDPPacketBuffer buf) { - if (!m_shutdownFlag) + if (IsRunningOutbound) { try { -- cgit v1.1 From fc861c7904840b2b0b9de0621e9b5d976c8071b1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 16 Oct 2012 23:35:05 +0100 Subject: Add optional pool for the UDPPacketBuffer objects that handle all incoming UDP data. Even when an avatar is standing still, it's sending in a constant stream of AgentUpdate packets that the client creates new UDPPacketBuffer objects to handle. This option pools those objects. This reduces memory churn. Currently off by default. Works but the scope can be expanded. --- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 42 ++++++++++++---------- .../ClientStack/Linden/UDP/OpenSimUDPBase.cs | 31 ++++++++++++---- 2 files changed, 49 insertions(+), 24 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index fc6dd4d..42247ca 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -188,7 +188,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// private IClientAPI m_currentIncomingClient; - public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) + public LLUDPServer( + IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, + IConfigSource configSource, AgentCircuitManager circuitManager) : base(listenIP, (int)port) { #region Environment.TickCount Measurement @@ -242,6 +244,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true); PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true); + UsePools = packetConfig.GetBoolean("RecycleBaseUDPPackets", false); } #region BinaryStats @@ -284,8 +287,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP private void StartInbound() { m_log.InfoFormat( - "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode", - m_asyncPacketHandling ? "asynchronous" : "synchronous"); + "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode with UsePools = {1}", + m_asyncPacketHandling ? "asynchronous" : "synchronous", UsePools); base.StartInbound(m_recvBufferSize, m_asyncPacketHandling); @@ -300,7 +303,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); } - private void StartOutbound() + private new void StartOutbound() { m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server"); @@ -317,7 +320,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); } - public new void Stop() + public void Stop() { m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName); base.StopOutbound(); @@ -806,7 +809,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP LLUDPClient udpClient = null; Packet packet = null; int packetEnd = buffer.DataLength - 1; - IPEndPoint address = (IPEndPoint)buffer.RemoteEndPoint; + IPEndPoint endPoint = (IPEndPoint)buffer.RemoteEndPoint; #region Decoding @@ -816,7 +819,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}", // buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); - return; // Drop undersizd packet + return; // Drop undersized packet } int headerLen = 7; @@ -842,6 +845,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP // packet = Packet.BuildPacket(buffer.Data, ref packetEnd, // // Only allocate a buffer for zerodecoding if the packet is zerocoded // ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); + // If OpenSimUDPBase.UsePool == true (which is currently separate from the PacketPool) then we + // assume that packet construction does not retain a reference to byte[] buffer.Data (instead, all + // bytes are copied out). packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd, // Only allocate a buffer for zerodecoding if the packet is zerocoded ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); @@ -884,7 +890,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP // UseCircuitCode handling if (packet.Type == PacketType.UseCircuitCode) { - object[] array = new object[] { buffer, packet }; + // We need to copy the endpoint so that it doesn't get changed when another thread reuses the + // buffer. + object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; Util.FireAndForget(HandleUseCircuitCode, array); @@ -893,7 +901,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Determine which agent this packet came from IClientAPI client; - if (!m_scene.TryGetClient(address, out client) || !(client is LLClientView)) + if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView)) { //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); return; @@ -1091,21 +1099,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP private void HandleUseCircuitCode(object o) { - IPEndPoint remoteEndPoint = null; + IPEndPoint endPoint = null; IClientAPI client = null; try { // DateTime startTime = DateTime.Now; object[] array = (object[])o; - UDPPacketBuffer buffer = (UDPPacketBuffer)array[0]; + endPoint = (IPEndPoint)array[0]; UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1]; m_log.DebugFormat( "[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} to {1} from IP {2}", - uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, buffer.RemoteEndPoint); - - remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint; + uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, endPoint); AuthenticateResponse sessionInfo; if (IsClientAuthorized(uccp, out sessionInfo)) @@ -1116,13 +1122,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP uccp.CircuitCode.Code, uccp.CircuitCode.ID, uccp.CircuitCode.SessionID, - remoteEndPoint, + endPoint, sessionInfo); // Send ack straight away to let the viewer know that the connection is active. // The client will be null if it already exists (e.g. if on a region crossing the client sends a use // circuit code to the existing child agent. This is not particularly obvious. - SendAckImmediate(remoteEndPoint, uccp.Header.Sequence); + SendAckImmediate(endPoint, uccp.Header.Sequence); // We only want to send initial data to new clients, not ones which are being converted from child to root. if (client != null) @@ -1133,7 +1139,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Don't create clients for unauthorized requesters. m_log.WarnFormat( "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", - uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint); + uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); } // m_log.DebugFormat( @@ -1145,7 +1151,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { m_log.ErrorFormat( "[LLUDPSERVER]: UseCircuitCode handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}", - remoteEndPoint != null ? remoteEndPoint.ToString() : "n/a", + endPoint != null ? endPoint.ToString() : "n/a", client != null ? client.Name : "unknown", client != null ? client.AgentId.ToString() : "unknown", e.Message, diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 828c23c..6e6b3ef 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs @@ -30,6 +30,7 @@ using System.Net; using System.Net.Sockets; using System.Threading; using log4net; +using OpenSim.Framework; namespace OpenMetaverse { @@ -58,6 +59,16 @@ namespace OpenMetaverse /// Flag to process packets asynchronously or synchronously private bool m_asyncPacketHandling; + /// + /// Pool to use for handling data. May be null if UsePools = false; + /// + protected OpenSim.Framework.Pool m_pool; + + /// + /// Are we to use object pool(s) to reduce memory churn when receiving data? + /// + public bool UsePools { get; protected set; } + /// Returns true if the server is currently listening for inbound packets, otherwise false public bool IsRunningInbound { get; private set; } @@ -70,6 +81,7 @@ namespace OpenMetaverse /// /// Local IP address to bind the server to /// Port to listening for incoming UDP packets on + /// /// Are we to use an object pool to get objects for handing inbound data? public OpenSimUDPBase(IPAddress bindAddress, int port) { m_localBindAddress = bindAddress; @@ -94,6 +106,11 @@ namespace OpenMetaverse /// necessary public void StartInbound(int recvBufferSize, bool asyncPacketHandling) { + if (UsePools) + m_pool = new Pool(() => new UDPPacketBuffer(), 500); + else + m_pool = null; + m_asyncPacketHandling = asyncPacketHandling; if (!IsRunningInbound) @@ -165,9 +182,12 @@ namespace OpenMetaverse private void AsyncBeginReceive() { - // allocate a packet buffer - //WrappedObject wrappedBuffer = Pool.CheckOut(); - UDPPacketBuffer buf = new UDPPacketBuffer(); + UDPPacketBuffer buf; + + if (UsePools) + buf = m_pool.GetObject(); + else + buf = new UDPPacketBuffer(); if (IsRunningInbound) { @@ -231,8 +251,6 @@ namespace OpenMetaverse // get the buffer that was created in AsyncBeginReceive // this is the received data - //WrappedObject wrappedBuffer = (WrappedObject)iar.AsyncState; - //UDPPacketBuffer buffer = wrappedBuffer.Instance; UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState; try @@ -249,7 +267,8 @@ namespace OpenMetaverse catch (ObjectDisposedException) { } finally { - //wrappedBuffer.Dispose(); + if (UsePools) + m_pool.ReturnObject(buffer); // Synchronous mode waits until the packet callback completes // before starting the receive to fetch another packet -- cgit v1.1 From f35826eb31e2f286e3ae5bdbcf8c3beb4723d5d9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 16 Oct 2012 23:50:45 +0100 Subject: minor: Make BasicCircuitTests.SetUp() call overriden base method instead of ignoring it. --- OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs index fa9378c..556df30 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs @@ -65,8 +65,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests } [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); m_scene = new SceneHelpers().SetupScene(); } -- cgit v1.1 From 2ed59ad8ac3ec836517b60580f13ab37102a0c67 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 17 Oct 2012 21:08:15 +0100 Subject: If RecycleBaseUDPPackets = true, also pool IncomingPackets to reduce memory churn --- .../ClientStack/Linden/UDP/IncomingPacket.cs | 7 +++++- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 25 +++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs index 1b8535c..e22670b 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs @@ -45,7 +45,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP public Packet Packet; /// - /// Default constructor + /// No arg constructor. + /// + public IncomingPacket() {} + + /// + /// Constructor /// /// Reference to the client this packet came from /// Packet data diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 42247ca..286d931 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -168,6 +168,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Flag to signal when clients should send pings protected bool m_sendPing; + private Pool m_incomingPacketPool; + private int m_defaultRTO = 0; private int m_maxRTO = 0; private int m_ackTimeout = 0; @@ -274,6 +276,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_throttle = new TokenBucket(null, sceneThrottleBps); ThrottleRates = new ThrottleRates(configSource); + + if (UsePools) + m_incomingPacketPool = new Pool(() => new IncomingPacket(), 500); } public void Start() @@ -1012,8 +1017,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion Ping Check Handling + IncomingPacket incomingPacket; + // Inbox insertion - packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet)); + if (UsePools) + { + incomingPacket = m_incomingPacketPool.GetObject(); + incomingPacket.Client = (LLClientView)client; + incomingPacket.Packet = packet; + } + else + { + incomingPacket = new IncomingPacket((LLClientView)client, packet); + } + + packetInbox.Enqueue(incomingPacket); } #region BinaryStats @@ -1283,7 +1301,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP } if (packetInbox.Dequeue(100, ref incomingPacket)) + { ProcessInPacket(incomingPacket);//, incomingPacket); Util.FireAndForget(ProcessInPacket, incomingPacket); + + if (UsePools) + m_incomingPacketPool.ReturnObject(incomingPacket); + } } catch (Exception ex) { -- cgit v1.1 From faf6b568393d8edfed103e0a656c98322c195e95 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 17 Oct 2012 23:08:14 +0100 Subject: Explicitly return only the incoming AgentUpdate packet as this is the only one we pool atm, rather than attempting to return all incoming packets. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 11 +++++++---- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 17 +++++++++++++++-- OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | 10 ++++++++-- 3 files changed, 30 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 0d4f09d..1e93b84 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -5425,16 +5425,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region Scene/Avatar - private bool HandleAgentUpdate(IClientAPI sener, Packet Pack) + private bool HandleAgentUpdate(IClientAPI sener, Packet packet) { if (OnAgentUpdate != null) { bool update = false; - AgentUpdatePacket agenUpdate = (AgentUpdatePacket)Pack; + AgentUpdatePacket agenUpdate = (AgentUpdatePacket)packet; #region Packet Session and User Check if (agenUpdate.AgentData.SessionID != SessionId || agenUpdate.AgentData.AgentID != AgentId) + { + PacketPool.Instance.ReturnPacket(packet); return false; + } #endregion AgentUpdatePacket.AgentDataBlock x = agenUpdate.AgentData; @@ -5499,6 +5502,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } + PacketPool.Instance.ReturnPacket(packet); + return true; } @@ -11851,8 +11856,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (!ProcessPacketMethod(packet)) m_log.Warn("[CLIENT]: unhandled packet " + packet.Type); - - PacketPool.Instance.ReturnPacket(packet); } private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 286d931..419de66 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -314,7 +314,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP base.StartOutbound(); - // This thread will process the packets received that are placed on the packetInbox Watchdog.StartThread( OutgoingPacketHandler, string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName), @@ -930,6 +929,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Handle appended ACKs if (packet.Header.AppendedAcks && packet.Header.AckList != null) { +// m_log.DebugFormat( +// "[LLUDPSERVER]: Handling {0} appended acks from {1} in {2}", +// packet.Header.AckList.Length, client.Name, m_scene.Name); + for (int i = 0; i < packet.Header.AckList.Length; i++) udpClient.NeedAcks.Acknowledge(packet.Header.AckList[i], now, packet.Header.Resent); } @@ -939,6 +942,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP { PacketAckPacket ackPacket = (PacketAckPacket)packet; +// m_log.DebugFormat( +// "[LLUDPSERVER]: Handling {0} packet acks for {1} in {2}", +// ackPacket.Packets.Length, client.Name, m_scene.Name); + for (int i = 0; i < ackPacket.Packets.Length; i++) udpClient.NeedAcks.Acknowledge(ackPacket.Packets[i].ID, now, packet.Header.Resent); @@ -952,6 +959,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (packet.Header.Reliable) { +// m_log.DebugFormat( +// "[LLUDPSERVER]: Adding ack request for {0} {1} from {2} in {3}", +// packet.Type, packet.Header.Sequence, client.Name, m_scene.Name); + udpClient.PendingAcks.Enqueue(packet.Header.Sequence); // This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out, @@ -998,6 +1009,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (packet.Type == PacketType.StartPingCheck) { +// m_log.DebugFormat("[LLUDPSERVER]: Handling ping from {0} in {1}", client.Name, m_scene.Name); + // We don't need to do anything else with ping checks StartPingCheckPacket startPing = (StartPingCheckPacket)packet; CompletePing(udpClient, startPing.PingID.PingID); @@ -1286,7 +1299,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // on to en-US to avoid number parsing issues Culture.SetCurrentCulture(); - while (base.IsRunningInbound) + while (IsRunningInbound) { try { diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs index 71f6fe1..2a3d14f 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs @@ -108,15 +108,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (!pool.ContainsKey(type) || pool[type] == null || (pool[type]).Count == 0) { +// m_log.DebugFormat("[PACKETPOOL]: Building {0} packet", type); + // Creating a new packet if we cannot reuse an old package packet = Packet.BuildPacket(type); } else { +// m_log.DebugFormat("[PACKETPOOL]: Pulling {0} packet", type); + // Recycle old packages m_packetsReusedStat.Antecedent++; - packet = (pool[type]).Pop(); + packet = pool[type].Pop(); } } @@ -227,7 +231,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP if ((pool[type]).Count < 50) { - (pool[type]).Push(packet); +// m_log.DebugFormat("[PACKETPOOL]: Pushing {0} packet", type); + + pool[type].Push(packet); } } break; -- cgit v1.1 From 3ec2923022dbc3e0b5411b17c6495dab6d641f0b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 17 Oct 2012 23:54:05 +0100 Subject: Reuse the same AgentUpdateArgs object for each AgentUpdate UDP packet (of which there are 10 a second) rather than constructing a new one every time. We can do this because AgentUpdate packets are handled synchronously. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 109 +++++++++++++-------- 1 file changed, 68 insertions(+), 41 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 1e93b84..65daca0 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -92,8 +92,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event ObjectDeselect OnObjectDetach; public event ObjectDrop OnObjectDrop; public event Action OnCompleteMovementToRegion; + + /// + /// Called when an AgentUpdate message is received and before OnAgentUpdate. + /// + /// + /// Listeners must not retain a reference to AgentUpdateArgs since this object is reused for subsequent AgentUpdates. + /// public event UpdateAgent OnPreAgentUpdate; + + /// + /// Called when an AgentUpdate message is received and after OnPreAgentUpdate. + /// + /// + /// Listeners must not retain a reference to AgentUpdateArgs since this object is reused for subsequent AgentUpdates. + /// public event UpdateAgent OnAgentUpdate; + public event AgentRequestSit OnAgentRequestSit; public event AgentSit OnAgentSit; public event AvatarPickerRequest OnAvatarPickerRequest; @@ -347,7 +362,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_moneyBalance; private int m_animationSequenceNumber = 1; private bool m_SendLogoutPacketWhenClosing = true; - private AgentUpdateArgs lastarg; + + /// + /// We retain a single AgentUpdateArgs so that we can constantly reuse it rather than construct a new one for + /// every single incoming AgentUpdate. Every client sends 10 AgentUpdate UDP messages per second, even if it + /// is doing absolutely nothing. + /// + /// + /// This does mean that agent updates must be processed synchronously, at least for each client, and called methods + /// cannot retain a reference to it outside of that method. + /// + private AgentUpdateArgs m_lastAgentUpdateArgs; protected Dictionary m_packetHandlers = new Dictionary(); protected Dictionary m_genericPacketHandlers = new Dictionary(); //PauPaw:Local Generic Message handlers @@ -5198,7 +5223,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected virtual void RegisterLocalPacketHandlers() { AddLocalPacketHandler(PacketType.LogoutRequest, HandleLogout); + + // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs + // for each AgentUpdate packet. AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); + AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); @@ -5429,73 +5458,71 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (OnAgentUpdate != null) { - bool update = false; - AgentUpdatePacket agenUpdate = (AgentUpdatePacket)packet; + AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet; #region Packet Session and User Check - if (agenUpdate.AgentData.SessionID != SessionId || agenUpdate.AgentData.AgentID != AgentId) + if (agentUpdate.AgentData.SessionID != SessionId || agentUpdate.AgentData.AgentID != AgentId) { PacketPool.Instance.ReturnPacket(packet); return false; } #endregion - AgentUpdatePacket.AgentDataBlock x = agenUpdate.AgentData; - - // We can only check when we have something to check - // against. + bool update = false; + AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData; - if (lastarg != null) + if (m_lastAgentUpdateArgs != null) { + // These should be ordered from most-likely to + // least likely to change. I've made an initial + // guess at that. update = ( - (x.BodyRotation != lastarg.BodyRotation) || - (x.CameraAtAxis != lastarg.CameraAtAxis) || - (x.CameraCenter != lastarg.CameraCenter) || - (x.CameraLeftAxis != lastarg.CameraLeftAxis) || - (x.CameraUpAxis != lastarg.CameraUpAxis) || - (x.ControlFlags != lastarg.ControlFlags) || - (x.Far != lastarg.Far) || - (x.Flags != lastarg.Flags) || - (x.State != lastarg.State) || - (x.HeadRotation != lastarg.HeadRotation) || - (x.SessionID != lastarg.SessionID) || - (x.AgentID != lastarg.AgentID) + (x.BodyRotation != m_lastAgentUpdateArgs.BodyRotation) || + (x.CameraAtAxis != m_lastAgentUpdateArgs.CameraAtAxis) || + (x.CameraCenter != m_lastAgentUpdateArgs.CameraCenter) || + (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) || + (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) || + (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) || + (x.Far != m_lastAgentUpdateArgs.Far) || + (x.Flags != m_lastAgentUpdateArgs.Flags) || + (x.State != m_lastAgentUpdateArgs.State) || + (x.HeadRotation != m_lastAgentUpdateArgs.HeadRotation) || + (x.SessionID != m_lastAgentUpdateArgs.SessionID) || + (x.AgentID != m_lastAgentUpdateArgs.AgentID) ); } else { + m_lastAgentUpdateArgs = new AgentUpdateArgs(); update = true; } - // These should be ordered from most-likely to - // least likely to change. I've made an initial - // guess at that. - if (update) { // m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name); - AgentUpdateArgs arg = new AgentUpdateArgs(); - arg.AgentID = x.AgentID; - arg.BodyRotation = x.BodyRotation; - arg.CameraAtAxis = x.CameraAtAxis; - arg.CameraCenter = x.CameraCenter; - arg.CameraLeftAxis = x.CameraLeftAxis; - arg.CameraUpAxis = x.CameraUpAxis; - arg.ControlFlags = x.ControlFlags; - arg.Far = x.Far; - arg.Flags = x.Flags; - arg.HeadRotation = x.HeadRotation; - arg.SessionID = x.SessionID; - arg.State = x.State; + m_lastAgentUpdateArgs.AgentID = x.AgentID; + m_lastAgentUpdateArgs.BodyRotation = x.BodyRotation; + m_lastAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis; + m_lastAgentUpdateArgs.CameraCenter = x.CameraCenter; + m_lastAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis; + m_lastAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis; + m_lastAgentUpdateArgs.ControlFlags = x.ControlFlags; + m_lastAgentUpdateArgs.Far = x.Far; + m_lastAgentUpdateArgs.Flags = x.Flags; + m_lastAgentUpdateArgs.HeadRotation = x.HeadRotation; + m_lastAgentUpdateArgs.SessionID = x.SessionID; + m_lastAgentUpdateArgs.State = x.State; + UpdateAgent handlerAgentUpdate = OnAgentUpdate; UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate; - lastarg = arg; // save this set of arguments for nexttime + if (handlerPreAgentUpdate != null) - OnPreAgentUpdate(this, arg); + OnPreAgentUpdate(this, m_lastAgentUpdateArgs); + if (handlerAgentUpdate != null) - OnAgentUpdate(this, arg); + OnAgentUpdate(this, m_lastAgentUpdateArgs); handlerAgentUpdate = null; handlerPreAgentUpdate = null; -- cgit v1.1 From 0811f3d28d70432e4657df735b5337726eb2f53f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 18 Oct 2012 00:34:10 +0100 Subject: minor: Remove event method doc from LLClientView that I forgot in the last commit (1de80c) --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 65daca0..7427c59 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -92,23 +92,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event ObjectDeselect OnObjectDetach; public event ObjectDrop OnObjectDrop; public event Action OnCompleteMovementToRegion; - - /// - /// Called when an AgentUpdate message is received and before OnAgentUpdate. - /// - /// - /// Listeners must not retain a reference to AgentUpdateArgs since this object is reused for subsequent AgentUpdates. - /// public event UpdateAgent OnPreAgentUpdate; - - /// - /// Called when an AgentUpdate message is received and after OnPreAgentUpdate. - /// - /// - /// Listeners must not retain a reference to AgentUpdateArgs since this object is reused for subsequent AgentUpdates. - /// public event UpdateAgent OnAgentUpdate; - public event AgentRequestSit OnAgentRequestSit; public event AgentSit OnAgentSit; public event AvatarPickerRequest OnAvatarPickerRequest; -- cgit v1.1