mantis 8647: try to not lose materials on fast objects take, but without changing a lot of files

master
UbitUmarov 2020-01-19 00:31:28 +00:00
parent 8db2ddb07f
commit 28db80f100
1 changed files with 41 additions and 18 deletions

View File

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