From 6f220a867981db8e3357484feff1fe1977170561 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Fri, 5 Oct 2012 17:30:27 -0700 Subject: Trigger ObjectAddedToScene when loading objects from oarfile. Already triggers when creating, duplicating or loading from database, incoming attachments, etc --- OpenSim/Region/Framework/Scenes/Scene.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index e6b8c16..671feda 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2139,7 +2139,14 @@ namespace OpenSim.Region.Framework.Scenes public bool AddRestoredSceneObject( SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) { - return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); + if (m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates)) + { + EventManager.TriggerObjectAddedToScene(sceneObject); + return true; + } + + return false; + } /// -- cgit v1.1 From a3c0e3ed260a8a76e3009e99162cdcb8142ea1b1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 9 Oct 2012 22:19:47 +0100 Subject: minor: elaborate method doc on Scene.NewUserConnection() --- OpenSim/Region/Framework/Scenes/Scene.cs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 671feda..ed88571 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3461,11 +3461,9 @@ namespace OpenSim.Region.Framework.Scenes /// /// Do the work necessary to initiate a new user connection for a particular scene. - /// At the moment, this consists of setting up the caps infrastructure - /// The return bool should allow for connections to be refused, but as not all calling paths - /// take proper notice of it let, we allowed banned users in still. /// /// CircuitData of the agent who is connecting + /// /// Outputs the reason for the false response on this string /// True if the region accepts this agent. False if it does not. False will /// also return a reason. @@ -3476,10 +3474,20 @@ namespace OpenSim.Region.Framework.Scenes /// /// Do the work necessary to initiate a new user connection for a particular scene. - /// At the moment, this consists of setting up the caps infrastructure + /// + /// + /// The return bool should allow for connections to be refused, but as not all calling paths + /// take proper notice of it yet, we still allowed banned users in. + /// + /// At the moment this method consists of setting up the caps infrastructure /// The return bool should allow for connections to be refused, but as not all calling paths /// take proper notice of it let, we allowed banned users in still. - /// + /// + /// This method is called by the login service (in the case of login) or another simulator (in the case of region + /// cross or teleport) to initiate the connection. It is not triggered by the viewer itself - the connection + /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of + /// the LLUDP stack). + /// /// CircuitData of the agent who is connecting /// Outputs the reason for the false response on this string /// True for normal presence. False for NPC @@ -3566,7 +3574,6 @@ namespace OpenSim.Region.Framework.Scenes return false; } - ScenePresence sp = GetScenePresence(agent.AgentID); if (sp != null && !sp.IsChildAgent) -- cgit v1.1 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. --- OpenSim/Region/Framework/Scenes/Scene.cs | 457 +++++++++++++++++-------------- 1 file changed, 256 insertions(+), 201 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index ed88571..fb2decc 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -80,6 +80,11 @@ namespace OpenSim.Region.Framework.Scenes public SynchronizeSceneHandler SynchronizeScene; /// + /// Used to prevent simultaneous calls to RemoveClient() for the same agent from interfering with each other. + /// + private object m_removeClientLock = new object(); + + /// /// Statistical information for this scene. /// public SimStatsReporter StatsReporter { get; private set; } @@ -2709,69 +2714,89 @@ namespace OpenSim.Region.Framework.Scenes public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) { + ScenePresence sp; + bool vialogin; + // Validation occurs in LLUDPServer + // + // XXX: A race condition exists here where two simultaneous calls to AddNewClient can interfere with + // each other. In practice, this does not currently occur in the code. AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); - bool vialogin - = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 - || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; - -// CheckHeartbeat(); - - ScenePresence sp = GetScenePresence(client.AgentId); - - // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this - // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause - // other problems, and possible the code calling AddNewClient() should ensure that no client is already - // connected. - if (sp == null) - { - m_log.DebugFormat( - "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", - client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); - - m_clientManager.Add(client); - SubscribeToClientEvents(client); - - sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type); - m_eventManager.TriggerOnNewPresence(sp); - - sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; + // We lock here on AgentCircuitData to prevent a race condition between the thread adding a new connection + // and a simultaneous one that removes it (as can happen if the client is closed at a particular point + // whilst connecting). + // + // It would be easier to lock across all NewUserConnection(), AddNewClient() and + // RemoveClient() calls for all agents, but this would allow a slow call (e.g. because of slow service + // response in some module listening to AddNewClient()) from holding up unrelated agent calls. + // + // In practice, the lock (this) in LLUDPServer.AddNewClient() currently lock across all + // AddNewClient() operations (though not other ops). + // In the future this can be relieved once locking per agent (not necessarily on AgentCircuitData) is improved. + lock (aCircuit) + { + vialogin + = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 + || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; + + // CheckHeartbeat(); + + sp = GetScenePresence(client.AgentId); - // The first agent upon login is a root agent by design. - // For this agent we will have to rez the attachments. - // All other AddNewClient calls find aCircuit.child to be true. - if (aCircuit.child == false) + // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this + // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause + // other problems, and possible the code calling AddNewClient() should ensure that no client is already + // connected. + if (sp == null) { - // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to - // start the scripts again (since this is done in RezAttachments()). - // XXX: This is convoluted. - sp.IsChildAgent = false; - - if (AttachmentsModule != null) - Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); }); + m_log.DebugFormat( + "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", + client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); + + m_clientManager.Add(client); + SubscribeToClientEvents(client); + + sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type); + m_eventManager.TriggerOnNewPresence(sp); + + sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; + + // The first agent upon login is a root agent by design. + // For this agent we will have to rez the attachments. + // All other AddNewClient calls find aCircuit.child to be true. + if (aCircuit.child == false) + { + // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to + // start the scripts again (since this is done in RezAttachments()). + // XXX: This is convoluted. + sp.IsChildAgent = false; + + if (AttachmentsModule != null) + Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); }); + } } - } - else - { - m_log.WarnFormat( - "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", - sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); - } + else + { + m_log.WarnFormat( + "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", + sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); + } + + // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the + // client is for a root or child agent. + client.SceneAgent = sp; - // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the - // client is for a root or child agent. - client.SceneAgent = sp; + // Cache the user's name + CacheUserName(sp, aCircuit); + + EventManager.TriggerOnNewClient(client); + if (vialogin) + EventManager.TriggerOnClientLogin(client); + } m_LastLogin = Util.EnvironmentTickCount(); - // Cache the user's name - CacheUserName(sp, aCircuit); - - EventManager.TriggerOnNewClient(client); - if (vialogin) - EventManager.TriggerOnClientLogin(client); - return sp; } @@ -3300,109 +3325,129 @@ namespace OpenSim.Region.Framework.Scenes { // CheckHeartbeat(); bool isChildAgent = false; - ScenePresence avatar = GetScenePresence(agentID); - - if (avatar == null) - { - m_log.WarnFormat( - "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID); - - return; - } + AgentCircuitData acd; - try + lock (m_removeClientLock) { - isChildAgent = avatar.IsChildAgent; - - m_log.DebugFormat( - "[SCENE]: Removing {0} agent {1} {2} from {3}", - (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName); + acd = m_authenticateHandler.GetAgentCircuitData(agentID); - // Don't do this to root agents, it's not nice for the viewer - if (closeChildAgents && isChildAgent) + if (acd == null) { - // Tell a single agent to disconnect from the region. - IEventQueue eq = RequestModuleInterface(); - if (eq != null) - { - eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID); - } - else - { - avatar.ControllingClient.SendShutdownConnectionNotice(); - } + m_log.ErrorFormat("[SCENE]: No agent circuit found for {0}, aborting Scene.RemoveClient", agentID); + return; } - - // Only applies to root agents. - if (avatar.ParentID != 0) + else { - avatar.StandUp(); + // We remove the acd up here to avoid later raec conditions if two RemoveClient() calls occurred + // simultaneously. + m_authenticateHandler.RemoveCircuit(acd.circuitcode); } + } - m_sceneGraph.removeUserCount(!isChildAgent); - - // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop - // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI - if (closeChildAgents && CapsModule != null) - CapsModule.RemoveCaps(agentID); - - // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever - // this method is doing is HORRIBLE!!! - avatar.Scene.NeedSceneCacheClear(avatar.UUID); - - if (closeChildAgents && !isChildAgent) + lock (acd) + { + ScenePresence avatar = GetScenePresence(agentID); + + if (avatar == null) { - List regions = avatar.KnownRegionHandles; - regions.Remove(RegionInfo.RegionHandle); - m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); + m_log.WarnFormat( + "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID); + + return; } - - m_eventManager.TriggerClientClosed(agentID, this); - m_eventManager.TriggerOnRemovePresence(agentID); - - if (!isChildAgent) + + try { - if (AttachmentsModule != null) + isChildAgent = avatar.IsChildAgent; + + m_log.DebugFormat( + "[SCENE]: Removing {0} agent {1} {2} from {3}", + (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName); + + // Don't do this to root agents, it's not nice for the viewer + if (closeChildAgents && isChildAgent) { - AttachmentsModule.DeRezAttachments(avatar); + // Tell a single agent to disconnect from the region. + IEventQueue eq = RequestModuleInterface(); + if (eq != null) + { + eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID); + } + else + { + avatar.ControllingClient.SendShutdownConnectionNotice(); + } } - - ForEachClient( - delegate(IClientAPI client) + + // Only applies to root agents. + if (avatar.ParentID != 0) + { + avatar.StandUp(); + } + + m_sceneGraph.removeUserCount(!isChildAgent); + + // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop + // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI + if (closeChildAgents && CapsModule != null) + CapsModule.RemoveCaps(agentID); + + // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever + // this method is doing is HORRIBLE!!! + avatar.Scene.NeedSceneCacheClear(avatar.UUID); + + if (closeChildAgents && !isChildAgent) + { + List regions = avatar.KnownRegionHandles; + regions.Remove(RegionInfo.RegionHandle); + m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); + } + + m_eventManager.TriggerClientClosed(agentID, this); + m_eventManager.TriggerOnRemovePresence(agentID); + + if (!isChildAgent) + { + if (AttachmentsModule != 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) { } - }); - } - - // It's possible for child agents to have transactions if changes are being made cross-border. - if (AgentTransactionsModule != null) - AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); + AttachmentsModule.DeRezAttachments(avatar); + } - m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); - } - catch (Exception e) - { - m_log.Error( - string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e); - } - finally - { - try - { - // 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. - m_sceneGraph.RemoveScenePresence(agentID); - m_clientManager.Remove(agentID); + 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) { } + }); + } - avatar.Close(); + // It's possible for child agents to have transactions if changes are being made cross-border. + if (AgentTransactionsModule != null) + AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); } catch (Exception e) { m_log.Error( - string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e); + string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e); + } + finally + { + try + { + // 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. + m_sceneGraph.RemoveScenePresence(agentID); + m_clientManager.Remove(agentID); + + avatar.Close(); + } + catch (Exception e) + { + m_log.Error( + string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e); + } } } @@ -3572,87 +3617,97 @@ namespace OpenSim.Region.Framework.Scenes agent.firstname, agent.lastname, agent.Viewer); reason = "Access denied, your viewer is banned by the region owner"; return false; - } - - ScenePresence sp = GetScenePresence(agent.AgentID); - - if (sp != null && !sp.IsChildAgent) - { - // 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.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(true); - sp = null; } - ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); + ILandObject land; - //On login test land permisions - if (vialogin) + lock (agent) { - if (land != null && !TestLandRestrictions(agent, land, out reason)) + ScenePresence sp = GetScenePresence(agent.AgentID); + + if (sp != null && !sp.IsChildAgent) { - return false; + // 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.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(true); + sp = null; } - } - - if (sp == null) // We don't have an [child] agent here already - { - if (requirePresenceLookup) + + land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); + + //On login test land permisions + if (vialogin) { - try - { - if (!VerifyUserPresence(agent, out reason)) - return false; - } catch (Exception e) + if (land != null && !TestLandRestrictions(agent, land, out reason)) { - m_log.ErrorFormat( - "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); return false; } } - - try - { - if (!AuthorizeUser(agent, out reason)) - return false; - } catch (Exception e) - { - m_log.ErrorFormat( - "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); - return false; - } - - m_log.InfoFormat( - "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})", - RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname, - agent.AgentID, agent.circuitcode); - - if (CapsModule != null) + + if (sp == null) // We don't have an [child] agent here already { - CapsModule.SetAgentCapsSeeds(agent); - CapsModule.CreateCaps(agent.AgentID); - } - } else - { - // Let the SP know how we got here. This has a lot of interesting - // uses down the line. - sp.TeleportFlags = (TPFlags)teleportFlags; + if (requirePresenceLookup) + { + try + { + if (!VerifyUserPresence(agent, out reason)) + return false; + } + catch (Exception e) + { + m_log.ErrorFormat( + "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); - if (sp.IsChildAgent) - { - m_log.DebugFormat( - "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", - agent.AgentID, RegionInfo.RegionName); + return false; + } + } + + try + { + if (!AuthorizeUser(agent, out reason)) + return false; + } + catch (Exception e) + { + m_log.ErrorFormat( + "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); - sp.AdjustKnownSeeds(); - + return false; + } + + m_log.InfoFormat( + "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})", + RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname, + agent.AgentID, agent.circuitcode); + if (CapsModule != null) + { CapsModule.SetAgentCapsSeeds(agent); + CapsModule.CreateCaps(agent.AgentID); + } + } + else + { + // Let the SP know how we got here. This has a lot of interesting + // uses down the line. + sp.TeleportFlags = (TPFlags)teleportFlags; + + if (sp.IsChildAgent) + { + m_log.DebugFormat( + "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", + agent.AgentID, RegionInfo.RegionName); + + sp.AdjustKnownSeeds(); + + if (CapsModule != null) + CapsModule.SetAgentCapsSeeds(agent); + } } } -- cgit v1.1 From b5a3c74a5cbd1634d021923124a997fc4945e5ef Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Oct 2012 02:52:08 +0100 Subject: Add "active true|false" to "debug scene" console command. This allows the scene update and maintenance loops to be started and stopped for debug purposes. --- OpenSim/Region/Framework/Scenes/Scene.cs | 40 +++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index fb2decc..7f4f7e5 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -306,6 +306,30 @@ namespace OpenSim.Region.Framework.Scenes } private volatile bool m_shuttingDown; + /// + /// Is the scene active? + /// + /// + /// If false, maintenance and update loops are not run. + /// + public bool Active + { + get { return m_active; } + set + { + if (value) + { + if (!m_active) + Start(); + } + else + { + m_active = false; + } + } + } + private volatile bool m_active; + // private int m_lastUpdate; // private bool m_firstHeartbeat = true; @@ -1159,6 +1183,14 @@ namespace OpenSim.Region.Framework.Scenes public void SetSceneCoreDebug(Dictionary options) { + if (options.ContainsKey("active")) + { + bool active; + + if (bool.TryParse(options["active"], out active)) + Active = active; + } + if (options.ContainsKey("scripting")) { bool enableScripts = true; @@ -1298,6 +1330,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void Start() { + m_active = true; + // m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); //m_heartbeatTimer.Enabled = true; @@ -1339,7 +1373,7 @@ namespace OpenSim.Region.Framework.Scenes #region Update Methods /// - /// Performs per-frame updates regularly + /// Activate the various loops necessary to continually update the scene. /// private void Heartbeat() { @@ -1396,7 +1430,7 @@ namespace OpenSim.Region.Framework.Scenes List coarseLocations; List avatarUUIDs; - while (!m_shuttingDown && (endRun == null || MaintenanceRun < endRun)) + while (Active && !m_shuttingDown && (endRun == null || MaintenanceRun < endRun)) { runtc = Util.EnvironmentTickCount(); ++MaintenanceRun; @@ -1455,7 +1489,7 @@ namespace OpenSim.Region.Framework.Scenes int previousFrameTick, tmpMS; int maintc = Util.EnvironmentTickCount(); - while (!m_shuttingDown && (endFrame == null || Frame < endFrame)) + while (Active && !m_shuttingDown && (endFrame == null || Frame < endFrame)) { ++Frame; -- cgit v1.1 From b9c2a1508e68b5580328097a5d5e0b5bfbc16a7d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Oct 2012 03:19:12 +0100 Subject: Fix problems with regression tests by allowing invoke of Update() with a finite number of frames even if the scene isn't active. --- OpenSim/Region/Framework/Scenes/Scene.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 7f4f7e5..fe549bc 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -310,7 +310,8 @@ namespace OpenSim.Region.Framework.Scenes /// Is the scene active? /// /// - /// If false, maintenance and update loops are not run. + /// If false, maintenance and update loops are not being run. Updates can still be triggered manually if + /// the scene is not active. /// public bool Active { @@ -1430,7 +1431,7 @@ namespace OpenSim.Region.Framework.Scenes List coarseLocations; List avatarUUIDs; - while (Active && !m_shuttingDown && (endRun == null || MaintenanceRun < endRun)) + while (!m_shuttingDown && ((endRun == null && Active) || MaintenanceRun < endRun)) { runtc = Util.EnvironmentTickCount(); ++MaintenanceRun; @@ -1489,7 +1490,7 @@ namespace OpenSim.Region.Framework.Scenes int previousFrameTick, tmpMS; int maintc = Util.EnvironmentTickCount(); - while (Active && !m_shuttingDown && (endFrame == null || Frame < endFrame)) + while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame)) { ++Frame; -- cgit v1.1