From 77e48a6725ccc30d33596b4f8c3dcdc956b7d1ba Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Fri, 9 Oct 2009 02:49:55 -0700 Subject: Change the backup thread to run on a BackgroundWorker instead of a Thread. I don't have an explanation, but this seems to stop a slow but steady memory leak I was experiencing --- OpenSim/Region/Framework/Scenes/Scene.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index ceff28b..6a550fa 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1186,10 +1186,10 @@ namespace OpenSim.Region.Framework.Scenes if (!m_backingup) { m_backingup = true; - Thread backupthread = new Thread(Backup); - backupthread.Name = "BackupWriter"; - backupthread.IsBackground = true; - backupthread.Start(); + + System.ComponentModel.BackgroundWorker backupWorker = new System.ComponentModel.BackgroundWorker(); + backupWorker.DoWork += delegate(object sender, System.ComponentModel.DoWorkEventArgs e) { Backup(); }; + backupWorker.RunWorkerAsync(); } } -- cgit v1.1 From c0beeb929e22509329781cdf85f7a5d90c4b0e36 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 12 Oct 2009 17:00:01 -0700 Subject: * Fixes http://opensimulator.org/mantis/view.php?id=4225 * Fixes http://opensimulator.org/mantis/view.php?id=3959 * Allows for viewing inventory textures outside home grid --- .../Framework/Scenes/Hypergrid/HGAssetMapper.cs | 98 ++++++++++------------ .../Scenes/Hypergrid/HGScene.Inventory.cs | 26 ++++++ OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 9 +- 3 files changed, 79 insertions(+), 54 deletions(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs index b6fa41d..244ac3b 100644 --- a/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs +++ b/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs @@ -35,6 +35,7 @@ using OpenSim.Framework; using OpenSim.Framework.Communications.Cache; using OpenSim.Framework.Communications.Clients; using OpenSim.Region.Framework.Scenes.Serialization; +using OpenSim.Region.Framework.Interfaces; using OpenSim.Services.Interfaces; //using HyperGrid.Framework; @@ -52,13 +53,13 @@ namespace OpenSim.Region.Framework.Scenes.Hypergrid private Scene m_scene; - private IHyperlinkService m_hyper; - IHyperlinkService HyperlinkService + private IHyperAssetService m_hyper; + IHyperAssetService HyperlinkAssets { get { if (m_hyper == null) - m_hyper = m_scene.RequestModuleInterface(); + m_hyper = m_scene.RequestModuleInterface(); return m_hyper; } } @@ -99,7 +100,7 @@ namespace OpenSim.Region.Framework.Scenes.Hypergrid if (asset != null) { - m_log.Debug("[HGScene]: Asset made it to asset cache. " + asset.Name + " " + assetID); + m_log.DebugFormat("[HGScene]: Copied asset {0} from {1} to local asset server. ", asset.ID, url); return asset; } return null; @@ -129,6 +130,7 @@ namespace OpenSim.Region.Framework.Scenes.Hypergrid } m_scene.AssetService.Store(asset1); + m_log.DebugFormat("[HGScene]: Posted copy of asset {0} from local asset server to {1}", asset1.ID, url); } return true; } @@ -167,34 +169,32 @@ namespace OpenSim.Region.Framework.Scenes.Hypergrid public void Get(UUID assetID, UUID ownerID) { - if (!HyperlinkService.IsLocalUser(ownerID)) + // Get the item from the remote asset server onto the local AssetCache + // and place an entry in m_assetMap + + string userAssetURL = HyperlinkAssets.GetUserAssetServer(ownerID); + if ((userAssetURL != string.Empty) && (userAssetURL != HyperlinkAssets.GetSimAssetServer())) { - // Get the item from the remote asset server onto the local AssetCache - // and place an entry in m_assetMap + m_log.Debug("[HGScene]: Fetching object " + assetID + " from asset server " + userAssetURL); + AssetBase asset = FetchAsset(userAssetURL, assetID); - string userAssetURL = UserAssetURL(ownerID); - if (userAssetURL != null) + if (asset != null) { - m_log.Debug("[HGScene]: Fetching object " + assetID + " to asset server " + userAssetURL); - AssetBase asset = FetchAsset(userAssetURL, assetID); + // OK, now fetch the inside. + Dictionary ids = new Dictionary(); + HGUuidGatherer uuidGatherer = new HGUuidGatherer(this, m_scene.AssetService, userAssetURL); + uuidGatherer.GatherAssetUuids(asset.FullID, (AssetType)asset.Type, ids); + foreach (UUID uuid in ids.Keys) + FetchAsset(userAssetURL, uuid); + + m_log.DebugFormat("[HGScene]: Successfully fetched asset {0} from asset server {1}", asset.ID, userAssetURL); - if (asset != null) - { - m_log.Debug("[HGScene]: Successfully fetched item from remote asset server " + userAssetURL); - - // OK, now fetch the inside. - Dictionary ids = new Dictionary(); - HGUuidGatherer uuidGatherer = new HGUuidGatherer(this, m_scene.AssetService, userAssetURL); - uuidGatherer.GatherAssetUuids(asset.FullID, (AssetType)asset.Type, ids); - foreach (UUID uuid in ids.Keys) - FetchAsset(userAssetURL, uuid); - } - else - m_log.Warn("[HGScene]: Could not fetch asset from remote asset server " + userAssetURL); } else - m_log.Warn("[HGScene]: Unable to locate foreign user's asset server"); + m_log.Warn("[HGScene]: Could not fetch asset from remote asset server " + userAssetURL); } + else + m_log.Debug("[HGScene]: user's asset server is the local region's asset server"); } //public InventoryItemBase Get(InventoryItemBase item, UUID rootFolder, CachedUserInfo userInfo) @@ -225,44 +225,38 @@ namespace OpenSim.Region.Framework.Scenes.Hypergrid public void Post(UUID assetID, UUID ownerID) { - if (!HyperlinkService.IsLocalUser(ownerID)) - { // Post the item from the local AssetCache onto the remote asset server // and place an entry in m_assetMap - string userAssetURL = UserAssetURL(ownerID); - if (userAssetURL != null) + string userAssetURL = HyperlinkAssets.GetUserAssetServer(ownerID); + if ((userAssetURL != string.Empty) && (userAssetURL != HyperlinkAssets.GetSimAssetServer())) + { + m_log.Debug("[HGScene]: Posting object " + assetID + " to asset server " + userAssetURL); + AssetBase asset = m_scene.AssetService.Get(assetID.ToString()); + if (asset != null) { - m_log.Debug("[HGScene]: Posting object " + assetID + " to asset server " + userAssetURL); - AssetBase asset = m_scene.AssetService.Get(assetID.ToString()); - if (asset != null) + Dictionary ids = new Dictionary(); + HGUuidGatherer uuidGatherer = new HGUuidGatherer(this, m_scene.AssetService, string.Empty); + uuidGatherer.GatherAssetUuids(asset.FullID, (AssetType)asset.Type, ids); + foreach (UUID uuid in ids.Keys) { - Dictionary ids = new Dictionary(); - HGUuidGatherer uuidGatherer = new HGUuidGatherer(this, m_scene.AssetService, string.Empty); - uuidGatherer.GatherAssetUuids(asset.FullID, (AssetType)asset.Type, ids); - foreach (UUID uuid in ids.Keys) - { - asset = m_scene.AssetService.Get(uuid.ToString()); - if (asset != null) - m_log.DebugFormat("[HGScene]: Posting {0} {1}", asset.Type.ToString(), asset.Name); - else - m_log.DebugFormat("[HGScene]: Could not find asset {0}", uuid); + asset = m_scene.AssetService.Get(uuid.ToString()); + if (asset == null) + m_log.DebugFormat("[HGScene]: Could not find asset {0}", uuid); + else PostAsset(userAssetURL, asset); - } + } - if (ids.Count > 0) // maybe it succeeded... - m_log.DebugFormat("[HGScene]: Successfully posted item {0} to remote asset server {1}", assetID, userAssetURL); - else - m_log.WarnFormat("[HGScene]: Could not post asset {0} to remote asset server {1}", assetID, userAssetURL); + // maybe all pieces got there... + m_log.DebugFormat("[HGScene]: Successfully posted item {0} to asset server {1}", assetID, userAssetURL); - } - else - m_log.Debug("[HGScene]: Something wrong with asset, it could not be found"); } else - m_log.Warn("[HGScene]: Unable to locate foreign user's asset server"); - + m_log.DebugFormat("[HGScene]: Something wrong with asset {0}, it could not be found", assetID); } + else + m_log.Debug("[HGScene]: user's asset server is local region's asset server"); + } #endregion diff --git a/OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.Inventory.cs index 8fe3565..6f7f34f 100644 --- a/OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.Inventory.cs @@ -32,6 +32,7 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Communications; using OpenSim.Framework.Communications.Cache; +using OpenSim.Region.Framework.Interfaces; namespace OpenSim.Region.Framework.Scenes.Hypergrid { @@ -41,6 +42,21 @@ namespace OpenSim.Region.Framework.Scenes.Hypergrid private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private HGAssetMapper m_assMapper; + public HGAssetMapper AssetMapper + { + get { return m_assMapper; } + } + + private IHyperAssetService m_hyper; + private IHyperAssetService HyperAssets + { + get + { + if (m_hyper == null) + m_hyper = RequestModuleInterface(); + return m_hyper; + } + } #endregion @@ -140,6 +156,16 @@ namespace OpenSim.Region.Framework.Scenes.Hypergrid } + protected override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver) + { + string userAssetServer = HyperAssets.GetUserAssetServer(sender); + if ((userAssetServer != string.Empty) && (userAssetServer != HyperAssets.GetSimAssetServer())) + m_assMapper.Get(item.AssetID, sender); + + userAssetServer = HyperAssets.GetUserAssetServer(receiver); + if ((userAssetServer != string.Empty) && (userAssetServer != HyperAssets.GetSimAssetServer())) + m_assMapper.Post(item.AssetID, receiver); + } #endregion diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 1917228..0cb5682 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -408,7 +408,7 @@ namespace OpenSim.Region.Framework.Scenes public virtual InventoryItemBase GiveInventoryItem( UUID recipient, UUID senderId, UUID itemId, UUID recipientFolderId) { - Console.WriteLine("Scene.Inventory.cs: GiveInventoryItem"); + //Console.WriteLine("Scene.Inventory.cs: GiveInventoryItem"); InventoryItemBase item = new InventoryItemBase(itemId, senderId); item = InventoryService.GetItem(item); @@ -472,7 +472,8 @@ namespace OpenSim.Region.Framework.Scenes itemCopy.SalePrice = item.SalePrice; itemCopy.SaleType = item.SaleType; - InventoryService.AddItem(itemCopy); + if (InventoryService.AddItem(itemCopy)) + TransferInventoryAssets(itemCopy, senderId, recipient); if (!Permissions.BypassPermissions()) { @@ -494,6 +495,10 @@ namespace OpenSim.Region.Framework.Scenes } + protected virtual void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver) + { + } + /// /// Give an entire inventory folder from one user to another. The entire contents (including all descendent /// folders) is given. -- cgit v1.1 From 0cfbdf3894756654465c0a2e1b8e796fcdb37baa Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 12 Oct 2009 17:01:03 -0700 Subject: Added this one file for the previous commit to work. --- .../Region/Framework/Interfaces/IHyperService.cs | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 OpenSim/Region/Framework/Interfaces/IHyperService.cs (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Interfaces/IHyperService.cs b/OpenSim/Region/Framework/Interfaces/IHyperService.cs new file mode 100644 index 0000000..51ea28a --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IHyperService.cs @@ -0,0 +1,37 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using OpenMetaverse; + +namespace OpenSim.Region.Framework.Interfaces +{ + public interface IHyperAssetService + { + string GetUserAssetServer(UUID userID); + string GetSimAssetServer(); + } +} -- cgit v1.1 From c893761319f7e61d13b2d2301180d0f227fde1a9 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 13 Oct 2009 12:50:59 -0700 Subject: * Unregister event handlers in LLUDPServer when a client logs out and disconnects * Move ViewerEffect handling to Scene.PacketHandlers * Removing the unused CloseAllAgents function * Trimming ClientManager down. This class needs to be reworked to keep LLUDP circuit codes from intruding into the abstract OpenSim core code --- .../Framework/Scenes/Scene.PacketHandlers.cs | 26 ++++++++++++++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 15 ++----------- OpenSim/Region/Framework/Scenes/SceneBase.cs | 2 -- .../Framework/Scenes/Tests/SceneBaseTests.cs | 5 ----- 4 files changed, 28 insertions(+), 20 deletions(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 4ae4dc3..dbbf679 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -390,6 +390,32 @@ namespace OpenSim.Region.Framework.Scenes EventManager.TriggerScriptReset(part.LocalId, itemID); } } + + void ProcessViewerEffect(IClientAPI remoteClient, List args) + { + // TODO: don't create new blocks if recycling an old packet + List effectBlock = new List(); + for (int i = 0; i < args.Count; i++) + { + ViewerEffectPacket.EffectBlock effect = new ViewerEffectPacket.EffectBlock(); + effect.AgentID = args[i].AgentID; + effect.Color = args[i].Color; + effect.Duration = args[i].Duration; + effect.ID = args[i].ID; + effect.Type = args[i].Type; + effect.TypeData = args[i].TypeData; + effectBlock.Add(effect); + } + ViewerEffectPacket.EffectBlock[] effectBlockArray = effectBlock.ToArray(); + + ClientManager.ForEachClient( + delegate(IClientAPI client) + { + if (client.AgentId != remoteClient.AgentId) + client.SendViewerEffect(effectBlockArray); + } + ); + } /// /// Handle a fetch inventory request from the client diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index cffb23c..e81b07b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2572,6 +2572,7 @@ namespace OpenSim.Region.Framework.Scenes public virtual void SubscribeToClientNetworkEvents(IClientAPI client) { client.OnNetworkStatsUpdate += StatsReporter.AddPacketsStats; + client.OnViewerEffect += ProcessViewerEffect; } protected virtual void UnsubscribeToClientEvents(IClientAPI client) @@ -2726,11 +2727,9 @@ namespace OpenSim.Region.Framework.Scenes public virtual void UnSubscribeToClientNetworkEvents(IClientAPI client) { client.OnNetworkStatsUpdate -= StatsReporter.AddPacketsStats; + client.OnViewerEffect -= ProcessViewerEffect; } - - - /// /// Teleport an avatar to their home region /// @@ -3053,16 +3052,6 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Closes all endpoints with the circuitcode provided. - /// - /// Circuit Code of the endpoint to close - public override void CloseAllAgents(uint circuitcode) - { - // Called by ClientView to kill all circuit codes - ClientManager.CloseAllAgents(circuitcode); - } - - /// /// Inform all other ScenePresences on this Scene that someone else has changed position on the minimap. /// public void NotifyMyCoarseLocationChange() diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index 0ac4ed4..cf5c3c8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs @@ -196,8 +196,6 @@ namespace OpenSim.Region.Framework.Scenes /// public abstract void RemoveClient(UUID agentID); - public abstract void CloseAllAgents(uint circuitcode); - #endregion /// diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneBaseTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneBaseTests.cs index 5c9e66f..8230f32 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneBaseTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneBaseTests.cs @@ -61,11 +61,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests throw new NotImplementedException(); } - public override void CloseAllAgents(uint circuitcode) - { - throw new NotImplementedException(); - } - public override void OtherRegionUp(GridRegion otherRegion) { throw new NotImplementedException(); -- cgit v1.1 From 23a334b9f54a1ef5df3b503c165e7b76b746a2b1 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 13 Oct 2009 14:50:03 -0700 Subject: * Rewrote ClientManager to remove Lindenisms from OpenSim core, improve performance by removing locks, and replace LLUDPClientCollection * Removed the confusing (and LL-specific) shutdowncircuit parameter from IClientAPI.Close() * Updated the LLUDP code to only use ClientManager instead of trying to synchronize ClientManager and m_clients * Remove clients asynchronously since it is a very slow operation (including a 2000ms sleep) --- OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index dbbf679..ac89f7b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -408,7 +408,7 @@ namespace OpenSim.Region.Framework.Scenes } ViewerEffectPacket.EffectBlock[] effectBlockArray = effectBlock.ToArray(); - ClientManager.ForEachClient( + ClientManager.ForEach( delegate(IClientAPI client) { if (client.AgentId != remoteClient.AgentId) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index e81b07b..bb71896 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -867,7 +867,7 @@ namespace OpenSim.Region.Framework.Scenes Thread.Sleep(500); // Stop all client threads. - ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(true); }); + ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); }); // Stop updating the scene objects and agents. //m_heartbeatTimer.Close(); @@ -3372,7 +3372,7 @@ namespace OpenSim.Region.Framework.Scenes loggingOffUser.ControllingClient.Kick(message); // Give them a second to receive the message! Thread.Sleep(1000); - loggingOffUser.ControllingClient.Close(true); + loggingOffUser.ControllingClient.Close(); } else { @@ -3543,7 +3543,7 @@ namespace OpenSim.Region.Framework.Scenes presence.ControllingClient.SendShutdownConnectionNotice(); } - presence.ControllingClient.Close(true); + presence.ControllingClient.Close(); return true; } -- cgit v1.1 From dc11643c007adf7a640ec4fbabe25995352aaa18 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 13 Oct 2009 17:33:45 -0700 Subject: * Consolidated adding / removing ClientManager IClientAPIs to two places in Scene * Added some missing implementations of IClientAPI.RemoteEndPoint * Added a ClientManager.Remove(UUID) overload * Removed a reference to a missing project from prebuild.xml --- OpenSim/Region/Framework/Scenes/Scene.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index bb71896..7944548 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2363,6 +2363,8 @@ namespace OpenSim.Region.Framework.Scenes /// public override void AddNewClient(IClientAPI client) { + ClientManager.Add(client); + CheckHeartbeat(); SubscribeToClientEvents(client); ScenePresence presence; @@ -3002,7 +3004,9 @@ namespace OpenSim.Region.Framework.Scenes agentTransactions.RemoveAgentAssetTransactions(agentID); } + // Remove the avatar from the scene m_sceneGraph.RemoveScenePresence(agentID); + ClientManager.Remove(agentID); try { -- cgit v1.1 From 31a61bbeec5aae6b679ffa53e2966420e774f301 Mon Sep 17 00:00:00 2001 From: Teravus Ovares (Dan Olivares) Date: Tue, 13 Oct 2009 22:03:00 -0400 Subject: * Fixes some prim crossings on megaregions with regions beyond the 512m mark * There's a slight chance that this could cause a problem with regular prim crossings.. but hopefully not. Revert if it does. --- OpenSim/Region/Framework/Scenes/Scene.cs | 114 +++++++++++++++++++++++++------ 1 file changed, 93 insertions(+), 21 deletions(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 949cf19..0f351ce 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1780,36 +1780,86 @@ namespace OpenSim.Region.Framework.Scenes Vector3 pos = attemptedPosition; + int changeX = 1; + int changeY = 1; + if (TestBorderCross(attemptedPosition + WestCross, Cardinals.W)) { if (TestBorderCross(attemptedPosition + SouthCross, Cardinals.S)) { - //Border crossedBorderx = GetCrossedBorder(attemptedPosition,Cardinals.W); - //Border crossedBordery = GetCrossedBorder(attemptedPosition, Cardinals.S); + + Border crossedBorderx = GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W); + + if (crossedBorderx.BorderLine.Z > 0) + { + pos.X = ((pos.X + crossedBorderx.BorderLine.Z)); + changeX = (int)(crossedBorderx.BorderLine.Z /(int) Constants.RegionSize); + } + else + pos.X = ((pos.X + Constants.RegionSize)); + + Border crossedBordery = GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) - pos.X = ((pos.X + Constants.RegionSize)); - pos.Y = ((pos.Y + Constants.RegionSize)); + + if (crossedBordery.BorderLine.Z > 0) + { + pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); + } + else + pos.Y = ((pos.Y + Constants.RegionSize)); + + + newRegionHandle - = Util.UIntsToLong((uint)((thisx - 1) * Constants.RegionSize), - (uint)((thisy - 1) * Constants.RegionSize)); + = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), + (uint)((thisy - changeY) * Constants.RegionSize)); // x - 1 // y - 1 } else if (TestBorderCross(attemptedPosition + NorthCross, Cardinals.N)) { - pos.X = ((pos.X + Constants.RegionSize)); - pos.Y = ((pos.Y - Constants.RegionSize)); + Border crossedBorderx = GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W); + + if (crossedBorderx.BorderLine.Z > 0) + { + pos.X = ((pos.X + crossedBorderx.BorderLine.Z)); + changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize); + } + else + pos.X = ((pos.X + Constants.RegionSize)); + + + Border crossedBordery = GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); + //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) + + if (crossedBordery.BorderLine.Z > 0) + { + pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); + changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); + } + else + pos.Y = ((pos.Y + Constants.RegionSize)); + newRegionHandle - = Util.UIntsToLong((uint)((thisx - 1) * Constants.RegionSize), - (uint)((thisy + 1) * Constants.RegionSize)); + = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), + (uint)((thisy + changeY) * Constants.RegionSize)); // x - 1 // y + 1 } else { - pos.X = ((pos.X + Constants.RegionSize)); + Border crossedBorderx = GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W); + + if (crossedBorderx.BorderLine.Z > 0) + { + pos.X = ((pos.X + crossedBorderx.BorderLine.Z)); + changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize); + } + else + pos.X = ((pos.X + Constants.RegionSize)); + newRegionHandle - = Util.UIntsToLong((uint) ((thisx - 1)*Constants.RegionSize), + = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), (uint) (thisy*Constants.RegionSize)); // x - 1 } @@ -1818,11 +1868,23 @@ namespace OpenSim.Region.Framework.Scenes { if (TestBorderCross(attemptedPosition + SouthCross, Cardinals.S)) { + pos.X = ((pos.X - Constants.RegionSize)); - pos.Y = ((pos.Y + Constants.RegionSize)); + Border crossedBordery = GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); + //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) + + if (crossedBordery.BorderLine.Z > 0) + { + pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); + changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); + } + else + pos.Y = ((pos.Y + Constants.RegionSize)); + + newRegionHandle - = Util.UIntsToLong((uint)((thisx + 1) * Constants.RegionSize), - (uint)((thisy - 1) * Constants.RegionSize)); + = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize), + (uint)((thisy - changeY) * Constants.RegionSize)); // x + 1 // y - 1 } @@ -1831,8 +1893,8 @@ namespace OpenSim.Region.Framework.Scenes pos.X = ((pos.X - Constants.RegionSize)); pos.Y = ((pos.Y - Constants.RegionSize)); newRegionHandle - = Util.UIntsToLong((uint)((thisx + 1) * Constants.RegionSize), - (uint)((thisy + 1) * Constants.RegionSize)); + = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize), + (uint)((thisy + changeY) * Constants.RegionSize)); // x + 1 // y + 1 } @@ -1840,16 +1902,26 @@ namespace OpenSim.Region.Framework.Scenes { pos.X = ((pos.X - Constants.RegionSize)); newRegionHandle - = Util.UIntsToLong((uint) ((thisx + 1)*Constants.RegionSize), + = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize), (uint) (thisy*Constants.RegionSize)); // x + 1 } } else if (TestBorderCross(attemptedPosition + SouthCross, Cardinals.S)) { - pos.Y = ((pos.Y + Constants.RegionSize)); + Border crossedBordery = GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); + //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) + + if (crossedBordery.BorderLine.Z > 0) + { + pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); + changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); + } + else + pos.Y = ((pos.Y + Constants.RegionSize)); + newRegionHandle - = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - 1) * Constants.RegionSize)); + = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - changeY) * Constants.RegionSize)); // y - 1 } else if (TestBorderCross(attemptedPosition + NorthCross, Cardinals.N)) @@ -1857,7 +1929,7 @@ namespace OpenSim.Region.Framework.Scenes pos.Y = ((pos.Y - Constants.RegionSize)); newRegionHandle - = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + 1) * Constants.RegionSize)); + = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize)); // y + 1 } -- cgit v1.1 From 5976ac16b0eedaeca2360010a3d6f7be4213700a Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Tue, 13 Oct 2009 19:13:06 -0700 Subject: Optimized heartbeat by calling Update() only on updated objects. During the heartbeat loop, Update() is called on every SceneObjectGroup which in turn checks if any SceneObjectPart has changed. For large regions (> 100k prims) this work consumes 20-30% of a CPU even though there are only a few objects updating each frame. There is only one other reason to check every object on every frame, and that is the case where a script has registered the object with an "at target" listener. We can easily track when an object is registered or unregistered with an AtTarget, so this is not a reason to check every object every heartbeat. In the attached patch, I have added a dictionary to the scene which tracks the objects which have At Targets. Each heartbeat, the AtTarget() function will be called on every object registered with a listener for that event. Also, I added a dictionary to SceneGraph which stores references to objects which have been queued for updates during the heartbeat. At each heartbeat, Update() is called only on the objects which have generated updates during that beat. --- OpenSim/Region/Framework/Scenes/Scene.cs | 82 ++++++++++------------ OpenSim/Region/Framework/Scenes/SceneGraph.cs | 28 +++----- .../Region/Framework/Scenes/SceneObjectGroup.cs | 15 ++-- 3 files changed, 52 insertions(+), 73 deletions(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 7944548..1ca0267 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -117,6 +117,8 @@ namespace OpenSim.Region.Framework.Scenes private volatile bool m_backingup = false; private Dictionary m_returns = new Dictionary(); + + private Dictionary m_groupsWithTargets = new Dictionary(); protected string m_simulatorVersion = "OpenSimulator Server"; @@ -246,8 +248,7 @@ namespace OpenSim.Region.Framework.Scenes private int m_update_physics = 1; private int m_update_entitymovement = 1; - private int m_update_entities = 1; // Run through all objects checking for updates - private int m_update_entitiesquick = 200; // Run through objects that have scheduled updates checking for updates + private int m_update_objects = 1; // Update objects which have scheduled themselves for updates private int m_update_presences = 1; // Update scene presence movements private int m_update_events = 1; private int m_update_backup = 200; @@ -979,28 +980,7 @@ namespace OpenSim.Region.Framework.Scenes maintc = Environment.TickCount; TimeSpan SinceLastFrame = DateTime.Now - m_lastupdate; - // Aquire a lock so only one update call happens at once - //updateLock.WaitOne(); float physicsFPS = 0; - //m_log.Info("sadfadf" + m_neighbours.Count.ToString()); - int agentsInScene = m_sceneGraph.GetRootAgentCount() + m_sceneGraph.GetChildAgentCount(); - - if (agentsInScene > 21) - { - if (m_update_entities == 1) - { - m_update_entities = 5; - StatsReporter.SetUpdateMS(6000); - } - } - else - { - if (m_update_entities == 5) - { - m_update_entities = 1; - StatsReporter.SetUpdateMS(3000); - } - } frameMS = Environment.TickCount; try @@ -1013,30 +993,17 @@ namespace OpenSim.Region.Framework.Scenes m_frame = 0; otherMS = Environment.TickCount; - // run through all entities looking for updates (slow) - if (m_frame % m_update_entities == 0) - { - /* // Adam Experimental - if (m_updateEntitiesThread == null) - { - m_updateEntitiesThread = new Thread(m_sceneGraph.UpdateEntities); - ThreadTracker.Add(m_updateEntitiesThread); - } - - if (m_updateEntitiesThread.ThreadState == ThreadState.Stopped) - m_updateEntitiesThread.Start(); - */ - - m_sceneGraph.UpdateEntities(); - } + // Check if any objects have reached their targets + CheckAtTargets(); + + // Update SceneObjectGroups that have scheduled themselves for updates + // Objects queue their updates onto all scene presences + if (m_frame % m_update_objects == 0) + m_sceneGraph.UpdateObjectGroups(); - // run through entities that have scheduled themselves for - // updates looking for updates(faster) - if (m_frame % m_update_entitiesquick == 0) - m_sceneGraph.ProcessUpdates(); - - // Run through scenepresences looking for updates + // Run through all ScenePresences looking for updates + // Presence updates and queued object updates for each presence are sent to clients if (m_frame % m_update_presences == 0) m_sceneGraph.UpdatePresences(); @@ -1140,6 +1107,31 @@ namespace OpenSim.Region.Framework.Scenes } } + + public void AddGroupTarget(SceneObjectGroup grp) + { + lock(m_groupsWithTargets) + m_groupsWithTargets[grp.UUID] = grp; + } + + public void RemoveGroupTarget(SceneObjectGroup grp) + { + lock(m_groupsWithTargets) + m_groupsWithTargets.Remove(grp.UUID); + } + + private void CheckAtTargets() + { + lock (m_groupsWithTargets) + { + foreach (KeyValuePair kvp in m_groupsWithTargets) + { + kvp.Value.checkAtTargets(); + } + } + } + + /// /// Send out simstats data to all clients /// diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 54ac792..9cd2247 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -77,7 +77,7 @@ namespace OpenSim.Region.Framework.Scenes protected RegionInfo m_regInfo; protected Scene m_parentScene; - protected Dictionary m_updateList = new Dictionary(); + protected Dictionary m_updateList = new Dictionary(); protected int m_numRootAgents = 0; protected int m_numPrim = 0; protected int m_numChildAgents = 0; @@ -155,16 +155,6 @@ namespace OpenSim.Region.Framework.Scenes } } - protected internal void UpdateEntities() - { - List updateEntities = GetEntities(); - - foreach (EntityBase entity in updateEntities) - { - entity.Update(); - } - } - protected internal void UpdatePresences() { List updateScenePresences = GetScenePresences(); @@ -365,12 +355,12 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Add an entity to the list of prims to process on the next update + /// Add an object to the list of prims to process on the next update /// /// - /// A + /// A /// - protected internal void AddToUpdateList(EntityBase obj) + protected internal void AddToUpdateList(SceneObjectGroup obj) { lock (m_updateList) { @@ -381,18 +371,18 @@ namespace OpenSim.Region.Framework.Scenes /// /// Process all pending updates /// - protected internal void ProcessUpdates() + protected internal void UpdateObjectGroups() { - Dictionary updates; + Dictionary updates; // Some updates add more updates to the updateList. // Get the current list of updates and clear the list before iterating lock (m_updateList) { - updates = new Dictionary(m_updateList); + updates = new Dictionary(m_updateList); m_updateList.Clear(); } - // Go through all timers - foreach (KeyValuePair kvp in updates) + // Go through all updates + foreach (KeyValuePair kvp in updates) { // Don't abort the whole update if one entity happens to give us an exception. try diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 6a10618..d4cef7d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1234,6 +1234,7 @@ namespace OpenSim.Region.Framework.Scenes { lock (m_targets) m_targets.Clear(); + m_scene.RemoveGroupTarget(this); } ScheduleGroupForFullUpdate(); @@ -1864,12 +1865,6 @@ namespace OpenSim.Region.Framework.Scenes m_rootPart.UpdateFlag = 1; lastPhysGroupPos = AbsolutePosition; } - //foreach (SceneObjectPart part in m_parts.Values) - //{ - //if (part.UpdateFlag == 0) part.UpdateFlag = 1; - //} - - checkAtTargets(); if (UsePhysics && ((Math.Abs(lastPhysGroupRot.W - GroupRotation.W) > 0.1) || (Math.Abs(lastPhysGroupRot.X - GroupRotation.X) > 0.1) @@ -3114,6 +3109,7 @@ namespace OpenSim.Region.Framework.Scenes { m_targets.Add(handle, waypoint); } + m_scene.AddGroupTarget(this); return (int)handle; } @@ -3121,12 +3117,13 @@ namespace OpenSim.Region.Framework.Scenes { lock (m_targets) { - if (m_targets.ContainsKey((uint)handle)) - m_targets.Remove((uint)handle); + m_targets.Remove((uint)handle); + if (m_targets.Count == 0) + m_scene.RemoveGroupTarget(this); } } - private void checkAtTargets() + public void checkAtTargets() { if (m_scriptListens_atTarget || m_scriptListens_notAtTarget) { -- cgit v1.1 From bea13e37090bd2daa44c2202634c8e2fa81c203b Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 14 Oct 2009 11:01:46 -0700 Subject: Setting changeY in border crossing. --- OpenSim/Region/Framework/Scenes/Scene.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 0f351ce..04eb93f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1804,6 +1804,7 @@ namespace OpenSim.Region.Framework.Scenes if (crossedBordery.BorderLine.Z > 0) { pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); + changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); } else pos.Y = ((pos.Y + Constants.RegionSize)); -- cgit v1.1