aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorMelanie2009-09-02 05:04:24 +0100
committerMelanie2009-09-02 05:04:24 +0100
commit994c5e20949139542d11222b0b85721956cf611e (patch)
tree1d7e57278607f5c9df6eb29be61c8da315f8c2a7
parentThank you, dslake, for a set of patches to improve OpenSim startup (diff)
downloadopensim-SC-994c5e20949139542d11222b0b85721956cf611e.zip
opensim-SC-994c5e20949139542d11222b0b85721956cf611e.tar.gz
opensim-SC-994c5e20949139542d11222b0b85721956cf611e.tar.bz2
opensim-SC-994c5e20949139542d11222b0b85721956cf611e.tar.xz
Prevent the Viewer's threaded inventory retrieval causing a OOM and overload
the inventory server by serializing upstream requests.
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/Capabilities/Caps.cs80
1 files changed, 45 insertions, 35 deletions
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
106 private Queue<string> m_capsEventQueue = new Queue<string>(); 106 private Queue<string> m_capsEventQueue = new Queue<string>();
107 private bool m_dumpAssetsToFile; 107 private bool m_dumpAssetsToFile;
108 private string m_regionName; 108 private string m_regionName;
109 private object m_fetchLock = new Object();
109 110
110 public bool SSLCaps 111 public bool SSLCaps
111 { 112 {
@@ -368,15 +369,21 @@ namespace OpenSim.Framework.Capabilities
368 369
369 public string FetchInventoryDescendentsRequest(string request, string path, string param,OSHttpRequest httpRequest, OSHttpResponse httpResponse) 370 public string FetchInventoryDescendentsRequest(string request, string path, string param,OSHttpRequest httpRequest, OSHttpResponse httpResponse)
370 { 371 {
371 // m_log.Debug("[CAPS]: FetchInventoryDescendentsRequest in region: " + m_regionName + "request is "+request); 372 // nasty temporary hack here, the linden client falsely
372 373 // identifies the uuid 00000000-0000-0000-0000-000000000000
373 // nasty temporary hack here, the linden client falsely identifies the uuid 00000000-0000-0000-0000-000000000000 as a string which breaks us 374 // as a string which breaks us
375 //
374 // correctly mark it as a uuid 376 // correctly mark it as a uuid
377 //
375 request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>"); 378 request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>");
376 379
377 // another hack <integer>1</integer> results in a System.ArgumentException: Object type System.Int32 cannot be converted to target type: System.Boolean 380 // another hack <integer>1</integer> results in a
381 // System.ArgumentException: Object type System.Int32 cannot
382 // be converted to target type: System.Boolean
383 //
378 request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>"); 384 request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>");
379 request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>"); 385 request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>");
386
380 Hashtable hash = new Hashtable(); 387 Hashtable hash = new Hashtable();
381 try 388 try
382 { 389 {
@@ -391,46 +398,49 @@ namespace OpenSim.Framework.Capabilities
391 ArrayList foldersrequested = (ArrayList)hash["folders"]; 398 ArrayList foldersrequested = (ArrayList)hash["folders"];
392 399
393 string response = ""; 400 string response = "";
394 for (int i = 0; i < foldersrequested.Count; i++) 401 lock (m_fetchLock)
395 { 402 {
396 string inventoryitemstr = ""; 403 for (int i = 0; i < foldersrequested.Count; i++)
397 Hashtable inventoryhash = (Hashtable)foldersrequested[i]; 404 {
405 string inventoryitemstr = "";
406 Hashtable inventoryhash = (Hashtable)foldersrequested[i];
398 407
399 LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); 408 LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
409
410 try{
411 LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
412 }
413 catch(Exception e)
414 {
415 m_log.Debug("[CAPS]: caught exception doing OSD deserialize" + e);
416 }
417 LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);
418
419 inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
420 inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
421 inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");
422
423 response += inventoryitemstr;
424 }
400 425
401 try{ 426
402 LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); 427 if (response.Length == 0)
428 {
429 // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants.
430 // Therefore, I'm concluding that the client only has so many threads available to do requests
431 // and when a thread stalls.. is stays stalled.
432 // Therefore we need to return something valid
433 response = "<llsd><map><key>folders</key><array /></map></llsd>";
403 } 434 }
404 catch(Exception e) 435 else
405 { 436 {
406 m_log.Debug("[CAPS]: caught exception doing OSD deserialize" + e); 437 response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
407 } 438 }
408 LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);
409 439
410 inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); 440 //m_log.DebugFormat("[CAPS]: Replying to CAPS fetch inventory request with following xml");
411 inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", ""); 441 //m_log.Debug("[CAPS] "+response);
412 inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");
413 442
414 response += inventoryitemstr;
415 }
416
417
418 if (response.Length == 0)
419 {
420 // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants.
421 // Therefore, I'm concluding that the client only has so many threads available to do requests
422 // and when a thread stalls.. is stays stalled.
423 // Therefore we need to return something valid
424 response = "<llsd><map><key>folders</key><array /></map></llsd>";
425 } 443 }
426 else
427 {
428 response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
429 }
430
431 //m_log.DebugFormat("[CAPS]: Replying to CAPS fetch inventory request with following xml");
432 //m_log.Debug("[CAPS] "+response);
433
434 return response; 444 return response;
435 } 445 }
436 446