diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/Caps')
9 files changed, 431 insertions, 341 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 6f5775a..b8d423f 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs | |||
@@ -503,7 +503,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
503 | errorResponse.state = "error"; | 503 | errorResponse.state = "error"; |
504 | errorResponse.error = resperror; | 504 | errorResponse.error = resperror; |
505 | return errorResponse; | 505 | return errorResponse; |
506 | break; | ||
507 | case FileAgentInventoryState.waitUpload: | 506 | case FileAgentInventoryState.waitUpload: |
508 | // todo stop current uploader server | 507 | // todo stop current uploader server |
509 | break; | 508 | break; |
@@ -1377,30 +1376,37 @@ namespace OpenSim.Region.ClientStack.Linden | |||
1377 | IOSHttpResponse httpResponse) | 1376 | IOSHttpResponse httpResponse) |
1378 | { | 1377 | { |
1379 | OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); | 1378 | OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); |
1380 | OSDMap resp = new OSDMap(); | ||
1381 | OSDArray object_ids = (OSDArray)req["object_ids"]; | 1379 | OSDArray object_ids = (OSDArray)req["object_ids"]; |
1382 | 1380 | ||
1383 | for (int i = 0 ; i < object_ids.Count ; i++) | 1381 | StringBuilder lsl = LLSDxmlEncode.Start(); |
1382 | |||
1383 | if(object_ids.Count == 0) | ||
1384 | LLSDxmlEncode.AddEmptyMap(lsl); | ||
1385 | else | ||
1384 | { | 1386 | { |
1385 | UUID uuid = object_ids[i].AsUUID(); | 1387 | LLSDxmlEncode.AddMap(lsl); |
1386 | 1388 | for (int i = 0 ; i < object_ids.Count ; i++) | |
1387 | SceneObjectPart obj = m_Scene.GetSceneObjectPart(uuid); | ||
1388 | if (obj != null) | ||
1389 | { | 1389 | { |
1390 | OSDMap object_data = new OSDMap(); | 1390 | UUID uuid = object_ids[i].AsUUID(); |
1391 | |||
1392 | SceneObjectPart obj = m_Scene.GetSceneObjectPart(uuid); | ||
1393 | if (obj != null) | ||
1394 | { | ||
1395 | LLSDxmlEncode.AddMap(uuid.ToString(),lsl); | ||
1391 | 1396 | ||
1392 | object_data["PhysicsShapeType"] = obj.PhysicsShapeType; | 1397 | LLSDxmlEncode.AddElem("PhysicsShapeType", obj.PhysicsShapeType, lsl); |
1393 | object_data["Density"] = obj.Density; | 1398 | LLSDxmlEncode.AddElem("Density", obj.Density, lsl); |
1394 | object_data["Friction"] = obj.Friction; | 1399 | LLSDxmlEncode.AddElem("Friction", obj.Friction, lsl); |
1395 | object_data["Restitution"] = obj.Restitution; | 1400 | LLSDxmlEncode.AddElem("Restitution", obj.Restitution, lsl); |
1396 | object_data["GravityMultiplier"] = obj.GravityModifier; | 1401 | LLSDxmlEncode.AddElem("GravityMultiplier", obj.GravityModifier, lsl); |
1397 | 1402 | ||
1398 | resp[uuid.ToString()] = object_data; | 1403 | LLSDxmlEncode.AddEndMap(lsl); |
1404 | } | ||
1405 | LLSDxmlEncode.AddEndMap(lsl); | ||
1399 | } | 1406 | } |
1400 | } | 1407 | } |
1401 | 1408 | ||
1402 | string response = OSDParser.SerializeLLSDXmlString(resp); | 1409 | return LLSDxmlEncode.End(lsl); |
1403 | return response; | ||
1404 | } | 1410 | } |
1405 | 1411 | ||
1406 | public string GetObjectCost(string request, string path, | 1412 | public string GetObjectCost(string request, string path, |
@@ -1408,47 +1414,59 @@ namespace OpenSim.Region.ClientStack.Linden | |||
1408 | IOSHttpResponse httpResponse) | 1414 | IOSHttpResponse httpResponse) |
1409 | { | 1415 | { |
1410 | OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); | 1416 | OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); |
1411 | OSDMap resp = new OSDMap(); | ||
1412 | |||
1413 | OSDArray object_ids = (OSDArray)req["object_ids"]; | 1417 | OSDArray object_ids = (OSDArray)req["object_ids"]; |
1414 | 1418 | ||
1415 | for (int i = 0; i < object_ids.Count; i++) | 1419 | StringBuilder lsl = LLSDxmlEncode.Start(512); |
1420 | |||
1421 | if(object_ids.Count == 0) | ||
1422 | LLSDxmlEncode.AddEmptyMap(lsl); | ||
1423 | else | ||
1416 | { | 1424 | { |
1417 | UUID uuid = object_ids[i].AsUUID(); | 1425 | bool haveone = false; |
1426 | LLSDxmlEncode.AddMap(lsl); | ||
1427 | for (int i = 0; i < object_ids.Count; i++) | ||
1428 | { | ||
1429 | UUID uuid = object_ids[i].AsUUID(); | ||
1418 | 1430 | ||
1419 | SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid); | 1431 | SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid); |
1420 | SceneObjectGroup grp = null; | 1432 | SceneObjectGroup grp = null; |
1421 | if (part != null) | 1433 | if (part != null) |
1422 | grp = part.ParentGroup; | 1434 | grp = part.ParentGroup; |
1423 | if (grp != null) | 1435 | if (grp != null) |
1436 | { | ||
1437 | haveone = true; | ||
1438 | float linksetCost; | ||
1439 | float linksetPhysCost; | ||
1440 | float partCost; | ||
1441 | float partPhysCost; | ||
1442 | |||
1443 | grp.GetResourcesCosts(part,out linksetCost,out linksetPhysCost,out partCost,out partPhysCost); | ||
1444 | |||
1445 | LLSDxmlEncode.AddMap(uuid.ToString(), lsl); | ||
1446 | |||
1447 | LLSDxmlEncode.AddElem("linked_set_resource_cost", linksetCost, lsl); | ||
1448 | LLSDxmlEncode.AddElem("resource_cost", partCost, lsl); | ||
1449 | LLSDxmlEncode.AddElem("physics_cost", partPhysCost, lsl); | ||
1450 | LLSDxmlEncode.AddElem("linked_set_physics_cost", linksetPhysCost, lsl); | ||
1451 | LLSDxmlEncode.AddElem("resource_limiting_type", "legacy", lsl); | ||
1452 | |||
1453 | LLSDxmlEncode.AddEndMap(lsl); | ||
1454 | } | ||
1455 | } | ||
1456 | if(!haveone) | ||
1424 | { | 1457 | { |
1425 | float linksetCost; | 1458 | LLSDxmlEncode.AddMap(UUID.Zero.ToString(), lsl); |
1426 | float linksetPhysCost; | 1459 | LLSDxmlEncode.AddElem("linked_set_resource_cost", 0, lsl); |
1427 | float partCost; | 1460 | LLSDxmlEncode.AddElem("resource_cost", 0, lsl); |
1428 | float partPhysCost; | 1461 | LLSDxmlEncode.AddElem("physics_cost", 0, lsl); |
1429 | 1462 | LLSDxmlEncode.AddElem("linked_set_physics_cost", 0, lsl); | |
1430 | grp.GetResourcesCosts(part,out linksetCost,out linksetPhysCost,out partCost,out partPhysCost); | 1463 | LLSDxmlEncode.AddElem("resource_limiting_type", "legacy", lsl); |
1431 | 1464 | LLSDxmlEncode.AddEndMap(lsl); | |
1432 | OSDMap object_data = new OSDMap(); | ||
1433 | object_data["linked_set_resource_cost"] = linksetCost; | ||
1434 | object_data["resource_cost"] = partCost; | ||
1435 | object_data["physics_cost"] = partPhysCost; | ||
1436 | object_data["linked_set_physics_cost"] = linksetPhysCost; | ||
1437 | object_data["resource_limiting_type"] = "legacy"; | ||
1438 | resp[uuid.ToString()] = object_data; | ||
1439 | } | 1465 | } |
1466 | LLSDxmlEncode.AddEndMap(lsl); | ||
1440 | } | 1467 | } |
1441 | if(resp.Count == 0) | 1468 | |
1442 | { | 1469 | return LLSDxmlEncode.End(lsl); |
1443 | OSDMap object_data = new OSDMap(); | ||
1444 | object_data["linked_set_resource_cost"] = 0; | ||
1445 | object_data["resource_cost"] = 0; | ||
1446 | object_data["physics_cost"] = 0; | ||
1447 | object_data["linked_set_physics_cost"] = 0; | ||
1448 | resp[UUID.Zero.ToString()] = object_data; | ||
1449 | } | ||
1450 | string response = OSDParser.SerializeLLSDXmlString(resp); | ||
1451 | return response; | ||
1452 | } | 1470 | } |
1453 | 1471 | ||
1454 | public string ResourceCostSelected(string request, string path, | 1472 | public string ResourceCostSelected(string request, string path, |
@@ -1456,8 +1474,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
1456 | IOSHttpResponse httpResponse) | 1474 | IOSHttpResponse httpResponse) |
1457 | { | 1475 | { |
1458 | OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); | 1476 | OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); |
1459 | OSDMap resp = new OSDMap(); | ||
1460 | |||
1461 | 1477 | ||
1462 | float phys=0; | 1478 | float phys=0; |
1463 | float stream=0; | 1479 | float stream=0; |
@@ -1508,16 +1524,21 @@ namespace OpenSim.Region.ClientStack.Linden | |||
1508 | } | 1524 | } |
1509 | } | 1525 | } |
1510 | 1526 | ||
1511 | OSDMap object_data = new OSDMap(); | 1527 | StringBuilder lsl = LLSDxmlEncode.Start(); |
1528 | LLSDxmlEncode.AddMap(lsl); | ||
1529 | |||
1530 | LLSDxmlEncode.AddMap("selected", lsl); | ||
1512 | 1531 | ||
1513 | object_data["physics"] = phys; | 1532 | LLSDxmlEncode.AddElem("physics", phys, lsl); |
1514 | object_data["streaming"] = stream; | 1533 | LLSDxmlEncode.AddElem("streaming", stream, lsl); |
1515 | object_data["simulation"] = simul; | 1534 | LLSDxmlEncode.AddElem("simulation", simul, lsl); |
1516 | 1535 | ||
1517 | resp["selected"] = object_data; | 1536 | LLSDxmlEncode.AddEndMap(lsl); |
1537 | LLSDxmlEncode.AddEndMap(lsl); | ||
1538 | |||
1518 | // resp["transaction_id"] = "undef"; | 1539 | // resp["transaction_id"] = "undef"; |
1519 | string response = OSDParser.SerializeLLSDXmlString(resp); | 1540 | return LLSDxmlEncode.End(lsl); |
1520 | return response; | 1541 | |
1521 | } | 1542 | } |
1522 | 1543 | ||
1523 | public string UpdateAgentInformation(string request, string path, | 1544 | public string UpdateAgentInformation(string request, string path, |
@@ -1820,57 +1841,53 @@ namespace OpenSim.Region.ClientStack.Linden | |||
1820 | return ""; | 1841 | return ""; |
1821 | } | 1842 | } |
1822 | 1843 | ||
1844 | // Full content request | ||
1845 | httpResponse.StatusCode = (int)System.Net.HttpStatusCode.OK; | ||
1846 | //httpResponse.ContentLength = ??; | ||
1847 | httpResponse.ContentType = "application/llsd+xml"; | ||
1848 | |||
1823 | NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); | 1849 | NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); |
1824 | string[] ids = query.GetValues("ids"); | 1850 | string[] ids = query.GetValues("ids"); |
1825 | 1851 | ||
1826 | Dictionary<UUID,string> names = m_UserManager.GetUsersNames(ids); | 1852 | Dictionary<UUID,string> names = m_UserManager.GetUsersNames(ids); |
1827 | 1853 | ||
1828 | OSDMap osdReply = new OSDMap(); | 1854 | StringBuilder lsl = LLSDxmlEncode.Start(names.Count * 256 + 256); |
1829 | OSDArray agents = new OSDArray(); | 1855 | LLSDxmlEncode.AddMap(lsl); |
1830 | 1856 | if(names.Count == 0) | |
1831 | osdReply["agents"] = agents; | 1857 | LLSDxmlEncode.AddEmptyArray("agents", lsl); |
1832 | foreach (KeyValuePair<UUID,string> kvp in names) | 1858 | else |
1833 | { | 1859 | { |
1834 | if (string.IsNullOrEmpty(kvp.Value)) | 1860 | LLSDxmlEncode.AddArray("agents", lsl); |
1835 | continue; | 1861 | |
1836 | if(kvp.Key == UUID.Zero) | 1862 | foreach (KeyValuePair<UUID,string> kvp in names) |
1837 | continue; | 1863 | { |
1864 | if (string.IsNullOrEmpty(kvp.Value)) | ||
1865 | continue; | ||
1866 | if(kvp.Key == UUID.Zero) | ||
1867 | continue; | ||
1838 | 1868 | ||
1839 | string[] parts = kvp.Value.Split(new char[] {' '}); | 1869 | string[] parts = kvp.Value.Split(new char[] {' '}); |
1840 | OSDMap osdname = new OSDMap(); | ||
1841 | 1870 | ||
1842 | // dont tell about unknown users, we can't send them back on Bad either | 1871 | // dont tell about unknown users, we can't send them back on Bad either |
1843 | if(parts[0] == "Unknown") | 1872 | if(parts[0] == "Unknown") |
1844 | continue; | 1873 | continue; |
1845 | /* | 1874 | |
1846 | if(parts[0] == "Unknown") | 1875 | LLSDxmlEncode.AddMap(lsl); |
1847 | { | 1876 | LLSDxmlEncode.AddElem("display_name_next_update", DateTime.UtcNow.AddDays(8), lsl); |
1848 | osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddHours(1)); | 1877 | LLSDxmlEncode.AddElem("display_name_expires", DateTime.UtcNow.AddMonths(1), lsl); |
1849 | osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddHours(2)); | 1878 | LLSDxmlEncode.AddElem("display_name", kvp.Value, lsl); |
1879 | LLSDxmlEncode.AddElem("legacy_first_name", parts[0], lsl); | ||
1880 | LLSDxmlEncode.AddElem("legacy_last_name", parts[1], lsl); | ||
1881 | LLSDxmlEncode.AddElem("username", kvp.Value, lsl); | ||
1882 | LLSDxmlEncode.AddElem("id", kvp.Key, lsl); | ||
1883 | LLSDxmlEncode.AddElem("is_display_name_default", true, lsl); | ||
1884 | LLSDxmlEncode.AddEndMap(lsl); | ||
1850 | } | 1885 | } |
1851 | else | 1886 | LLSDxmlEncode.AddEndArray(lsl); |
1852 | */ | ||
1853 | { | ||
1854 | osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddDays(8)); | ||
1855 | osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddMonths(1)); | ||
1856 | } | ||
1857 | osdname["display_name"] = OSD.FromString(kvp.Value); | ||
1858 | osdname["legacy_first_name"] = parts[0]; | ||
1859 | osdname["legacy_last_name"] = parts[1]; | ||
1860 | osdname["username"] = OSD.FromString(kvp.Value); | ||
1861 | osdname["id"] = OSD.FromUUID(kvp.Key); | ||
1862 | osdname["is_display_name_default"] = OSD.FromBoolean(true); | ||
1863 | |||
1864 | agents.Add(osdname); | ||
1865 | } | 1887 | } |
1866 | 1888 | ||
1867 | // Full content request | 1889 | LLSDxmlEncode.AddEndMap(lsl); |
1868 | httpResponse.StatusCode = (int)System.Net.HttpStatusCode.OK; | 1890 | return LLSDxmlEncode.End(lsl);; |
1869 | //httpResponse.ContentLength = ??; | ||
1870 | httpResponse.ContentType = "application/llsd+xml"; | ||
1871 | |||
1872 | string reply = OSDParser.SerializeLLSDXmlString(osdReply); | ||
1873 | return reply; | ||
1874 | } | 1891 | } |
1875 | } | 1892 | } |
1876 | 1893 | ||
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 7c9a1c4..442cc65 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs | |||
@@ -30,7 +30,7 @@ using System.Collections; | |||
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Net; | 31 | using System.Net; |
32 | using System.Reflection; | 32 | using System.Reflection; |
33 | using System.Threading; | 33 | using System.Text; |
34 | using log4net; | 34 | using log4net; |
35 | using Nini.Config; | 35 | using Nini.Config; |
36 | using Mono.Addins; | 36 | using Mono.Addins; |
@@ -44,7 +44,6 @@ using OpenSim.Framework.Servers; | |||
44 | using OpenSim.Framework.Servers.HttpServer; | 44 | using OpenSim.Framework.Servers.HttpServer; |
45 | using OpenSim.Region.Framework.Interfaces; | 45 | using OpenSim.Region.Framework.Interfaces; |
46 | using OpenSim.Region.Framework.Scenes; | 46 | using OpenSim.Region.Framework.Scenes; |
47 | using BlockingLLSDQueue = OpenSim.Framework.BlockingQueue<OpenMetaverse.StructuredData.OSD>; | ||
48 | using Caps=OpenSim.Framework.Capabilities.Caps; | 47 | using Caps=OpenSim.Framework.Capabilities.Caps; |
49 | 48 | ||
50 | namespace OpenSim.Region.ClientStack.Linden | 49 | namespace OpenSim.Region.ClientStack.Linden |
@@ -292,8 +291,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
292 | Queue<OSD> queue; | 291 | Queue<OSD> queue; |
293 | Random rnd = new Random(Environment.TickCount); | 292 | Random rnd = new Random(Environment.TickCount); |
294 | int nrnd = rnd.Next(30000000); | 293 | int nrnd = rnd.Next(30000000); |
295 | if (nrnd < 0) | ||
296 | nrnd = -nrnd; | ||
297 | 294 | ||
298 | lock (queues) | 295 | lock (queues) |
299 | { | 296 | { |
@@ -307,21 +304,11 @@ namespace OpenSim.Region.ClientStack.Linden | |||
307 | queue = new Queue<OSD>(); | 304 | queue = new Queue<OSD>(); |
308 | queues[agentID] = queue; | 305 | queues[agentID] = queue; |
309 | 306 | ||
310 | // push markers to handle old responses still waiting | ||
311 | // this will cost at most viewer getting two forced noevents | ||
312 | // even being a new queue better be safe | ||
313 | queue.Enqueue(null); | ||
314 | queue.Enqueue(null); // one should be enough | ||
315 | |||
316 | lock (m_AvatarQueueUUIDMapping) | 307 | lock (m_AvatarQueueUUIDMapping) |
317 | { | 308 | { |
318 | eventQueueGetUUID = UUID.Random(); | 309 | eventQueueGetUUID = UUID.Random(); |
319 | if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) | 310 | while(m_AvatarQueueUUIDMapping.ContainsKey(agentID)) |
320 | { | 311 | eventQueueGetUUID = UUID.Random(); |
321 | // oops this should not happen ? | ||
322 | m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID without a queue"); | ||
323 | eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; | ||
324 | } | ||
325 | m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); | 312 | m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); |
326 | } | 313 | } |
327 | lock (m_ids) | 314 | lock (m_ids) |
@@ -329,18 +316,14 @@ namespace OpenSim.Region.ClientStack.Linden | |||
329 | if (!m_ids.ContainsKey(agentID)) | 316 | if (!m_ids.ContainsKey(agentID)) |
330 | m_ids.Add(agentID, nrnd); | 317 | m_ids.Add(agentID, nrnd); |
331 | else | 318 | else |
332 | m_ids[agentID] = nrnd; | 319 | m_ids[agentID]++; |
333 | } | 320 | } |
334 | } | 321 | } |
335 | else | 322 | else |
336 | { | 323 | { |
337 | // push markers to handle old responses still waiting | ||
338 | // this will cost at most viewer getting two forced noevents | ||
339 | // even being a new queue better be safe | ||
340 | queue.Enqueue(null); | 324 | queue.Enqueue(null); |
341 | queue.Enqueue(null); // one should be enough | 325 | queue.Enqueue(null); // one should be enough |
342 | 326 | // reuse or not to reuse | |
343 | // reuse or not to reuse TODO FIX | ||
344 | lock (m_AvatarQueueUUIDMapping) | 327 | lock (m_AvatarQueueUUIDMapping) |
345 | { | 328 | { |
346 | // Reuse open queues. The client does! | 329 | // Reuse open queues. The client does! |
@@ -349,30 +332,39 @@ namespace OpenSim.Region.ClientStack.Linden | |||
349 | { | 332 | { |
350 | m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); | 333 | m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); |
351 | eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; | 334 | eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; |
335 | lock (m_ids) | ||
336 | { | ||
337 | // change to negative numbers so they are changed at end of sending first marker | ||
338 | // old data on a queue may be sent on a response for a new caps | ||
339 | // but at least will be sent with coerent IDs | ||
340 | if (!m_ids.ContainsKey(agentID)) | ||
341 | m_ids.Add(agentID, -nrnd); // should not happen | ||
342 | else | ||
343 | m_ids[agentID] = -m_ids[agentID]; | ||
344 | } | ||
352 | } | 345 | } |
353 | else | 346 | else |
354 | { | 347 | { |
355 | eventQueueGetUUID = UUID.Random(); | 348 | eventQueueGetUUID = UUID.Random(); |
349 | while(m_AvatarQueueUUIDMapping.ContainsKey(agentID)) | ||
350 | eventQueueGetUUID = UUID.Random(); | ||
356 | m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); | 351 | m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); |
357 | m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); | 352 | m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); |
353 | lock (m_ids) | ||
354 | { | ||
355 | if (!m_ids.ContainsKey(agentID)) | ||
356 | m_ids.Add(agentID, nrnd); | ||
357 | else | ||
358 | m_ids[agentID]++; | ||
359 | } | ||
358 | } | 360 | } |
359 | } | 361 | } |
360 | lock (m_ids) | ||
361 | { | ||
362 | // change to negative numbers so they are changed at end of sending first marker | ||
363 | // old data on a queue may be sent on a response for a new caps | ||
364 | // but at least will be sent with coerent IDs | ||
365 | if (!m_ids.ContainsKey(agentID)) | ||
366 | m_ids.Add(agentID, -nrnd); // should not happen | ||
367 | else | ||
368 | m_ids[agentID] = -m_ids[agentID]; | ||
369 | } | ||
370 | } | 362 | } |
371 | } | 363 | } |
372 | 364 | ||
373 | caps.RegisterPollHandler( | 365 | caps.RegisterPollHandler( |
374 | "EventQueueGet", | 366 | "EventQueueGet", |
375 | new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS)); | 367 | new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, Drop, agentID, SERVER_EQ_TIME_NO_EVENTS)); |
376 | } | 368 | } |
377 | 369 | ||
378 | public bool HasEvents(UUID requestID, UUID agentID) | 370 | public bool HasEvents(UUID requestID, UUID agentID) |
@@ -448,7 +440,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
448 | if (DebugLevel > 0) | 440 | if (DebugLevel > 0) |
449 | LogOutboundDebugMessage(element, pAgentId); | 441 | LogOutboundDebugMessage(element, pAgentId); |
450 | array.Add(element); | 442 | array.Add(element); |
451 | thisID++; | ||
452 | } | 443 | } |
453 | } | 444 | } |
454 | 445 | ||
@@ -465,8 +456,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
465 | { | 456 | { |
466 | Random rnd = new Random(Environment.TickCount); | 457 | Random rnd = new Random(Environment.TickCount); |
467 | thisID = rnd.Next(30000000); | 458 | thisID = rnd.Next(30000000); |
468 | if (thisID < 0) | ||
469 | thisID = -thisID; | ||
470 | } | 459 | } |
471 | 460 | ||
472 | lock (m_ids) | 461 | lock (m_ids) |
@@ -474,16 +463,19 @@ namespace OpenSim.Region.ClientStack.Linden | |||
474 | m_ids[pAgentId] = thisID + 1; | 463 | m_ids[pAgentId] = thisID + 1; |
475 | } | 464 | } |
476 | 465 | ||
466 | Hashtable responsedata; | ||
477 | // if there where no elements before a marker send a NoEvents | 467 | // if there where no elements before a marker send a NoEvents |
478 | if (array.Count == 0) | 468 | if (events == null) |
479 | return NoEvents(requestID, pAgentId); | 469 | { |
480 | 470 | return NoEvents(requestID, pAgentId); | |
481 | Hashtable responsedata = new Hashtable(); | 471 | } |
482 | responsedata["int_response_code"] = 200; | 472 | else |
483 | responsedata["content_type"] = "application/xml"; | 473 | { |
484 | responsedata["keepalive"] = false; | 474 | responsedata = new Hashtable(); |
485 | responsedata["reusecontext"] = false; | 475 | responsedata["int_response_code"] = 200; |
486 | responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events); | 476 | responsedata["content_type"] = "application/xml"; |
477 | responsedata["bin_response_data"] = Encoding.UTF8.GetBytes(OSDParser.SerializeLLSDXmlString(events)); | ||
478 | } | ||
487 | //m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", pAgentId, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]); | 479 | //m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", pAgentId, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]); |
488 | return responsedata; | 480 | return responsedata; |
489 | } | 481 | } |
@@ -493,13 +485,13 @@ namespace OpenSim.Region.ClientStack.Linden | |||
493 | Hashtable responsedata = new Hashtable(); | 485 | Hashtable responsedata = new Hashtable(); |
494 | responsedata["int_response_code"] = 502; | 486 | responsedata["int_response_code"] = 502; |
495 | responsedata["content_type"] = "text/plain"; | 487 | responsedata["content_type"] = "text/plain"; |
496 | responsedata["keepalive"] = false; | ||
497 | responsedata["reusecontext"] = false; | ||
498 | responsedata["str_response_string"] = "<llsd></llsd>"; | 488 | responsedata["str_response_string"] = "<llsd></llsd>"; |
499 | responsedata["error_status_text"] = "<llsd></llsd>"; | 489 | responsedata["error_status_text"] = "<llsd></llsd>"; |
500 | responsedata["http_protocol_version"] = "HTTP/1.0"; | 490 | responsedata["http_protocol_version"] = "HTTP/1.0"; |
491 | responsedata["keepalive"] = false; | ||
501 | return responsedata; | 492 | return responsedata; |
502 | } | 493 | } |
494 | |||
503 | /* this is not a event message | 495 | /* this is not a event message |
504 | public void DisableSimulator(ulong handle, UUID avatarID) | 496 | public void DisableSimulator(ulong handle, UUID avatarID) |
505 | { | 497 | { |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs index 461f776..52cfd48 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs | |||
@@ -43,16 +43,16 @@ namespace OpenSim.Region.ClientStack.Linden | |||
43 | private static byte[] ulongToByteArray(ulong uLongValue) | 43 | private static byte[] ulongToByteArray(ulong uLongValue) |
44 | { | 44 | { |
45 | // Reverse endianness of RegionHandle | 45 | // Reverse endianness of RegionHandle |
46 | return new byte[] | 46 | return new byte[8] |
47 | { | 47 | { |
48 | (byte)((uLongValue >> 56) % 256), | 48 | (byte)((uLongValue >> 56) & 0xff), |
49 | (byte)((uLongValue >> 48) % 256), | 49 | (byte)((uLongValue >> 48) & 0xff), |
50 | (byte)((uLongValue >> 40) % 256), | 50 | (byte)((uLongValue >> 40) & 0xff), |
51 | (byte)((uLongValue >> 32) % 256), | 51 | (byte)((uLongValue >> 32) & 0xff), |
52 | (byte)((uLongValue >> 24) % 256), | 52 | (byte)((uLongValue >> 24) & 0xff), |
53 | (byte)((uLongValue >> 16) % 256), | 53 | (byte)((uLongValue >> 16) & 0xff), |
54 | (byte)((uLongValue >> 8) % 256), | 54 | (byte)((uLongValue >> 8) & 0xff), |
55 | (byte)(uLongValue % 256) | 55 | (byte)(uLongValue & 0xff) |
56 | }; | 56 | }; |
57 | } | 57 | } |
58 | 58 | ||
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs index ee3f4f1..080cef9 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs | |||
@@ -29,6 +29,7 @@ using System; | |||
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Net; | 31 | using System.Net; |
32 | using System.Text; | ||
32 | using log4net.Config; | 33 | using log4net.Config; |
33 | using Nini.Config; | 34 | using Nini.Config; |
34 | using NUnit.Framework; | 35 | using NUnit.Framework; |
@@ -59,13 +60,12 @@ namespace OpenSim.Region.ClientStack.Linden.Tests | |||
59 | base.SetUp(); | 60 | base.SetUp(); |
60 | 61 | ||
61 | uint port = 9999; | 62 | uint port = 9999; |
62 | uint sslPort = 9998; | ||
63 | 63 | ||
64 | // This is an unfortunate bit of clean up we have to do because MainServer manages things through static | 64 | // This is an unfortunate bit of clean up we have to do because MainServer manages things through static |
65 | // variables and the VM is not restarted between tests. | 65 | // variables and the VM is not restarted between tests. |
66 | MainServer.RemoveHttpServer(port); | 66 | MainServer.RemoveHttpServer(port); |
67 | 67 | ||
68 | BaseHttpServer server = new BaseHttpServer(port, false, sslPort, ""); | 68 | BaseHttpServer server = new BaseHttpServer(port, false, "","",""); |
69 | MainServer.AddHttpServer(server); | 69 | MainServer.AddHttpServer(server); |
70 | MainServer.Instance = server; | 70 | MainServer.Instance = server; |
71 | 71 | ||
@@ -126,7 +126,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests | |||
126 | Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID); | 126 | Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID); |
127 | 127 | ||
128 | // initial queue as null events | 128 | // initial queue as null events |
129 | eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID); | 129 | // eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID); |
130 | if((int)eventsResponse["int_response_code"] != (int)HttpStatusCode.OK) | 130 | if((int)eventsResponse["int_response_code"] != (int)HttpStatusCode.OK) |
131 | { | 131 | { |
132 | eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID); | 132 | eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID); |
@@ -137,8 +137,11 @@ namespace OpenSim.Region.ClientStack.Linden.Tests | |||
137 | Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.OK)); | 137 | Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.OK)); |
138 | 138 | ||
139 | // Console.WriteLine("Response [{0}]", (string)eventsResponse["str_response_string"]); | 139 | // Console.WriteLine("Response [{0}]", (string)eventsResponse["str_response_string"]); |
140 | string data = String.Empty; | ||
141 | if(eventsResponse["bin_response_data"] != null) | ||
142 | data = Encoding.UTF8.GetString((byte[])eventsResponse["bin_response_data"]); | ||
140 | 143 | ||
141 | OSDMap rawOsd = (OSDMap)OSDParser.DeserializeLLSDXml((string)eventsResponse["str_response_string"]); | 144 | OSDMap rawOsd = (OSDMap)OSDParser.DeserializeLLSDXml(data); |
142 | OSDArray eventsOsd = (OSDArray)rawOsd["events"]; | 145 | OSDArray eventsOsd = (OSDArray)rawOsd["events"]; |
143 | 146 | ||
144 | bool foundUpdate = false; | 147 | bool foundUpdate = false; |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs index e0a11cc..eef9435 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs | |||
@@ -51,7 +51,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
51 | private Scene m_scene; | 51 | private Scene m_scene; |
52 | 52 | ||
53 | private IInventoryService m_inventoryService; | 53 | private IInventoryService m_inventoryService; |
54 | 54 | private ILibraryService m_LibraryService; | |
55 | private string m_fetchInventory2Url; | 55 | private string m_fetchInventory2Url; |
56 | 56 | ||
57 | #region ISharedRegionModule Members | 57 | #region ISharedRegionModule Members |
@@ -91,7 +91,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
91 | return; | 91 | return; |
92 | 92 | ||
93 | m_inventoryService = m_scene.InventoryService; | 93 | m_inventoryService = m_scene.InventoryService; |
94 | 94 | m_LibraryService = m_scene.LibraryService; | |
95 | m_scene.EventManager.OnRegisterCaps += RegisterCaps; | 95 | m_scene.EventManager.OnRegisterCaps += RegisterCaps; |
96 | } | 96 | } |
97 | 97 | ||
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs index ba917e39..5be75fa 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs | |||
@@ -28,17 +28,14 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Collections.Specialized; | 31 | using System.Collections.Concurrent; |
32 | using System.Reflection; | 32 | using System.Reflection; |
33 | using System.IO; | ||
34 | using System.Threading; | 33 | using System.Threading; |
35 | using System.Web; | ||
36 | using Mono.Addins; | 34 | using Mono.Addins; |
37 | using OpenSim.Framework.Monitoring; | 35 | using OpenSim.Framework.Monitoring; |
38 | using log4net; | 36 | using log4net; |
39 | using Nini.Config; | 37 | using Nini.Config; |
40 | using OpenMetaverse; | 38 | using OpenMetaverse; |
41 | using OpenMetaverse.StructuredData; | ||
42 | using OpenSim.Capabilities.Handlers; | 39 | using OpenSim.Capabilities.Handlers; |
43 | using OpenSim.Framework; | 40 | using OpenSim.Framework; |
44 | using OpenSim.Framework.Servers; | 41 | using OpenSim.Framework.Servers; |
@@ -57,7 +54,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
57 | // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 54 | // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
58 | 55 | ||
59 | private Scene m_scene; | 56 | private Scene m_scene; |
60 | private IAssetService m_AssetService; | ||
61 | private bool m_Enabled = true; | 57 | private bool m_Enabled = true; |
62 | private string m_URL; | 58 | private string m_URL; |
63 | 59 | ||
@@ -65,21 +61,19 @@ namespace OpenSim.Region.ClientStack.Linden | |||
65 | private string m_RedirectURL = null; | 61 | private string m_RedirectURL = null; |
66 | private string m_RedirectURL2 = null; | 62 | private string m_RedirectURL2 = null; |
67 | 63 | ||
68 | struct aPollRequest | 64 | class APollRequest |
69 | { | 65 | { |
70 | public PollServiceMeshEventArgs thepoll; | 66 | public PollServiceMeshEventArgs thepoll; |
71 | public UUID reqID; | 67 | public UUID reqID; |
72 | public Hashtable request; | 68 | public Hashtable request; |
73 | } | 69 | } |
74 | 70 | ||
75 | public class aPollResponse | 71 | public class APollResponse |
76 | { | 72 | { |
77 | public Hashtable response; | 73 | public Hashtable response; |
78 | public int bytes; | 74 | public int bytes; |
79 | public int lod; | ||
80 | } | 75 | } |
81 | 76 | ||
82 | |||
83 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 77 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
84 | 78 | ||
85 | private static GetMeshHandler m_getMeshHandler; | 79 | private static GetMeshHandler m_getMeshHandler; |
@@ -89,8 +83,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
89 | private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>(); | 83 | private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>(); |
90 | private static Thread[] m_workerThreads = null; | 84 | private static Thread[] m_workerThreads = null; |
91 | private static int m_NumberScenes = 0; | 85 | private static int m_NumberScenes = 0; |
92 | private static OpenSim.Framework.BlockingQueue<aPollRequest> m_queue = | 86 | private static BlockingCollection<APollRequest> m_queue = new BlockingCollection<APollRequest>(); |
93 | new OpenSim.Framework.BlockingQueue<aPollRequest>(); | ||
94 | 87 | ||
95 | private Dictionary<UUID, PollServiceMeshEventArgs> m_pollservices = new Dictionary<UUID, PollServiceMeshEventArgs>(); | 88 | private Dictionary<UUID, PollServiceMeshEventArgs> m_pollservices = new Dictionary<UUID, PollServiceMeshEventArgs>(); |
96 | 89 | ||
@@ -132,33 +125,35 @@ namespace OpenSim.Region.ClientStack.Linden | |||
132 | return; | 125 | return; |
133 | 126 | ||
134 | m_scene = pScene; | 127 | m_scene = pScene; |
135 | |||
136 | m_assetService = pScene.AssetService; | ||
137 | } | 128 | } |
138 | 129 | ||
139 | public void RemoveRegion(Scene scene) | 130 | public void RemoveRegion(Scene s) |
140 | { | 131 | { |
141 | if (!m_Enabled) | 132 | if (!m_Enabled) |
142 | return; | 133 | return; |
143 | 134 | ||
144 | m_scene.EventManager.OnRegisterCaps -= RegisterCaps; | 135 | s.EventManager.OnRegisterCaps -= RegisterCaps; |
145 | m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps; | 136 | s.EventManager.OnDeregisterCaps -= DeregisterCaps; |
146 | m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate; | 137 | s.EventManager.OnThrottleUpdate -= ThrottleUpdate; |
147 | m_NumberScenes--; | 138 | m_NumberScenes--; |
148 | m_scene = null; | 139 | m_scene = null; |
149 | } | 140 | } |
150 | 141 | ||
151 | public void RegionLoaded(Scene scene) | 142 | public void RegionLoaded(Scene s) |
152 | { | 143 | { |
153 | if (!m_Enabled) | 144 | if (!m_Enabled) |
154 | return; | 145 | return; |
155 | 146 | ||
156 | m_AssetService = m_scene.RequestModuleInterface<IAssetService>(); | 147 | if(m_assetService == null) |
157 | m_scene.EventManager.OnRegisterCaps += RegisterCaps; | 148 | { |
158 | // We'll reuse the same handler for all requests. | 149 | m_assetService = m_scene.RequestModuleInterface<IAssetService>(); |
159 | m_getMeshHandler = new GetMeshHandler(m_assetService); | 150 | // We'll reuse the same handler for all requests. |
160 | m_scene.EventManager.OnDeregisterCaps += DeregisterCaps; | 151 | m_getMeshHandler = new GetMeshHandler(m_assetService); |
161 | m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate; | 152 | } |
153 | |||
154 | s.EventManager.OnRegisterCaps += RegisterCaps; | ||
155 | s.EventManager.OnDeregisterCaps += DeregisterCaps; | ||
156 | s.EventManager.OnThrottleUpdate += ThrottleUpdate; | ||
162 | 157 | ||
163 | m_NumberScenes++; | 158 | m_NumberScenes++; |
164 | 159 | ||
@@ -190,7 +185,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
190 | // Prevent red ink. | 185 | // Prevent red ink. |
191 | try | 186 | try |
192 | { | 187 | { |
193 | m_queue.Clear(); | 188 | m_queue.Dispose(); |
194 | } | 189 | } |
195 | catch {} | 190 | catch {} |
196 | } | 191 | } |
@@ -202,14 +197,18 @@ namespace OpenSim.Region.ClientStack.Linden | |||
202 | 197 | ||
203 | private static void DoMeshRequests() | 198 | private static void DoMeshRequests() |
204 | { | 199 | { |
205 | while(true) | 200 | while (m_NumberScenes > 0) |
206 | { | 201 | { |
207 | aPollRequest poolreq = m_queue.Dequeue(4500); | 202 | APollRequest poolreq; |
208 | Watchdog.UpdateThread(); | 203 | if(m_queue.TryTake(out poolreq, 4500)) |
209 | if(m_NumberScenes <= 0) | 204 | { |
210 | return; | 205 | if(m_NumberScenes <= 0) |
211 | if(poolreq.reqID != UUID.Zero) | 206 | break; |
212 | poolreq.thepoll.Process(poolreq); | 207 | |
208 | if(poolreq.reqID != UUID.Zero) | ||
209 | poolreq.thepoll.Process(poolreq); | ||
210 | } | ||
211 | Watchdog.UpdateThread(); | ||
213 | } | 212 | } |
214 | } | 213 | } |
215 | 214 | ||
@@ -229,13 +228,14 @@ namespace OpenSim.Region.ClientStack.Linden | |||
229 | { | 228 | { |
230 | private List<Hashtable> requests = | 229 | private List<Hashtable> requests = |
231 | new List<Hashtable>(); | 230 | new List<Hashtable>(); |
232 | private Dictionary<UUID, aPollResponse> responses = | 231 | private Dictionary<UUID, APollResponse> responses = |
233 | new Dictionary<UUID, aPollResponse>(); | 232 | new Dictionary<UUID, APollResponse>(); |
233 | private HashSet<UUID> dropedResponses = new HashSet<UUID>(); | ||
234 | 234 | ||
235 | private Scene m_scene; | 235 | private Scene m_scene; |
236 | private MeshCapsDataThrottler m_throttler; | 236 | private MeshCapsDataThrottler m_throttler; |
237 | public PollServiceMeshEventArgs(string uri, UUID pId, Scene scene) : | 237 | public PollServiceMeshEventArgs(string uri, UUID pId, Scene scene) : |
238 | base(null, uri, null, null, null, pId, int.MaxValue) | 238 | base(null, uri, null, null, null, null, pId, int.MaxValue) |
239 | { | 239 | { |
240 | m_scene = scene; | 240 | m_scene = scene; |
241 | m_throttler = new MeshCapsDataThrottler(100000); | 241 | m_throttler = new MeshCapsDataThrottler(100000); |
@@ -249,6 +249,17 @@ namespace OpenSim.Region.ClientStack.Linden | |||
249 | 249 | ||
250 | } | 250 | } |
251 | }; | 251 | }; |
252 | |||
253 | Drop = (x, y) => | ||
254 | { | ||
255 | lock (responses) | ||
256 | { | ||
257 | responses.Remove(x); | ||
258 | lock(dropedResponses) | ||
259 | dropedResponses.Add(x); | ||
260 | } | ||
261 | }; | ||
262 | |||
252 | GetEvents = (x, y) => | 263 | GetEvents = (x, y) => |
253 | { | 264 | { |
254 | lock (responses) | 265 | lock (responses) |
@@ -267,12 +278,12 @@ namespace OpenSim.Region.ClientStack.Linden | |||
267 | // x is request id, y is request data hashtable | 278 | // x is request id, y is request data hashtable |
268 | Request = (x, y) => | 279 | Request = (x, y) => |
269 | { | 280 | { |
270 | aPollRequest reqinfo = new aPollRequest(); | 281 | APollRequest reqinfo = new APollRequest(); |
271 | reqinfo.thepoll = this; | 282 | reqinfo.thepoll = this; |
272 | reqinfo.reqID = x; | 283 | reqinfo.reqID = x; |
273 | reqinfo.request = y; | 284 | reqinfo.request = y; |
274 | 285 | ||
275 | m_queue.Enqueue(reqinfo); | 286 | m_queue.Add(reqinfo); |
276 | m_throttler.PassTime(); | 287 | m_throttler.PassTime(); |
277 | }; | 288 | }; |
278 | 289 | ||
@@ -298,7 +309,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
298 | }; | 309 | }; |
299 | } | 310 | } |
300 | 311 | ||
301 | public void Process(aPollRequest requestinfo) | 312 | public void Process(APollRequest requestinfo) |
302 | { | 313 | { |
303 | Hashtable response; | 314 | Hashtable response; |
304 | 315 | ||
@@ -307,30 +318,48 @@ namespace OpenSim.Region.ClientStack.Linden | |||
307 | if(m_scene.ShuttingDown) | 318 | if(m_scene.ShuttingDown) |
308 | return; | 319 | return; |
309 | 320 | ||
310 | // If the avatar is gone, don't bother to get the texture | 321 | lock(responses) |
311 | if (m_scene.GetScenePresence(Id) == null) | ||
312 | { | 322 | { |
313 | response = new Hashtable(); | 323 | lock(dropedResponses) |
314 | 324 | { | |
315 | response["int_response_code"] = 500; | 325 | if(dropedResponses.Contains(requestID)) |
316 | response["str_response_string"] = "Script timeout"; | 326 | { |
317 | response["content_type"] = "text/plain"; | 327 | dropedResponses.Remove(requestID); |
318 | response["keepalive"] = false; | 328 | return; |
319 | response["reusecontext"] = false; | 329 | } |
330 | } | ||
331 | |||
332 | // If the avatar is gone, don't bother to get the texture | ||
333 | if (m_scene.GetScenePresence(Id) == null) | ||
334 | { | ||
335 | response = new Hashtable(); | ||
320 | 336 | ||
321 | lock (responses) | 337 | response["int_response_code"] = 500; |
322 | responses[requestID] = new aPollResponse() { bytes = 0, response = response, lod = 0 }; | 338 | response["str_response_string"] = "Script timeout"; |
339 | response["content_type"] = "text/plain"; | ||
340 | response["keepalive"] = false; | ||
341 | responses[requestID] = new APollResponse() { bytes = 0, response = response}; | ||
323 | 342 | ||
324 | return; | 343 | return; |
344 | } | ||
325 | } | 345 | } |
326 | 346 | ||
327 | response = m_getMeshHandler.Handle(requestinfo.request); | 347 | response = m_getMeshHandler.Handle(requestinfo.request); |
348 | |||
328 | lock (responses) | 349 | lock (responses) |
329 | { | 350 | { |
330 | responses[requestID] = new aPollResponse() | 351 | lock(dropedResponses) |
352 | { | ||
353 | if(dropedResponses.Contains(requestID)) | ||
354 | { | ||
355 | dropedResponses.Remove(requestID); | ||
356 | return; | ||
357 | } | ||
358 | } | ||
359 | |||
360 | responses[requestID] = new APollResponse() | ||
331 | { | 361 | { |
332 | bytes = (int)response["int_bytes"], | 362 | bytes = (int)response["int_bytes"], |
333 | lod = (int)response["int_lod"], | ||
334 | response = response | 363 | response = response |
335 | }; | 364 | }; |
336 | 365 | ||
@@ -408,7 +437,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
408 | lastTimeElapsed = Util.GetTimeStampMS(); | 437 | lastTimeElapsed = Util.GetTimeStampMS(); |
409 | } | 438 | } |
410 | 439 | ||
411 | public bool hasEvents(UUID key, Dictionary<UUID, aPollResponse> responses) | 440 | public bool hasEvents(UUID key, Dictionary<UUID, APollResponse> responses) |
412 | { | 441 | { |
413 | PassTime(); | 442 | PassTime(); |
414 | // Note, this is called IN LOCK | 443 | // Note, this is called IN LOCK |
@@ -418,7 +447,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
418 | { | 447 | { |
419 | return false; | 448 | return false; |
420 | } | 449 | } |
421 | aPollResponse response; | 450 | APollResponse response; |
422 | if (responses.TryGetValue(key, out response)) | 451 | if (responses.TryGetValue(key, out response)) |
423 | { | 452 | { |
424 | // Normal | 453 | // Normal |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index b01c7dc..b206739 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs | |||
@@ -28,6 +28,7 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Collections.Concurrent; | ||
31 | using System.Reflection; | 32 | using System.Reflection; |
32 | using System.Threading; | 33 | using System.Threading; |
33 | using log4net; | 34 | using log4net; |
@@ -51,7 +52,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
51 | public class GetTextureModule : INonSharedRegionModule | 52 | public class GetTextureModule : INonSharedRegionModule |
52 | { | 53 | { |
53 | 54 | ||
54 | struct aPollRequest | 55 | class APollRequest |
55 | { | 56 | { |
56 | public PollServiceTextureEventArgs thepoll; | 57 | public PollServiceTextureEventArgs thepoll; |
57 | public UUID reqID; | 58 | public UUID reqID; |
@@ -59,7 +60,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
59 | public bool send503; | 60 | public bool send503; |
60 | } | 61 | } |
61 | 62 | ||
62 | public class aPollResponse | 63 | public class APollResponse |
63 | { | 64 | { |
64 | public Hashtable response; | 65 | public Hashtable response; |
65 | public int bytes; | 66 | public int bytes; |
@@ -77,8 +78,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
77 | private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>(); | 78 | private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>(); |
78 | private static Thread[] m_workerThreads = null; | 79 | private static Thread[] m_workerThreads = null; |
79 | private static int m_NumberScenes = 0; | 80 | private static int m_NumberScenes = 0; |
80 | private static OpenSim.Framework.BlockingQueue<aPollRequest> m_queue = | 81 | private static BlockingCollection<APollRequest> m_queue = new BlockingCollection<APollRequest>(); |
81 | new OpenSim.Framework.BlockingQueue<aPollRequest>(); | ||
82 | 82 | ||
83 | private Dictionary<UUID,PollServiceTextureEventArgs> m_pollservices = new Dictionary<UUID,PollServiceTextureEventArgs>(); | 83 | private Dictionary<UUID,PollServiceTextureEventArgs> m_pollservices = new Dictionary<UUID,PollServiceTextureEventArgs>(); |
84 | 84 | ||
@@ -107,26 +107,29 @@ namespace OpenSim.Region.ClientStack.Linden | |||
107 | public void AddRegion(Scene s) | 107 | public void AddRegion(Scene s) |
108 | { | 108 | { |
109 | m_scene = s; | 109 | m_scene = s; |
110 | m_assetService = s.AssetService; | ||
111 | } | 110 | } |
112 | 111 | ||
113 | public void RemoveRegion(Scene s) | 112 | public void RemoveRegion(Scene s) |
114 | { | 113 | { |
115 | m_scene.EventManager.OnRegisterCaps -= RegisterCaps; | 114 | s.EventManager.OnRegisterCaps -= RegisterCaps; |
116 | m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps; | 115 | s.EventManager.OnDeregisterCaps -= DeregisterCaps; |
117 | m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate; | 116 | s.EventManager.OnThrottleUpdate -= ThrottleUpdate; |
118 | m_NumberScenes--; | 117 | m_NumberScenes--; |
119 | m_scene = null; | 118 | m_scene = null; |
120 | } | 119 | } |
121 | 120 | ||
122 | public void RegionLoaded(Scene s) | 121 | public void RegionLoaded(Scene s) |
123 | { | 122 | { |
124 | // We'll reuse the same handler for all requests. | 123 | if(m_assetService == null) |
125 | m_getTextureHandler = new GetTextureHandler(m_assetService); | 124 | { |
125 | m_assetService = s.RequestModuleInterface<IAssetService>(); | ||
126 | // We'll reuse the same handler for all requests. | ||
127 | m_getTextureHandler = new GetTextureHandler(m_assetService); | ||
128 | } | ||
126 | 129 | ||
127 | m_scene.EventManager.OnRegisterCaps += RegisterCaps; | 130 | s.EventManager.OnRegisterCaps += RegisterCaps; |
128 | m_scene.EventManager.OnDeregisterCaps += DeregisterCaps; | 131 | s.EventManager.OnDeregisterCaps += DeregisterCaps; |
129 | m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate; | 132 | s.EventManager.OnThrottleUpdate += ThrottleUpdate; |
130 | 133 | ||
131 | m_NumberScenes++; | 134 | m_NumberScenes++; |
132 | 135 | ||
@@ -146,39 +149,13 @@ namespace OpenSim.Region.ClientStack.Linden | |||
146 | } | 149 | } |
147 | } | 150 | } |
148 | } | 151 | } |
149 | private int ExtractImageThrottle(byte[] pthrottles) | 152 | |
150 | { | ||
151 | |||
152 | byte[] adjData; | ||
153 | int pos = 0; | ||
154 | |||
155 | if (!BitConverter.IsLittleEndian) | ||
156 | { | ||
157 | byte[] newData = new byte[7 * 4]; | ||
158 | Buffer.BlockCopy(pthrottles, 0, newData, 0, 7 * 4); | ||
159 | |||
160 | for (int i = 0; i < 7; i++) | ||
161 | Array.Reverse(newData, i * 4, 4); | ||
162 | |||
163 | adjData = newData; | ||
164 | } | ||
165 | else | ||
166 | { | ||
167 | adjData = pthrottles; | ||
168 | } | ||
169 | |||
170 | pos = pos + 20; | ||
171 | int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); //pos += 4; | ||
172 | //int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); | ||
173 | return texture; | ||
174 | } | ||
175 | |||
176 | // Now we know when the throttle is changed by the client in the case of a root agent or by a neighbor region in the case of a child agent. | 153 | // Now we know when the throttle is changed by the client in the case of a root agent or by a neighbor region in the case of a child agent. |
177 | public void ThrottleUpdate(ScenePresence p) | 154 | public void ThrottleUpdate(ScenePresence p) |
178 | { | 155 | { |
179 | byte[] throttles = p.ControllingClient.GetThrottlesPacked(1); | 156 | byte[] throttles = p.ControllingClient.GetThrottlesPacked(1); |
180 | UUID user = p.UUID; | 157 | UUID user = p.UUID; |
181 | int imagethrottle = ExtractImageThrottle(throttles); | 158 | int imagethrottle = p.ControllingClient.GetAgentThrottleSilent((int)ThrottleOutPacketType.Texture); |
182 | PollServiceTextureEventArgs args; | 159 | PollServiceTextureEventArgs args; |
183 | if (m_pollservices.TryGetValue(user,out args)) | 160 | if (m_pollservices.TryGetValue(user,out args)) |
184 | { | 161 | { |
@@ -199,7 +176,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
199 | foreach (Thread t in m_workerThreads) | 176 | foreach (Thread t in m_workerThreads) |
200 | Watchdog.AbortThread(t.ManagedThreadId); | 177 | Watchdog.AbortThread(t.ManagedThreadId); |
201 | 178 | ||
202 | m_queue.Clear(); | 179 | m_queue.Dispose(); |
203 | } | 180 | } |
204 | } | 181 | } |
205 | 182 | ||
@@ -216,15 +193,17 @@ namespace OpenSim.Region.ClientStack.Linden | |||
216 | { | 193 | { |
217 | private List<Hashtable> requests = | 194 | private List<Hashtable> requests = |
218 | new List<Hashtable>(); | 195 | new List<Hashtable>(); |
219 | private Dictionary<UUID, aPollResponse> responses = | 196 | private Dictionary<UUID, APollResponse> responses = |
220 | new Dictionary<UUID, aPollResponse>(); | 197 | new Dictionary<UUID, APollResponse>(); |
198 | private HashSet<UUID> dropedResponses = new HashSet<UUID>(); | ||
221 | 199 | ||
222 | private Scene m_scene; | 200 | private Scene m_scene; |
223 | private CapsDataThrottler m_throttler = new CapsDataThrottler(100000); | 201 | private CapsDataThrottler m_throttler; |
224 | public PollServiceTextureEventArgs(UUID pId, Scene scene) : | 202 | public PollServiceTextureEventArgs(UUID pId, Scene scene) : |
225 | base(null, "", null, null, null, pId, int.MaxValue) | 203 | base(null, "", null, null, null, null, pId, int.MaxValue) |
226 | { | 204 | { |
227 | m_scene = scene; | 205 | m_scene = scene; |
206 | m_throttler = new CapsDataThrottler(100000); | ||
228 | // x is request id, y is userid | 207 | // x is request id, y is userid |
229 | HasEvents = (x, y) => | 208 | HasEvents = (x, y) => |
230 | { | 209 | { |
@@ -235,6 +214,16 @@ namespace OpenSim.Region.ClientStack.Linden | |||
235 | 214 | ||
236 | } | 215 | } |
237 | }; | 216 | }; |
217 | |||
218 | Drop = (x, y) => | ||
219 | { | ||
220 | lock (responses) | ||
221 | { | ||
222 | responses.Remove(x); | ||
223 | dropedResponses.Add(x); | ||
224 | } | ||
225 | }; | ||
226 | |||
238 | GetEvents = (x, y) => | 227 | GetEvents = (x, y) => |
239 | { | 228 | { |
240 | lock (responses) | 229 | lock (responses) |
@@ -253,7 +242,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
253 | // x is request id, y is request data hashtable | 242 | // x is request id, y is request data hashtable |
254 | Request = (x, y) => | 243 | Request = (x, y) => |
255 | { | 244 | { |
256 | aPollRequest reqinfo = new aPollRequest(); | 245 | APollRequest reqinfo = new APollRequest(); |
257 | reqinfo.thepoll = this; | 246 | reqinfo.thepoll = this; |
258 | reqinfo.reqID = x; | 247 | reqinfo.reqID = x; |
259 | reqinfo.request = y; | 248 | reqinfo.request = y; |
@@ -263,14 +252,14 @@ namespace OpenSim.Region.ClientStack.Linden | |||
263 | { | 252 | { |
264 | if (responses.Count > 0) | 253 | if (responses.Count > 0) |
265 | { | 254 | { |
266 | if (m_queue.Count() >= 4) | 255 | if (m_queue.Count >= 4) |
267 | { | 256 | { |
268 | // Never allow more than 4 fetches to wait | 257 | // Never allow more than 4 fetches to wait |
269 | reqinfo.send503 = true; | 258 | reqinfo.send503 = true; |
270 | } | 259 | } |
271 | } | 260 | } |
272 | } | 261 | } |
273 | m_queue.Enqueue(reqinfo); | 262 | m_queue.Add(reqinfo); |
274 | m_throttler.PassTime(); | 263 | m_throttler.PassTime(); |
275 | }; | 264 | }; |
276 | 265 | ||
@@ -296,7 +285,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
296 | }; | 285 | }; |
297 | } | 286 | } |
298 | 287 | ||
299 | public void Process(aPollRequest requestinfo) | 288 | public void Process(APollRequest requestinfo) |
300 | { | 289 | { |
301 | Hashtable response; | 290 | Hashtable response; |
302 | 291 | ||
@@ -305,53 +294,71 @@ namespace OpenSim.Region.ClientStack.Linden | |||
305 | if(m_scene.ShuttingDown) | 294 | if(m_scene.ShuttingDown) |
306 | return; | 295 | return; |
307 | 296 | ||
308 | if (requestinfo.send503) | 297 | lock (responses) |
309 | { | 298 | { |
310 | response = new Hashtable(); | 299 | lock(dropedResponses) |
300 | { | ||
301 | if(dropedResponses.Contains(requestID)) | ||
302 | { | ||
303 | dropedResponses.Remove(requestID); | ||
304 | return; | ||
305 | } | ||
306 | } | ||
311 | 307 | ||
312 | response["int_response_code"] = 503; | 308 | if (requestinfo.send503) |
313 | response["str_response_string"] = "Throttled"; | 309 | { |
314 | response["content_type"] = "text/plain"; | 310 | response = new Hashtable(); |
315 | response["keepalive"] = false; | ||
316 | response["reusecontext"] = false; | ||
317 | 311 | ||
318 | Hashtable headers = new Hashtable(); | 312 | response["int_response_code"] = 503; |
319 | headers["Retry-After"] = 30; | 313 | response["str_response_string"] = "Throttled"; |
320 | response["headers"] = headers; | 314 | response["content_type"] = "text/plain"; |
315 | response["keepalive"] = false; | ||
316 | response["reusecontext"] = false; | ||
321 | 317 | ||
322 | lock (responses) | 318 | Hashtable headers = new Hashtable(); |
323 | responses[requestID] = new aPollResponse() {bytes = 0, response = response}; | 319 | headers["Retry-After"] = 30; |
320 | response["headers"] = headers; | ||
324 | 321 | ||
325 | return; | 322 | responses[requestID] = new APollResponse() {bytes = 0, response = response}; |
326 | } | 323 | |
324 | return; | ||
325 | } | ||
327 | 326 | ||
328 | // If the avatar is gone, don't bother to get the texture | 327 | // If the avatar is gone, don't bother to get the texture |
329 | if (m_scene.GetScenePresence(Id) == null) | 328 | if (m_scene.GetScenePresence(Id) == null) |
330 | { | 329 | { |
331 | response = new Hashtable(); | 330 | response = new Hashtable(); |
332 | 331 | ||
333 | response["int_response_code"] = 500; | 332 | response["int_response_code"] = 500; |
334 | response["str_response_string"] = "Script timeout"; | 333 | response["str_response_string"] = "Script timeout"; |
335 | response["content_type"] = "text/plain"; | 334 | response["content_type"] = "text/plain"; |
336 | response["keepalive"] = false; | 335 | response["keepalive"] = false; |
337 | response["reusecontext"] = false; | ||
338 | 336 | ||
339 | lock (responses) | 337 | responses[requestID] = new APollResponse() {bytes = 0, response = response}; |
340 | responses[requestID] = new aPollResponse() {bytes = 0, response = response}; | ||
341 | 338 | ||
342 | return; | 339 | return; |
340 | } | ||
343 | } | 341 | } |
344 | 342 | ||
345 | response = m_getTextureHandler.Handle(requestinfo.request); | 343 | response = m_getTextureHandler.Handle(requestinfo.request); |
344 | |||
346 | lock (responses) | 345 | lock (responses) |
347 | { | 346 | { |
348 | responses[requestID] = new aPollResponse() | 347 | lock(dropedResponses) |
349 | { | 348 | { |
350 | bytes = (int) response["int_bytes"], | 349 | if(dropedResponses.Contains(requestID)) |
351 | response = response | 350 | { |
352 | }; | 351 | dropedResponses.Remove(requestID); |
353 | 352 | m_throttler.PassTime(); | |
354 | } | 353 | return; |
354 | } | ||
355 | } | ||
356 | responses[requestID] = new APollResponse() | ||
357 | { | ||
358 | bytes = (int) response["int_bytes"], | ||
359 | response = response | ||
360 | }; | ||
361 | } | ||
355 | m_throttler.PassTime(); | 362 | m_throttler.PassTime(); |
356 | } | 363 | } |
357 | 364 | ||
@@ -415,12 +422,20 @@ namespace OpenSim.Region.ClientStack.Linden | |||
415 | 422 | ||
416 | private static void DoTextureRequests() | 423 | private static void DoTextureRequests() |
417 | { | 424 | { |
418 | while (true) | 425 | APollRequest poolreq; |
426 | while (m_NumberScenes > 0) | ||
419 | { | 427 | { |
420 | aPollRequest poolreq = m_queue.Dequeue(4500); | 428 | poolreq = null; |
421 | Watchdog.UpdateThread(); | 429 | if(!m_queue.TryTake(out poolreq, 4500) || poolreq == null) |
430 | { | ||
431 | Watchdog.UpdateThread(); | ||
432 | continue; | ||
433 | } | ||
434 | |||
422 | if(m_NumberScenes <= 0) | 435 | if(m_NumberScenes <= 0) |
423 | return; | 436 | break; |
437 | |||
438 | Watchdog.UpdateThread(); | ||
424 | if(poolreq.reqID != UUID.Zero) | 439 | if(poolreq.reqID != UUID.Zero) |
425 | poolreq.thepoll.Process(poolreq); | 440 | poolreq.thepoll.Process(poolreq); |
426 | } | 441 | } |
@@ -437,7 +452,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
437 | ThrottleBytes = pBytes; | 452 | ThrottleBytes = pBytes; |
438 | lastTimeElapsed = Util.GetTimeStampMS(); | 453 | lastTimeElapsed = Util.GetTimeStampMS(); |
439 | } | 454 | } |
440 | public bool hasEvents(UUID key, Dictionary<UUID, GetTextureModule.aPollResponse> responses) | 455 | public bool hasEvents(UUID key, Dictionary<UUID, GetTextureModule.APollResponse> responses) |
441 | { | 456 | { |
442 | PassTime(); | 457 | PassTime(); |
443 | // Note, this is called IN LOCK | 458 | // Note, this is called IN LOCK |
@@ -446,7 +461,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
446 | { | 461 | { |
447 | return false; | 462 | return false; |
448 | } | 463 | } |
449 | GetTextureModule.aPollResponse response; | 464 | GetTextureModule.APollResponse response; |
450 | if (responses.TryGetValue(key, out response)) | 465 | if (responses.TryGetValue(key, out response)) |
451 | { | 466 | { |
452 | // This is any error response | 467 | // This is any error response |
@@ -476,7 +491,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
476 | return; | 491 | return; |
477 | int add = (int)(ThrottleBytes * timeElapsed * 0.001); | 492 | int add = (int)(ThrottleBytes * timeElapsed * 0.001); |
478 | if (add >= 1000) | 493 | if (add >= 1000) |
479 | { | 494 | { |
480 | lastTimeElapsed = currenttime; | 495 | lastTimeElapsed = currenttime; |
481 | BytesSent -= add; | 496 | BytesSent -= add; |
482 | if (BytesSent < 0) BytesSent = 0; | 497 | if (BytesSent < 0) BytesSent = 0; |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs index 39f5baf..cbcbd2d 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs | |||
@@ -253,7 +253,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
253 | Hashtable responsedata = new Hashtable(); | 253 | Hashtable responsedata = new Hashtable(); |
254 | responsedata["int_response_code"] = 200; | 254 | responsedata["int_response_code"] = 200; |
255 | responsedata["content_type"] = "text/plain"; | 255 | responsedata["content_type"] = "text/plain"; |
256 | responsedata["keepalive"] = false; | ||
257 | 256 | ||
258 | responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(copy); | 257 | responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(copy); |
259 | 258 | ||
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 8d4e561..1113002 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs | |||
@@ -28,14 +28,13 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Collections.Concurrent; | ||
31 | using System.Reflection; | 32 | using System.Reflection; |
32 | using System.Threading; | 33 | using System.Threading; |
33 | using log4net; | 34 | using log4net; |
34 | using Nini.Config; | 35 | using Nini.Config; |
35 | using Mono.Addins; | 36 | using Mono.Addins; |
36 | using OpenMetaverse; | 37 | using OpenMetaverse; |
37 | using OpenSim.Framework; | ||
38 | using OpenSim.Framework.Servers; | ||
39 | using OpenSim.Framework.Servers.HttpServer; | 38 | using OpenSim.Framework.Servers.HttpServer; |
40 | using OpenSim.Region.Framework.Interfaces; | 39 | using OpenSim.Region.Framework.Interfaces; |
41 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
@@ -55,13 +54,12 @@ namespace OpenSim.Region.ClientStack.Linden | |||
55 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebFetchInvDescModule")] | 54 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebFetchInvDescModule")] |
56 | public class WebFetchInvDescModule : INonSharedRegionModule | 55 | public class WebFetchInvDescModule : INonSharedRegionModule |
57 | { | 56 | { |
58 | class aPollRequest | 57 | class APollRequest |
59 | { | 58 | { |
60 | public PollServiceInventoryEventArgs thepoll; | 59 | public PollServiceInventoryEventArgs thepoll; |
61 | public UUID reqID; | 60 | public UUID reqID; |
62 | public Hashtable request; | 61 | public Hashtable request; |
63 | public ScenePresence presence; | 62 | public ScenePresence presence; |
64 | public List<UUID> folders; | ||
65 | } | 63 | } |
66 | 64 | ||
67 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 65 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
@@ -99,8 +97,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
99 | 97 | ||
100 | private static Thread[] m_workerThreads = null; | 98 | private static Thread[] m_workerThreads = null; |
101 | 99 | ||
102 | private static OpenSim.Framework.BlockingQueue<aPollRequest> m_queue = | 100 | private static BlockingCollection<APollRequest> m_queue = new BlockingCollection<APollRequest>(); |
103 | new OpenSim.Framework.BlockingQueue<aPollRequest>(); | ||
104 | 101 | ||
105 | private static int m_NumberScenes = 0; | 102 | private static int m_NumberScenes = 0; |
106 | 103 | ||
@@ -181,7 +178,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
181 | "httpfetch", | 178 | "httpfetch", |
182 | StatType.Pull, | 179 | StatType.Pull, |
183 | MeasuresOfInterest.AverageChangeOverTime, | 180 | MeasuresOfInterest.AverageChangeOverTime, |
184 | stat => { stat.Value = m_queue.Count(); }, | 181 | stat => { stat.Value = m_queue.Count; }, |
185 | StatVerbosity.Debug); | 182 | StatVerbosity.Debug); |
186 | 183 | ||
187 | StatsManager.RegisterStat(s_processedRequestsStat); | 184 | StatsManager.RegisterStat(s_processedRequestsStat); |
@@ -235,6 +232,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
235 | m_workerThreads = null; | 232 | m_workerThreads = null; |
236 | } | 233 | } |
237 | } | 234 | } |
235 | // m_queue.Dispose(); | ||
238 | } | 236 | } |
239 | 237 | ||
240 | public string Name { get { return "WebFetchInvDescModule"; } } | 238 | public string Name { get { return "WebFetchInvDescModule"; } } |
@@ -250,17 +248,28 @@ namespace OpenSim.Region.ClientStack.Linden | |||
250 | { | 248 | { |
251 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 249 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
252 | 250 | ||
253 | private Dictionary<UUID, Hashtable> responses = | 251 | private Dictionary<UUID, Hashtable> responses = new Dictionary<UUID, Hashtable>(); |
254 | new Dictionary<UUID, Hashtable>(); | 252 | private HashSet<UUID> dropedResponses = new HashSet<UUID>(); |
255 | 253 | ||
256 | private WebFetchInvDescModule m_module; | 254 | private WebFetchInvDescModule m_module; |
257 | 255 | ||
258 | public PollServiceInventoryEventArgs(WebFetchInvDescModule module, string url, UUID pId) : | 256 | public PollServiceInventoryEventArgs(WebFetchInvDescModule module, string url, UUID pId) : |
259 | base(null, url, null, null, null, pId, int.MaxValue) | 257 | base(null, url, null, null, null, null, pId, int.MaxValue) |
260 | { | 258 | { |
261 | m_module = module; | 259 | m_module = module; |
262 | 260 | ||
263 | HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; | 261 | HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; |
262 | |||
263 | Drop = (x, y) => | ||
264 | { | ||
265 | lock (responses) | ||
266 | { | ||
267 | responses.Remove(x); | ||
268 | lock(dropedResponses) | ||
269 | dropedResponses.Add(x); | ||
270 | } | ||
271 | }; | ||
272 | |||
264 | GetEvents = (x, y) => | 273 | GetEvents = (x, y) => |
265 | { | 274 | { |
266 | lock (responses) | 275 | lock (responses) |
@@ -280,13 +289,15 @@ namespace OpenSim.Region.ClientStack.Linden | |||
280 | { | 289 | { |
281 | ScenePresence sp = m_module.Scene.GetScenePresence(Id); | 290 | ScenePresence sp = m_module.Scene.GetScenePresence(Id); |
282 | 291 | ||
283 | aPollRequest reqinfo = new aPollRequest(); | 292 | APollRequest reqinfo = new APollRequest(); |
284 | reqinfo.thepoll = this; | 293 | reqinfo.thepoll = this; |
285 | reqinfo.reqID = x; | 294 | reqinfo.reqID = x; |
286 | reqinfo.request = y; | 295 | reqinfo.request = y; |
287 | reqinfo.presence = sp; | 296 | reqinfo.presence = sp; |
288 | reqinfo.folders = new List<UUID>(); | ||
289 | 297 | ||
298 | /* why where we doing this? just to get cof ? | ||
299 | List<UUID> folders = new List<UUID>(); | ||
300 | |||
290 | // Decode the request here | 301 | // Decode the request here |
291 | string request = y["body"].ToString(); | 302 | string request = y["body"].ToString(); |
292 | 303 | ||
@@ -322,11 +333,11 @@ namespace OpenSim.Region.ClientStack.Linden | |||
322 | UUID folderID; | 333 | UUID folderID; |
323 | if (UUID.TryParse(folder, out folderID)) | 334 | if (UUID.TryParse(folder, out folderID)) |
324 | { | 335 | { |
325 | if (!reqinfo.folders.Contains(folderID)) | 336 | if (!folders.Contains(folderID)) |
326 | { | 337 | { |
327 | if (sp.COF != UUID.Zero && sp.COF == folderID) | 338 | if (sp.COF != UUID.Zero && sp.COF == folderID) |
328 | highPriority = true; | 339 | highPriority = true; |
329 | reqinfo.folders.Add(folderID); | 340 | folders.Add(folderID); |
330 | } | 341 | } |
331 | } | 342 | } |
332 | } | 343 | } |
@@ -334,7 +345,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
334 | if (highPriority) | 345 | if (highPriority) |
335 | m_queue.PriorityEnqueue(reqinfo); | 346 | m_queue.PriorityEnqueue(reqinfo); |
336 | else | 347 | else |
337 | m_queue.Enqueue(reqinfo); | 348 | */ |
349 | m_queue.Add(reqinfo); | ||
338 | }; | 350 | }; |
339 | 351 | ||
340 | NoEvents = (x, y) => | 352 | NoEvents = (x, y) => |
@@ -352,36 +364,56 @@ namespace OpenSim.Region.ClientStack.Linden | |||
352 | response["str_response_string"] = "Script timeout"; | 364 | response["str_response_string"] = "Script timeout"; |
353 | response["content_type"] = "text/plain"; | 365 | response["content_type"] = "text/plain"; |
354 | response["keepalive"] = false; | 366 | response["keepalive"] = false; |
355 | response["reusecontext"] = false; | ||
356 | 367 | ||
357 | return response; | 368 | return response; |
358 | }; | 369 | }; |
359 | } | 370 | } |
360 | 371 | ||
361 | public void Process(aPollRequest requestinfo) | 372 | public void Process(APollRequest requestinfo) |
362 | { | 373 | { |
363 | if(m_module == null || m_module.Scene == null || m_module.Scene.ShuttingDown) | 374 | if(m_module == null || m_module.Scene == null || m_module.Scene.ShuttingDown) |
364 | return; | 375 | return; |
365 | 376 | ||
366 | UUID requestID = requestinfo.reqID; | 377 | UUID requestID = requestinfo.reqID; |
367 | 378 | ||
379 | |||
380 | lock(responses) | ||
381 | { | ||
382 | lock(dropedResponses) | ||
383 | { | ||
384 | if(dropedResponses.Contains(requestID)) | ||
385 | { | ||
386 | dropedResponses.Remove(requestID); | ||
387 | return; | ||
388 | } | ||
389 | } | ||
390 | } | ||
391 | |||
368 | Hashtable response = new Hashtable(); | 392 | Hashtable response = new Hashtable(); |
369 | 393 | ||
370 | response["int_response_code"] = 200; | 394 | response["int_response_code"] = 200; |
371 | response["content_type"] = "text/plain"; | 395 | response["content_type"] = "text/plain"; |
372 | response["keepalive"] = false; | ||
373 | response["reusecontext"] = false; | ||
374 | 396 | ||
375 | response["str_response_string"] = m_webFetchHandler.FetchInventoryDescendentsRequest( | 397 | response["str_response_string"] = m_webFetchHandler.FetchInventoryDescendentsRequest( |
376 | requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null); | 398 | requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null); |
377 | 399 | ||
378 | lock (responses) | 400 | lock (responses) |
379 | { | 401 | { |
402 | lock(dropedResponses) | ||
403 | { | ||
404 | if(dropedResponses.Contains(requestID)) | ||
405 | { | ||
406 | dropedResponses.Remove(requestID); | ||
407 | requestinfo.request.Clear(); | ||
408 | WebFetchInvDescModule.ProcessedRequestsCount++; | ||
409 | return; | ||
410 | } | ||
411 | } | ||
412 | |||
380 | if (responses.ContainsKey(requestID)) | 413 | if (responses.ContainsKey(requestID)) |
381 | m_log.WarnFormat("[FETCH INVENTORY DESCENDENTS2 MODULE]: Caught in the act of loosing responses! Please report this on mantis #7054"); | 414 | m_log.WarnFormat("[FETCH INVENTORY DESCENDENTS2 MODULE]: Caught in the act of loosing responses! Please report this on mantis #7054"); |
382 | responses[requestID] = response; | 415 | responses[requestID] = response; |
383 | } | 416 | } |
384 | requestinfo.folders.Clear(); | ||
385 | requestinfo.request.Clear(); | 417 | requestinfo.request.Clear(); |
386 | WebFetchInvDescModule.ProcessedRequestsCount++; | 418 | WebFetchInvDescModule.ProcessedRequestsCount++; |
387 | } | 419 | } |
@@ -441,23 +473,26 @@ namespace OpenSim.Region.ClientStack.Linden | |||
441 | 473 | ||
442 | private static void DoInventoryRequests() | 474 | private static void DoInventoryRequests() |
443 | { | 475 | { |
476 | APollRequest poolreq; | ||
444 | while (true) | 477 | while (true) |
445 | { | 478 | { |
446 | aPollRequest poolreq = m_queue.Dequeue(4500); | 479 | if(!m_queue.TryTake(out poolreq, 4500) || poolreq == null || poolreq.thepoll == null) |
447 | Watchdog.UpdateThread(); | 480 | { |
481 | Watchdog.UpdateThread(); | ||
482 | continue; | ||
483 | } | ||
448 | 484 | ||
449 | if (poolreq != null && poolreq.thepoll != null) | 485 | Watchdog.UpdateThread(); |
486 | try | ||
450 | { | 487 | { |
451 | try | 488 | APollRequest req = poolreq; |
452 | { | 489 | req.thepoll.Process(req); |
453 | poolreq.thepoll.Process(poolreq); | 490 | } |
454 | } | 491 | catch (Exception e) |
455 | catch (Exception e) | 492 | { |
456 | { | 493 | m_log.ErrorFormat( |
457 | m_log.ErrorFormat( | 494 | "[INVENTORY]: Failed to process queued inventory request {0} for {1}. Exception {2}", |
458 | "[INVENTORY]: Failed to process queued inventory request {0} for {1}. Exception {2}", | 495 | poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", e); |
459 | poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", e); | ||
460 | } | ||
461 | } | 496 | } |
462 | } | 497 | } |
463 | } | 498 | } |