From 3d95015686cafd7e5510d649fc58328c9565768b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 7 Dec 2011 18:43:48 +0000 Subject: On an Exception in Scene.RemoveClient(), always remove the client (and SP) structure so that logout on unexpired packets isn't retriggered, causing the same exception --- OpenSim/Region/Framework/Scenes/Scene.cs | 47 +++++++++++++++++++------------- 1 file changed, 28 insertions(+), 19 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 604f035..87af206 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3104,29 +3104,38 @@ namespace OpenSim.Region.Framework.Scenes // Avatar is already disposed :/ } - m_eventManager.TriggerOnRemovePresence(agentID); - - if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc) - AttachmentsModule.SaveChangedAttachments(avatar); - - ForEachClient( - delegate(IClientAPI client) + try + { + m_eventManager.TriggerOnRemovePresence(agentID); + + if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc) + AttachmentsModule.SaveChangedAttachments(avatar); + + ForEachClient( + delegate(IClientAPI client) + { + //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway + try { client.SendKillObject(avatar.RegionHandle, new List { avatar.LocalId }); } + catch (NullReferenceException) { } + }); + + IAgentAssetTransactions agentTransactions = this.RequestModuleInterface(); + if (agentTransactions != null) { - //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway - try { client.SendKillObject(avatar.RegionHandle, new List { avatar.LocalId }); } - catch (NullReferenceException) { } - }); - - IAgentAssetTransactions agentTransactions = this.RequestModuleInterface(); - if (agentTransactions != null) + agentTransactions.RemoveAgentAssetTransactions(agentID); + } + } + finally { - agentTransactions.RemoveAgentAssetTransactions(agentID); + // Always clean these structures up so that any failure above doesn't cause them to remain in the + // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering + // the same cleanup exception continually. + // TODO: This should probably extend to the whole method, but we don't want to also catch the NRE + // since this would hide the underlying failure and other associated problems. + m_sceneGraph.RemoveScenePresence(agentID); + m_clientManager.Remove(agentID); } - // Remove the avatar from the scene - m_sceneGraph.RemoveScenePresence(agentID); - m_clientManager.Remove(agentID); - try { avatar.Close(); -- cgit v1.1