From 994c5e20949139542d11222b0b85721956cf611e Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 2 Sep 2009 05:04:24 +0100 Subject: Prevent the Viewer's threaded inventory retrieval causing a OOM and overload the inventory server by serializing upstream requests. --- OpenSim/Framework/Capabilities/Caps.cs | 80 +++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 35 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Capabilities/Caps.cs b/OpenSim/Framework/Capabilities/Caps.cs index c5560b8..721d9ad 100644 --- a/OpenSim/Framework/Capabilities/Caps.cs +++ b/OpenSim/Framework/Capabilities/Caps.cs @@ -106,6 +106,7 @@ namespace OpenSim.Framework.Capabilities private Queue m_capsEventQueue = new Queue(); private bool m_dumpAssetsToFile; private string m_regionName; + private object m_fetchLock = new Object(); public bool SSLCaps { @@ -368,15 +369,21 @@ namespace OpenSim.Framework.Capabilities public string FetchInventoryDescendentsRequest(string request, string path, string param,OSHttpRequest httpRequest, OSHttpResponse httpResponse) { - // m_log.Debug("[CAPS]: FetchInventoryDescendentsRequest in region: " + m_regionName + "request is "+request); - - // nasty temporary hack here, the linden client falsely identifies the uuid 00000000-0000-0000-0000-000000000000 as a string which breaks us + // nasty temporary hack here, the linden client falsely + // identifies the uuid 00000000-0000-0000-0000-000000000000 + // as a string which breaks us + // // correctly mark it as a uuid + // request = request.Replace("00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000000"); - // another hack 1 results in a System.ArgumentException: Object type System.Int32 cannot be converted to target type: System.Boolean + // another hack 1 results in a + // System.ArgumentException: Object type System.Int32 cannot + // be converted to target type: System.Boolean + // request = request.Replace("fetch_folders0", "fetch_folders0"); request = request.Replace("fetch_folders1", "fetch_folders1"); + Hashtable hash = new Hashtable(); try { @@ -391,46 +398,49 @@ namespace OpenSim.Framework.Capabilities ArrayList foldersrequested = (ArrayList)hash["folders"]; string response = ""; - for (int i = 0; i < foldersrequested.Count; i++) + lock (m_fetchLock) { - string inventoryitemstr = ""; - Hashtable inventoryhash = (Hashtable)foldersrequested[i]; + for (int i = 0; i < foldersrequested.Count; i++) + { + string inventoryitemstr = ""; + Hashtable inventoryhash = (Hashtable)foldersrequested[i]; - LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); + LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); + + try{ + LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); + } + catch(Exception e) + { + m_log.Debug("[CAPS]: caught exception doing OSD deserialize" + e); + } + LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); + + inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); + inventoryitemstr = inventoryitemstr.Replace("folders", ""); + inventoryitemstr = inventoryitemstr.Replace("", ""); + + response += inventoryitemstr; + } - try{ - LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); + + if (response.Length == 0) + { + // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants. + // Therefore, I'm concluding that the client only has so many threads available to do requests + // and when a thread stalls.. is stays stalled. + // Therefore we need to return something valid + response = "folders"; } - catch(Exception e) + else { - m_log.Debug("[CAPS]: caught exception doing OSD deserialize" + e); + response = "folders" + response + ""; } - LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); - inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); - inventoryitemstr = inventoryitemstr.Replace("folders", ""); - inventoryitemstr = inventoryitemstr.Replace("", ""); + //m_log.DebugFormat("[CAPS]: Replying to CAPS fetch inventory request with following xml"); + //m_log.Debug("[CAPS] "+response); - response += inventoryitemstr; - } - - - if (response.Length == 0) - { - // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants. - // Therefore, I'm concluding that the client only has so many threads available to do requests - // and when a thread stalls.. is stays stalled. - // Therefore we need to return something valid - response = "folders"; } - else - { - response = "folders" + response + ""; - } - - //m_log.DebugFormat("[CAPS]: Replying to CAPS fetch inventory request with following xml"); - //m_log.Debug("[CAPS] "+response); - return response; } -- cgit v1.1