aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2012-06-08 01:24:44 +0100
committerJustin Clark-Casey (justincc)2012-06-08 01:26:43 +0100
commit30f4a33f01751d151ae3923b48e6e98083791140 (patch)
treee361716ee927c731621276b8bc490924a71d277f
parentGo back to calling IncomingCloseAgent() in the "kick user" command for consis... (diff)
downloadopensim-SC_OLD-30f4a33f01751d151ae3923b48e6e98083791140.zip
opensim-SC_OLD-30f4a33f01751d151ae3923b48e6e98083791140.tar.gz
opensim-SC_OLD-30f4a33f01751d151ae3923b48e6e98083791140.tar.bz2
opensim-SC_OLD-30f4a33f01751d151ae3923b48e6e98083791140.tar.xz
Don't make duplicate call to ScenePresence.Close() separately in ETM.DoTeleport() if an agent needs closing.
This is always done as part of Scene.RemoveClient() Also refactors try/catching in Scene.RemoveClient() to log NREs instead of silently discarding, since these are useful symptoms of problems.
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs149
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs4
4 files changed, 74 insertions, 82 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index f2926ea..7d82060 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -644,7 +644,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
644 // an agent cannot teleport back to this region if it has teleported away. 644 // an agent cannot teleport back to this region if it has teleported away.
645 Thread.Sleep(2000); 645 Thread.Sleep(2000);
646 646
647 sp.Close();
648 sp.Scene.IncomingCloseAgent(sp.UUID); 647 sp.Scene.IncomingCloseAgent(sp.UUID);
649 } 648 }
650 else 649 else
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 9048f00..7afde38 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -3231,10 +3231,23 @@ namespace OpenSim.Region.Framework.Scenes
3231// CheckHeartbeat(); 3231// CheckHeartbeat();
3232 bool isChildAgent = false; 3232 bool isChildAgent = false;
3233 ScenePresence avatar = GetScenePresence(agentID); 3233 ScenePresence avatar = GetScenePresence(agentID);
3234 if (avatar != null) 3234
3235 if (avatar == null)
3236 {
3237 m_log.WarnFormat(
3238 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3239
3240 return;
3241 }
3242
3243 try
3235 { 3244 {
3236 isChildAgent = avatar.IsChildAgent; 3245 isChildAgent = avatar.IsChildAgent;
3237 3246
3247 m_log.DebugFormat(
3248 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3249 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3250
3238 // Don't do this to root agents, it's not nice for the viewer 3251 // Don't do this to root agents, it's not nice for the viewer
3239 if (closeChildAgents && isChildAgent) 3252 if (closeChildAgents && isChildAgent)
3240 { 3253 {
@@ -3256,99 +3269,77 @@ namespace OpenSim.Region.Framework.Scenes
3256 avatar.StandUp(); 3269 avatar.StandUp();
3257 } 3270 }
3258 3271
3259 try 3272 m_sceneGraph.removeUserCount(!isChildAgent);
3260 {
3261 m_log.DebugFormat(
3262 "[SCENE]: Removing {0} agent {1} {2} from region {3}",
3263 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3264
3265 m_sceneGraph.removeUserCount(!isChildAgent);
3266
3267 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
3268 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
3269 if (closeChildAgents && CapsModule != null)
3270 CapsModule.RemoveCaps(agentID);
3271 3273
3272 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever 3274 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
3273 // this method is doing is HORRIBLE!!! 3275 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
3274 avatar.Scene.NeedSceneCacheClear(avatar.UUID); 3276 if (closeChildAgents && CapsModule != null)
3277 CapsModule.RemoveCaps(agentID);
3275 3278
3276 if (closeChildAgents && !avatar.IsChildAgent) 3279 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3277 { 3280 // this method is doing is HORRIBLE!!!
3278 List<ulong> regions = avatar.KnownRegionHandles; 3281 avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3279 regions.Remove(RegionInfo.RegionHandle);
3280 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3281 }
3282 3282
3283 m_eventManager.TriggerClientClosed(agentID, this); 3283 if (closeChildAgents && !isChildAgent)
3284 }
3285 catch (NullReferenceException)
3286 { 3284 {
3287 // We don't know which count to remove it from 3285 List<ulong> regions = avatar.KnownRegionHandles;
3288 // Avatar is already disposed :/ 3286 regions.Remove(RegionInfo.RegionHandle);
3287 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3289 } 3288 }
3290 3289
3291 try 3290 m_eventManager.TriggerClientClosed(agentID, this);
3291 m_eventManager.TriggerOnRemovePresence(agentID);
3292
3293 if (!isChildAgent)
3292 { 3294 {
3293 m_eventManager.TriggerOnRemovePresence(agentID); 3295 if (AttachmentsModule != null && avatar.PresenceType != PresenceType.Npc)
3294
3295 if (!isChildAgent)
3296 { 3296 {
3297 if (AttachmentsModule != null && avatar.PresenceType != PresenceType.Npc) 3297 IUserManagement uMan = RequestModuleInterface<IUserManagement>();
3298 { 3298 // Don't save attachments for HG visitors, it
3299 IUserManagement uMan = RequestModuleInterface<IUserManagement>(); 3299 // messes up their inventory. When a HG visitor logs
3300 // Don't save attachments for HG visitors, it 3300 // out on a foreign grid, their attachments will be
3301 // messes up their inventory. When a HG visitor logs 3301 // reloaded in the state they were in when they left
3302 // out on a foreign grid, their attachments will be 3302 // the home grid. This is best anyway as the visited
3303 // reloaded in the state they were in when they left 3303 // grid may use an incompatible script engine.
3304 // the home grid. This is best anyway as the visited 3304 if (uMan == null || uMan.IsLocalGridUser(avatar.UUID))
3305 // grid may use an incompatible script engine. 3305 AttachmentsModule.SaveChangedAttachments(avatar, false);
3306 if (uMan == null || uMan.IsLocalGridUser(avatar.UUID))
3307 AttachmentsModule.SaveChangedAttachments(avatar, false);
3308 }
3309
3310 ForEachClient(
3311 delegate(IClientAPI client)
3312 {
3313 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3314 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); }
3315 catch (NullReferenceException) { }
3316 });
3317 } 3306 }
3318 3307
3319 // It's possible for child agents to have transactions if changes are being made cross-border. 3308 ForEachClient(
3320 if (AgentTransactionsModule != null) 3309 delegate(IClientAPI client)
3321 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); 3310 {
3322 } 3311 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3323 finally 3312 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); }
3324 { 3313 catch (NullReferenceException) { }
3325 // Always clean these structures up so that any failure above doesn't cause them to remain in the 3314 });
3326 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3327 // the same cleanup exception continually.
3328 // TODO: This should probably extend to the whole method, but we don't want to also catch the NRE
3329 // since this would hide the underlying failure and other associated problems.
3330 m_sceneGraph.RemoveScenePresence(agentID);
3331 m_clientManager.Remove(agentID);
3332 } 3315 }
3333 3316
3334 try 3317 // It's possible for child agents to have transactions if changes are being made cross-border.
3335 { 3318 if (AgentTransactionsModule != null)
3336 avatar.Close(); 3319 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3337 } 3320
3338 catch (NullReferenceException) 3321 avatar.Close();
3339 {
3340 //We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway.
3341 }
3342 catch (Exception e)
3343 {
3344 m_log.ErrorFormat("[SCENE] Scene.cs:RemoveClient exception {0}{1}", e.Message, e.StackTrace);
3345 }
3346 3322
3347 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3323 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
3348// CleanDroppedAttachments();
3349 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3350 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
3351 } 3324 }
3325 catch (Exception e)
3326 {
3327 m_log.Error(
3328 string.Format("[SCENE]: Exception removing {0} from {1}, ", avatar.Name, RegionInfo.RegionName), e);
3329 }
3330 finally
3331 {
3332 // Always clean these structures up so that any failure above doesn't cause them to remain in the
3333 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3334 // the same cleanup exception continually.
3335 // TODO: This should probably extend to the whole method, but we don't want to also catch the NRE
3336 // since this would hide the underlying failure and other associated problems.
3337 m_sceneGraph.RemoveScenePresence(agentID);
3338 m_clientManager.Remove(agentID);
3339 }
3340
3341 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3342 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
3352 } 3343 }
3353 3344
3354 /// <summary> 3345 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 3adafc1..029e0d7 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -3416,7 +3416,7 @@ namespace OpenSim.Region.Framework.Scenes
3416 3416
3417 public void Close() 3417 public void Close()
3418 { 3418 {
3419 if (!IsChildAgent) 3419 if (!IsChildAgent && m_scene.AttachmentsModule != null)
3420 m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false); 3420 m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false);
3421 3421
3422 // Clear known regions 3422 // Clear known regions
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
index 1aa48d7..02c45ef 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
@@ -101,7 +101,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
101 public void TestCloseAgent() 101 public void TestCloseAgent()
102 { 102 {
103 TestHelpers.InMethod(); 103 TestHelpers.InMethod();
104// log4net.Config.XmlConfigurator.Configure(); 104// TestHelpers.EnableLogging();
105 105
106 TestScene scene = new SceneHelpers().SetupScene(); 106 TestScene scene = new SceneHelpers().SetupScene();
107 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); 107 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
@@ -114,6 +114,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
114 Assert.That(scene.GetScenePresence(sp.UUID), Is.Null); 114 Assert.That(scene.GetScenePresence(sp.UUID), Is.Null);
115 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null); 115 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null);
116 Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(0)); 116 Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(0));
117
118// TestHelpers.DisableLogging();
117 } 119 }
118 120
119 [Test] 121 [Test]