From c0ab406e2e3ab1e1702285c7cd35e1adc6cc593b Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 19 Jul 2012 21:41:13 +0100 Subject: [PATCH 1/8] Add basic TestCreateRootScenePresence() regression test --- .../Scenes/Tests/ScenePresenceAgentTests.cs | 271 +++++++++--------- 1 file changed, 140 insertions(+), 131 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index 02c45ef11c..44c1396b30 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs @@ -53,48 +53,60 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// Scene presence tests /// [TestFixture] - public class ScenePresenceAgentTests + public class ScenePresenceAgentTests : OpenSimTestCase { - public Scene scene, scene2, scene3; - public UUID agent1, agent2, agent3; - public static Random random; - public ulong region1,region2,region3; - public AgentCircuitData acd1; - public SceneObjectGroup sog1, sog2, sog3; - public TestClient testclient; +// public Scene scene, scene2, scene3; +// public UUID agent1, agent2, agent3; +// public static Random random; +// public ulong region1, region2, region3; +// public AgentCircuitData acd1; +// public TestClient testclient; - [TestFixtureSetUp] - public void Init() +// [TestFixtureSetUp] +// public void Init() +// { +//// TestHelpers.InMethod(); +//// +//// SceneHelpers sh = new SceneHelpers(); +//// +//// scene = sh.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); +//// scene2 = sh.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); +//// scene3 = sh.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000); +//// +//// ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); +//// interregionComms.Initialise(new IniConfigSource()); +//// interregionComms.PostInitialise(); +//// SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms); +//// SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms); +//// SceneHelpers.SetupSceneModules(scene3, new IniConfigSource(), interregionComms); +// +//// agent1 = UUID.Random(); +//// agent2 = UUID.Random(); +//// agent3 = UUID.Random(); +// +//// region1 = scene.RegionInfo.RegionHandle; +//// region2 = scene2.RegionInfo.RegionHandle; +//// region3 = scene3.RegionInfo.RegionHandle; +// } + + [Test] + public void TestCreateRootScenePresence() { TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); - SceneHelpers sh = new SceneHelpers(); + UUID spUuid = TestHelpers.ParseTail(0x1); - scene = sh.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); - scene2 = sh.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); - scene3 = sh.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000); + TestScene scene = new SceneHelpers().SetupScene(); + SceneHelpers.AddScenePresence(scene, spUuid); - ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); - interregionComms.Initialise(new IniConfigSource()); - interregionComms.PostInitialise(); - SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms); - SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms); - SceneHelpers.SetupSceneModules(scene3, new IniConfigSource(), interregionComms); + Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(spUuid), Is.Not.Null); + Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(1)); - agent1 = UUID.Random(); - agent2 = UUID.Random(); - agent3 = UUID.Random(); - random = new Random(); - sog1 = SceneHelpers.CreateSceneObject(1, agent1); - scene.AddSceneObject(sog1); - sog2 = SceneHelpers.CreateSceneObject(1, agent1); - scene.AddSceneObject(sog2); - sog3 = SceneHelpers.CreateSceneObject(1, agent1); - scene.AddSceneObject(sog3); - - region1 = scene.RegionInfo.RegionHandle; - region2 = scene2.RegionInfo.RegionHandle; - region3 = scene3.RegionInfo.RegionHandle; + ScenePresence sp = scene.GetScenePresence(spUuid); + Assert.That(sp, Is.Not.Null); + Assert.That(sp.IsChildAgent, Is.False); + Assert.That(sp.UUID, Is.EqualTo(spUuid)); } [Test] @@ -106,9 +118,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestScene scene = new SceneHelpers().SetupScene(); ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); - Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Not.Null); - Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(1)); - scene.IncomingCloseAgent(sp.UUID); Assert.That(scene.GetScenePresence(sp.UUID), Is.Null); @@ -266,99 +275,99 @@ namespace OpenSim.Region.Framework.Scenes.Tests // but things are synchronous among them. So there should be // 3 threads in here. //[Test] - public void T021_TestCrossToNewRegion() - { - TestHelpers.InMethod(); - - scene.RegisterRegionWithGrid(); - scene2.RegisterRegionWithGrid(); - - // Adding child agent to region 1001 - string reason; - scene2.NewUserConnection(acd1,0, out reason); - scene2.AddNewClient(testclient, PresenceType.User); - - ScenePresence presence = scene.GetScenePresence(agent1); - presence.MakeRootAgent(new Vector3(0,unchecked(Constants.RegionSize-1),0), true); - - ScenePresence presence2 = scene2.GetScenePresence(agent1); - - // Adding neighbour region caps info to presence2 - - string cap = presence.ControllingClient.RequestClientInfo().CapsPath; - presence2.AddNeighbourRegion(region1, cap); - - Assert.That(presence.IsChildAgent, Is.False, "Did not start root in origin region."); - Assert.That(presence2.IsChildAgent, Is.True, "Is not a child on destination region."); - - // Cross to x+1 - presence.AbsolutePosition = new Vector3(Constants.RegionSize+1,3,100); - presence.Update(); - - EventWaitHandle wh = new EventWaitHandle (false, EventResetMode.AutoReset, "Crossing"); - - // Mimicking communication between client and server, by waiting OK from client - // sent by TestClient.CrossRegion call. Originally, this is network comm. - if (!wh.WaitOne(5000,false)) - { - presence.Update(); - if (!wh.WaitOne(8000,false)) - throw new ArgumentException("1 - Timeout waiting for signal/variable."); - } - - // This is a TestClient specific method that fires OnCompleteMovementToRegion event, which - // would normally be fired after receiving the reply packet from comm. done on the last line. - testclient.CompleteMovement(); - - // Crossings are asynchronous - int timer = 10; - - // Make sure cross hasn't already finished - if (!presence.IsInTransit && !presence.IsChildAgent) - { - // If not and not in transit yet, give it some more time - Thread.Sleep(5000); - } - - // Enough time, should at least be in transit by now. - while (presence.IsInTransit && timer > 0) - { - Thread.Sleep(1000); - timer-=1; - } - - Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 2->1."); - Assert.That(presence.IsChildAgent, Is.True, "Did not complete region cross as expected."); - Assert.That(presence2.IsChildAgent, Is.False, "Did not receive root status after receiving agent."); - - // Cross Back - presence2.AbsolutePosition = new Vector3(-10, 3, 100); - presence2.Update(); - - if (!wh.WaitOne(5000,false)) - { - presence2.Update(); - if (!wh.WaitOne(8000,false)) - throw new ArgumentException("2 - Timeout waiting for signal/variable."); - } - testclient.CompleteMovement(); - - if (!presence2.IsInTransit && !presence2.IsChildAgent) - { - // If not and not in transit yet, give it some more time - Thread.Sleep(5000); - } - - // Enough time, should at least be in transit by now. - while (presence2.IsInTransit && timer > 0) - { - Thread.Sleep(1000); - timer-=1; - } - - Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 1->2."); - Assert.That(presence2.IsChildAgent, Is.True, "Did not return from region as expected."); - Assert.That(presence.IsChildAgent, Is.False, "Presence was not made root in old region again."); - } +// public void T021_TestCrossToNewRegion() +// { +// TestHelpers.InMethod(); +// +// scene.RegisterRegionWithGrid(); +// scene2.RegisterRegionWithGrid(); +// +// // Adding child agent to region 1001 +// string reason; +// scene2.NewUserConnection(acd1,0, out reason); +// scene2.AddNewClient(testclient, PresenceType.User); +// +// ScenePresence presence = scene.GetScenePresence(agent1); +// presence.MakeRootAgent(new Vector3(0,unchecked(Constants.RegionSize-1),0), true); +// +// ScenePresence presence2 = scene2.GetScenePresence(agent1); +// +// // Adding neighbour region caps info to presence2 +// +// string cap = presence.ControllingClient.RequestClientInfo().CapsPath; +// presence2.AddNeighbourRegion(region1, cap); +// +// Assert.That(presence.IsChildAgent, Is.False, "Did not start root in origin region."); +// Assert.That(presence2.IsChildAgent, Is.True, "Is not a child on destination region."); +// +// // Cross to x+1 +// presence.AbsolutePosition = new Vector3(Constants.RegionSize+1,3,100); +// presence.Update(); +// +// EventWaitHandle wh = new EventWaitHandle (false, EventResetMode.AutoReset, "Crossing"); +// +// // Mimicking communication between client and server, by waiting OK from client +// // sent by TestClient.CrossRegion call. Originally, this is network comm. +// if (!wh.WaitOne(5000,false)) +// { +// presence.Update(); +// if (!wh.WaitOne(8000,false)) +// throw new ArgumentException("1 - Timeout waiting for signal/variable."); +// } +// +// // This is a TestClient specific method that fires OnCompleteMovementToRegion event, which +// // would normally be fired after receiving the reply packet from comm. done on the last line. +// testclient.CompleteMovement(); +// +// // Crossings are asynchronous +// int timer = 10; +// +// // Make sure cross hasn't already finished +// if (!presence.IsInTransit && !presence.IsChildAgent) +// { +// // If not and not in transit yet, give it some more time +// Thread.Sleep(5000); +// } +// +// // Enough time, should at least be in transit by now. +// while (presence.IsInTransit && timer > 0) +// { +// Thread.Sleep(1000); +// timer-=1; +// } +// +// Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 2->1."); +// Assert.That(presence.IsChildAgent, Is.True, "Did not complete region cross as expected."); +// Assert.That(presence2.IsChildAgent, Is.False, "Did not receive root status after receiving agent."); +// +// // Cross Back +// presence2.AbsolutePosition = new Vector3(-10, 3, 100); +// presence2.Update(); +// +// if (!wh.WaitOne(5000,false)) +// { +// presence2.Update(); +// if (!wh.WaitOne(8000,false)) +// throw new ArgumentException("2 - Timeout waiting for signal/variable."); +// } +// testclient.CompleteMovement(); +// +// if (!presence2.IsInTransit && !presence2.IsChildAgent) +// { +// // If not and not in transit yet, give it some more time +// Thread.Sleep(5000); +// } +// +// // Enough time, should at least be in transit by now. +// while (presence2.IsInTransit && timer > 0) +// { +// Thread.Sleep(1000); +// timer-=1; +// } +// +// Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 1->2."); +// Assert.That(presence2.IsChildAgent, Is.True, "Did not return from region as expected."); +// Assert.That(presence.IsChildAgent, Is.False, "Presence was not made root in old region again."); +// } } } \ No newline at end of file From e9a121e1b203e8880bcaf85d35612fc6706b281a Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 19 Jul 2012 21:54:50 +0100 Subject: [PATCH 2/8] Add TestCreateDuplicateRootScenePresence() regression test. --- OpenSim/Region/Framework/Scenes/Scene.cs | 17 ++++++++++++++ OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 +- .../Scenes/Tests/ScenePresenceAgentTests.cs | 23 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 6d8ee7b9ef..36452dec09 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -4469,6 +4469,23 @@ namespace OpenSim.Region.Framework.Scenes return m_sceneGraph.GetScenePresence(localID); } + /// + /// Gets all the scene presences in this scene. + /// + /// + /// This method will return both root and child scene presences. + /// + /// Consider using ForEachScenePresence() or ForEachRootScenePresence() if possible since these will not + /// involving creating a new List object. + /// + /// + /// A list of the scene presences. Adding or removing from the list will not affect the presences in the scene. + /// + public List GetScenePresences() + { + return new List(m_sceneGraph.GetScenePresences()); + } + /// /// Performs action on all avatars in the scene (root scene presences) /// Avatars may be an NPC or a 'real' client. diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 2be5364a93..ba68dface9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -768,7 +768,7 @@ namespace OpenSim.Region.Framework.Scenes /// pass a delegate to ForEachScenePresence. /// /// - private List GetScenePresences() + protected internal List GetScenePresences() { return m_scenePresenceArray; } diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index 44c1396b30..5758869e7a 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs @@ -107,6 +107,29 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(sp, Is.Not.Null); Assert.That(sp.IsChildAgent, Is.False); Assert.That(sp.UUID, Is.EqualTo(spUuid)); + + Assert.That(scene.GetScenePresences().Count, Is.EqualTo(1)); + } + + [Test] + public void TestCreateDuplicateRootScenePresence() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID spUuid = TestHelpers.ParseTail(0x1); + + TestScene scene = new SceneHelpers().SetupScene(); + SceneHelpers.AddScenePresence(scene, spUuid); + SceneHelpers.AddScenePresence(scene, spUuid); + + Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(spUuid), Is.Not.Null); + Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(1)); + + ScenePresence sp = scene.GetScenePresence(spUuid); + Assert.That(sp, Is.Not.Null); + Assert.That(sp.IsChildAgent, Is.False); + Assert.That(sp.UUID, Is.EqualTo(spUuid)); } [Test] From ba80f137b58cfacf46fadb3ec8b63af6896c5b43 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 19 Jul 2012 22:32:27 +0100 Subject: [PATCH 3/8] Prevent race conditions between two threads that call LLClientView.Close() simultaneously (e.g. ack timeout and an attempt to reconnect) --- .../ClientStack/Linden/UDP/LLClientView.cs | 58 ++++++++++++++----- .../ClientStack/Linden/UDP/LLUDPServer.cs | 29 +++++----- OpenSim/Region/Framework/Scenes/Scene.cs | 6 +- 3 files changed, 60 insertions(+), 33 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 73cdec30fb..ae5207ba1d 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -347,8 +347,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_animationSequenceNumber = 1; private bool m_SendLogoutPacketWhenClosing = true; private AgentUpdateArgs lastarg; - private bool m_IsActive = true; - private bool m_IsLoggingOut = false; protected Dictionary m_packetHandlers = new Dictionary(); protected Dictionary m_genericPacketHandlers = new Dictionary(); //PauPaw:Local Generic Message handlers @@ -412,16 +410,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP public uint CircuitCode { get { return m_circuitCode; } } public int MoneyBalance { get { return m_moneyBalance; } } public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } } - public bool IsActive - { - get { return m_IsActive; } - set { m_IsActive = value; } - } - public bool IsLoggingOut - { - get { return m_IsLoggingOut; } - set { m_IsLoggingOut = value; } - } + + /// + /// As well as it's function in IClientAPI, in LLClientView we are locking on this property in order to + /// prevent race conditions by different threads calling Close(). + /// + public bool IsActive { get; set; } + + /// + /// Used to synchronise threads when client is being closed. + /// + public Object CloseSyncLock { get; private set; } + + public bool IsLoggingOut { get; set; } public bool DisableFacelights { @@ -446,6 +447,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP { // DebugPacketLevel = 1; + CloseSyncLock = new Object(); + RegisterInterface(this); RegisterInterface(this); RegisterInterface(this); @@ -478,17 +481,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_prioritizer = new Prioritizer(m_scene); RegisterLocalPacketHandlers(); + + IsActive = true; } #region Client Methods /// - /// Shut down the client view + /// Close down the client view /// public void Close() { - IsActive = false; + // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. + // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. + lock (CloseSyncLock) + { + if (!IsActive) + return; + IsActive = false; + CloseWithoutChecks(); + } + } + + /// + /// Closes down the client view without first checking whether it is active. + /// + /// + /// This exists because LLUDPServer has to set IsActive = false in earlier synchronous code before calling + /// CloseWithoutIsActiveCheck asynchronously. + /// + /// Callers must lock ClosingSyncLock before calling. + /// + public void CloseWithoutChecks() + { m_log.DebugFormat( "[CLIENT]: Close has been called for {0} attached to scene {1}", Name, m_scene.RegionInfo.RegionName); @@ -3567,7 +3593,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendCoarseLocationUpdate(List users, List CoarseLocations) { - if (!IsActive) return; // We don't need to update inactive clients. + // We don't need to update inactive clients. + if (!IsActive) + return; CoarseLocationUpdatePacket loc = (CoarseLocationUpdatePacket)PacketPool.Instance.GetPacket(PacketType.CoarseLocationUpdate); loc.Header.Reliable = false; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 097f1098eb..746eb90996 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1123,22 +1123,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// regular client pings. /// /// - private void DeactivateClientDueToTimeout(IClientAPI client) + private void DeactivateClientDueToTimeout(LLClientView client) { - // We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even - // though it's set later on by LLClientView.Close() - client.IsActive = false; - - m_log.WarnFormat( - "[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}", - client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName); - - StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); - - if (!client.SceneAgent.IsChildAgent) - client.Kick("Simulator logged you out due to connection timeout"); - - client.Close(); + lock (client.CloseSyncLock) + { + m_log.WarnFormat( + "[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}", + client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName); + + StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); + + if (!client.SceneAgent.IsChildAgent) + client.Kick("Simulator logged you out due to connection timeout"); + + client.CloseWithoutChecks(); + } } private void IncomingPacketHandler() diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 36452dec09..51a6820c67 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3517,8 +3517,8 @@ namespace OpenSim.Region.Framework.Scenes // We have a zombie from a crashed session. // Or the same user is trying to be root twice here, won't work. // Kill it. - m_log.DebugFormat( - "[SCENE]: Zombie scene presence detected for {0} {1} in {2}", + m_log.WarnFormat( + "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", sp.Name, sp.UUID, RegionInfo.RegionName); sp.ControllingClient.Close(); @@ -4474,7 +4474,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// This method will return both root and child scene presences. - /// + /// /// Consider using ForEachScenePresence() or ForEachRootScenePresence() if possible since these will not /// involving creating a new List object. /// From ccc7e75ce4773d0dd5fa2f28a76da57cde76c126 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 19 Jul 2012 22:37:48 +0100 Subject: [PATCH 4/8] minor: remove some mono compiler warnings --- .../OptionalModules/PhysicsParameters/PhysicsParameters.cs | 2 +- .../Scripting/RegionReadyModule/RegionReadyModule.cs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs index e45212444d..40f7fbc59a 100755 --- a/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs +++ b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs @@ -47,7 +47,7 @@ namespace OpenSim.Region.OptionalModules.PhysicsParameters [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "PhysicsParameters")] public class PhysicsParameters : ISharedRegionModule { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // private static string LogHeader = "[PHYSICS PARAMETERS]"; private List m_scenes = new List(); diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs index e49ad2a3f8..f459b8c610 100644 --- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs @@ -48,7 +48,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private IConfig m_config = null; - private bool m_ScriptRez; private bool m_firstEmptyCompileQueue; private bool m_oarFileLoading; private bool m_lastOarLoadedOk; @@ -91,7 +90,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady m_scene.RegisterModuleInterface(this); - m_ScriptRez = false; m_firstEmptyCompileQueue = true; m_oarFileLoading = false; m_lastOarLoadedOk = true; From e94831ddab282f2d84d0dad0b28e7cce6ac4c4b0 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 19 Jul 2012 22:59:28 +0100 Subject: [PATCH 5/8] Stop explicitly closing and nulling out Animator in order to prevent NREs in various places due to race conditions. Even where checks are being made they aren't enough since they all assume that the Animator they just checked is still there in the next line, which is not necessarily the case without locking. The memory used is small and these should be GC'd anyway when the SP is released. If this is not happening then the wider problem of old SPs being retained needs to be resolved. --- .../Scenes/Animation/ScenePresenceAnimator.cs | 8 +------ .../Region/Framework/Scenes/ScenePresence.cs | 22 +++++-------------- 2 files changed, 7 insertions(+), 23 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index 14ae2872bb..ff53f45f71 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -535,11 +535,5 @@ namespace OpenSim.Region.Framework.Scenes.Animation SendAnimPack(animIDs, sequenceNums, objectIDs); } - - public void Close() - { - m_animations = null; - m_scenePresence = null; - } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 0e7f2e5dd6..548dfd36a0 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -109,15 +109,10 @@ namespace OpenSim.Region.Framework.Scenes public UUID currentParcelUUID = UUID.Zero; - protected ScenePresenceAnimator m_animator; /// /// The animator for this avatar /// - public ScenePresenceAnimator Animator - { - get { return m_animator; } - private set { m_animator = value; } - } + public ScenePresenceAnimator Animator { get; private set; } /// /// Attachments recorded on this avatar. @@ -2569,8 +2564,7 @@ namespace OpenSim.Region.Framework.Scenes //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAgent from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID); avatar.ControllingClient.SendAvatarDataImmediate(this); - if (Animator != null) - Animator.SendAnimPackToClient(avatar.ControllingClient); + Animator.SendAnimPackToClient(avatar.ControllingClient); } /// @@ -3239,14 +3233,12 @@ namespace OpenSim.Region.Framework.Scenes //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents( // as of this comment the interval is set in AddToPhysicalScene - if (Animator != null) - { + // if (m_updateCount > 0) // { - Animator.UpdateMovementAnimations(); + Animator.UpdateMovementAnimations(); // m_updateCount--; // } - } CollisionEventUpdate collisionData = (CollisionEventUpdate)e; Dictionary coldata = collisionData.m_objCollisionList; @@ -3261,7 +3253,7 @@ namespace OpenSim.Region.Framework.Scenes // m_lastColCount = coldata.Count; // } - if (coldata.Count != 0 && Animator != null) + if (coldata.Count != 0) { switch (Animator.CurrentMovementAnimation) { @@ -3371,7 +3363,7 @@ namespace OpenSim.Region.Framework.Scenes ControllingClient.SendHealth(Health); } - public void Close() + protected internal void Close() { // Clear known regions KnownRegions = new Dictionary(); @@ -3387,8 +3379,6 @@ namespace OpenSim.Region.Framework.Scenes // m_reprioritizationTimer.Dispose(); RemoveFromPhysicalScene(); - Animator.Close(); - Animator = null; } public void AddAttachment(SceneObjectGroup gobj) From c4533e755bd321195056cfbbebc80dcc05998680 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 19 Jul 2012 23:13:08 +0100 Subject: [PATCH 6/8] Comment out OnIncomingInstantMessage and OnInstantMessage handlers in GroupsModule, since these led to a private blank method --- .../CoreModules/Avatar/Groups/GroupsModule.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs index 31363e5705..b258e13dce 100644 --- a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs @@ -96,7 +96,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnClientClosed += OnClientClosed; - scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; +// scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; } public void PostInitialise() @@ -133,7 +133,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups private void OnNewClient(IClientAPI client) { // Subscribe to instant messages - client.OnInstantMessage += OnInstantMessage; +// client.OnInstantMessage += OnInstantMessage; client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; lock (m_ClientMap) @@ -171,15 +171,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups ActiveGroupTitle); } - private void OnInstantMessage(IClientAPI client, GridInstantMessage im) - { - } +// private void OnInstantMessage(IClientAPI client, GridInstantMessage im) +// { +// } - private void OnGridInstantMessage(GridInstantMessage msg) - { - // Trigger the above event handler - OnInstantMessage(null, msg); - } +// private void OnGridInstantMessage(GridInstantMessage msg) +// { +// // Trigger the above event handler +// OnInstantMessage(null, msg); +// } private void HandleUUIDGroupNameRequest(UUID id,IClientAPI remote_client) { From d1d331a4c02243c8bb4ada60566fa48417c95a5a Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 19 Jul 2012 23:20:03 +0100 Subject: [PATCH 7/8] Make LLClientView instant message handling asynchronous rather than synchronous to prevent long operations from holding up all inbound packet processing. Giving a large folder from one avatar to another was causing a long delay when handled synchronously, since it took some time to retrieve the necessary data from the inventory service. Handling this asynchronously instead stops this delay from disrupting all avatars in the scene. This has been shown in OSGrid. I see no reason for not handling all IM messages asynchronously, just as incoming chat is handled asynchronously, so this has been switched for all instant messages. Thanks to Nebadon for testing this change out. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index ae5207ba1d..f7864b8c52 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -5192,7 +5192,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer); AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate); AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply); - AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage, false); + AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage); AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship); AddLocalPacketHandler(PacketType.DeclineFriendship, HandlerDeclineFriendship); AddLocalPacketHandler(PacketType.TerminateFriendship, HandlerTerminateFriendship); From be39f03caa701d2b623e4f2c1c89256df0e85914 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 19 Jul 2012 23:35:56 +0100 Subject: [PATCH 8/8] minor: switch around mixed up circuit code and endpoint data in "show connections" region console command --- OpenSim/Region/Application/OpenSim.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 230af8edbf..a4d85acefb 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -1145,8 +1145,8 @@ namespace OpenSim c => cdt.AddRow( s.Name, c.Name, - c.RemoteEndPoint.ToString(), c.CircuitCode.ToString(), + c.RemoteEndPoint.ToString(), c.IsActive.ToString()))); MainConsole.Instance.Output(cdt.ToString());