diff options
author | Melanie | 2009-09-02 05:04:24 +0100 |
---|---|---|
committer | Melanie | 2009-09-02 05:04:24 +0100 |
commit | 994c5e20949139542d11222b0b85721956cf611e (patch) | |
tree | 1d7e57278607f5c9df6eb29be61c8da315f8c2a7 | |
parent | Thank you, dslake, for a set of patches to improve OpenSim startup (diff) | |
download | opensim-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.cs | 80 |
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 | ||