diff --git a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs index 6357d4f19e..166cb981fa 100644 --- a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs +++ b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs @@ -67,6 +67,8 @@ namespace OpenSim.Region.OptionalModules.Materials public Dictionary m_MaterialsRefCount = new Dictionary(); private Dictionary m_changed = new Dictionary(); + private Queue delayedDelete = new Queue(); + private bool m_storeBusy; public void Initialise(IConfigSource source) { @@ -126,13 +128,37 @@ namespace OpenSim.Region.OptionalModules.Materials private void EventManager_OnBackup(ISimulationDataService datastore, bool forcedBackup) { - List toStore; + List toStore = null; lock (materialslock) { - if(m_changed.Count == 0) + if(m_storeBusy && !forcedBackup) return; + if(m_changed.Count == 0) + { + if(forcedBackup) + return; + + UUID id; + int throttle = 0; + while(delayedDelete.Count > 0 && throttle < 5) + { + id = delayedDelete.Dequeue(); + if (m_Materials.ContainsKey(id)) + { + if (m_MaterialsRefCount[id] <= 0) + { + m_Materials.Remove(id); + m_MaterialsRefCount.Remove(id); + m_cache.Expire(id.ToString()); + ++throttle; + } + } + } + return; + } + if (forcedBackup) { toStore = new List(m_changed.Keys); @@ -141,7 +167,7 @@ namespace OpenSim.Region.OptionalModules.Materials else { toStore = new List(); - double storetime = Util.GetTimeStamp() - 60.0; + double storetime = Util.GetTimeStamp() - 30.0; foreach(KeyValuePair kvp in m_changed) { if(kvp.Value < storetime) @@ -158,6 +184,7 @@ namespace OpenSim.Region.OptionalModules.Materials if(toStore.Count > 0) { + m_storeBusy = true; if (forcedBackup) { foreach (FaceMaterial fm in toStore) @@ -165,6 +192,7 @@ namespace OpenSim.Region.OptionalModules.Materials AssetBase a = MakeAsset(fm, false); m_scene.AssetService.Store(a); } + m_storeBusy = false; } else { @@ -175,6 +203,7 @@ namespace OpenSim.Region.OptionalModules.Materials AssetBase a = MakeAsset(fm, false); m_scene.AssetService.Store(a); } + m_storeBusy = false; }); } } @@ -190,16 +219,18 @@ namespace OpenSim.Region.OptionalModules.Materials private void EventManager_OnObjectDeleteFromScene(SceneObjectGroup obj) { foreach (var part in obj.Parts) + { if (part != null) RemoveMaterialsInPart(part); + } } private void OnRegisterCaps(OpenMetaverse.UUID agentID, OpenSim.Framework.Capabilities.Caps caps) { - string capsBase = "/CAPS/" + caps.CapsObjectPath; + string capsBase = "/CAPS/" + caps.CapsObjectPath + "/"; IRequestHandler renderMaterialsPostHandler - = new RestStreamHandler("POST", capsBase + "/", + = new RestStreamHandler("POST", capsBase, (request, path, param, httpRequest, httpResponse) => RenderMaterialsPostCap(request, agentID), "RenderMaterials", null); @@ -210,7 +241,7 @@ namespace OpenSim.Region.OptionalModules.Materials // handler normally and then add a GET handler via MainServer IRequestHandler renderMaterialsGetHandler - = new RestStreamHandler("GET", capsBase + "/", + = new RestStreamHandler("GET", capsBase, (request, path, param, httpRequest, httpResponse) => RenderMaterialsGetCap(request), "RenderMaterials", null); @@ -218,7 +249,7 @@ namespace OpenSim.Region.OptionalModules.Materials // materials viewer seems to use either POST or PUT, so assign POST handler for PUT as well IRequestHandler renderMaterialsPutHandler - = new RestStreamHandler("PUT", capsBase + "/", + = new RestStreamHandler("PUT", capsBase, (request, path, param, httpRequest, httpResponse) => RenderMaterialsPutCap(request, agentID), "RenderMaterials", null); @@ -439,19 +470,11 @@ namespace OpenSim.Region.OptionalModules.Materials lock (materialslock) { - if(!m_Materials.ContainsKey(id)) - return; - else + if(m_Materials.ContainsKey(id)) { m_MaterialsRefCount[id]--; - if(m_MaterialsRefCount[id] <= 0) - { - FaceMaterial oldFaceMat = m_Materials[id]; - m_changed.Remove(oldFaceMat); - m_Materials.Remove(id); - m_MaterialsRefCount.Remove(id); - m_cache.Expire(id.ToString()); - } + if (m_MaterialsRefCount[id] <= 0) + delayedDelete.Enqueue(id); } } }