aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs217
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs90
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs18
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs11
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs137
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs193
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs1
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs101
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs41
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs34
11 files changed, 476 insertions, 371 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;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Net; 31using System.Net;
32using System.Reflection; 32using System.Reflection;
33using System.Threading; 33using System.Text;
34using log4net; 34using log4net;
35using Nini.Config; 35using Nini.Config;
36using Mono.Addins; 36using Mono.Addins;
@@ -44,7 +44,6 @@ using OpenSim.Framework.Servers;
44using OpenSim.Framework.Servers.HttpServer; 44using OpenSim.Framework.Servers.HttpServer;
45using OpenSim.Region.Framework.Interfaces; 45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 46using OpenSim.Region.Framework.Scenes;
47using BlockingLLSDQueue = OpenSim.Framework.BlockingQueue<OpenMetaverse.StructuredData.OSD>;
48using Caps=OpenSim.Framework.Capabilities.Caps; 47using Caps=OpenSim.Framework.Capabilities.Caps;
49 48
50namespace OpenSim.Region.ClientStack.Linden 49namespace 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;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Net; 31using System.Net;
32using System.Text;
32using log4net.Config; 33using log4net.Config;
33using Nini.Config; 34using Nini.Config;
34using NUnit.Framework; 35using 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 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Collections.Specialized; 31using System.Collections.Concurrent;
32using System.Reflection; 32using System.Reflection;
33using System.IO;
34using System.Threading; 33using System.Threading;
35using System.Web;
36using Mono.Addins; 34using Mono.Addins;
37using OpenSim.Framework.Monitoring; 35using OpenSim.Framework.Monitoring;
38using log4net; 36using log4net;
39using Nini.Config; 37using Nini.Config;
40using OpenMetaverse; 38using OpenMetaverse;
41using OpenMetaverse.StructuredData;
42using OpenSim.Capabilities.Handlers; 39using OpenSim.Capabilities.Handlers;
43using OpenSim.Framework; 40using OpenSim.Framework;
44using OpenSim.Framework.Servers; 41using 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 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Collections.Concurrent;
31using System.Reflection; 32using System.Reflection;
32using System.Threading; 33using System.Threading;
33using log4net; 34using 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 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Collections.Concurrent;
31using System.Reflection; 32using System.Reflection;
32using System.Threading; 33using System.Threading;
33using log4net; 34using log4net;
34using Nini.Config; 35using Nini.Config;
35using Mono.Addins; 36using Mono.Addins;
36using OpenMetaverse; 37using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Framework.Servers;
39using OpenSim.Framework.Servers.HttpServer; 38using OpenSim.Framework.Servers.HttpServer;
40using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes; 40using 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 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 2ff6ced..cd687aa 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -99,8 +99,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
99 public event AgentRequestSit OnAgentRequestSit; 99 public event AgentRequestSit OnAgentRequestSit;
100 public event AgentSit OnAgentSit; 100 public event AgentSit OnAgentSit;
101 public event AvatarPickerRequest OnAvatarPickerRequest; 101 public event AvatarPickerRequest OnAvatarPickerRequest;
102 public event StartAnim OnStartAnim;
103 public event StopAnim OnStopAnim;
104 public event ChangeAnim OnChangeAnim; 102 public event ChangeAnim OnChangeAnim;
105 public event Action<IClientAPI> OnRequestAvatarsData; 103 public event Action<IClientAPI> OnRequestAvatarsData;
106 public event LinkObjects OnLinkObjects; 104 public event LinkObjects OnLinkObjects;
@@ -131,12 +129,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
131 public event UpdatePrimTexture OnUpdatePrimTexture; 129 public event UpdatePrimTexture OnUpdatePrimTexture;
132 public event ClientChangeObject onClientChangeObject; 130 public event ClientChangeObject onClientChangeObject;
133 public event UpdateVector OnUpdatePrimGroupPosition; 131 public event UpdateVector OnUpdatePrimGroupPosition;
134 public event UpdateVector OnUpdatePrimSinglePosition;
135 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 132 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
136 public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation;
137 public event UpdatePrimSingleRotationPosition OnUpdatePrimSingleRotationPosition;
138 public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation;
139 public event UpdateVector OnUpdatePrimScale;
140 public event UpdateVector OnUpdatePrimGroupScale; 133 public event UpdateVector OnUpdatePrimGroupScale;
141 public event RequestMapBlocks OnRequestMapBlocks; 134 public event RequestMapBlocks OnRequestMapBlocks;
142 public event RequestMapName OnMapNameRequest; 135 public event RequestMapName OnMapNameRequest;
@@ -292,7 +285,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
292 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate; 285 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
293 public event GenericCall2 OnUpdateThrottles; 286 public event GenericCall2 OnUpdateThrottles;
294 287
288
295#pragma warning disable 0067 289#pragma warning disable 0067
290 // still unused
296 public event GenericMessage OnGenericMessage; 291 public event GenericMessage OnGenericMessage;
297 public event TextureRequest OnRequestTexture; 292 public event TextureRequest OnRequestTexture;
298 public event StatusChange OnChildAgentStatus; 293 public event StatusChange OnChildAgentStatus;
@@ -304,6 +299,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
304 public event SetEstateTerrainBaseTexture OnSetEstateTerrainBaseTexture; 299 public event SetEstateTerrainBaseTexture OnSetEstateTerrainBaseTexture;
305 public event TerrainUnacked OnUnackedTerrain; 300 public event TerrainUnacked OnUnackedTerrain;
306 public event CachedTextureRequest OnCachedTextureRequest; 301 public event CachedTextureRequest OnCachedTextureRequest;
302
303 public event UpdateVector OnUpdatePrimSinglePosition;
304 public event StartAnim OnStartAnim;
305 public event StopAnim OnStopAnim;
306 public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation;
307 public event UpdatePrimSingleRotationPosition OnUpdatePrimSingleRotationPosition;
308 public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation;
309 public event UpdateVector OnUpdatePrimScale;
310
311
307#pragma warning restore 0067 312#pragma warning restore 0067
308 313
309 #endregion Events 314 #endregion Events
@@ -335,16 +340,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
335 private readonly byte[] m_channelVersion = Utils.EmptyBytes; 340 private readonly byte[] m_channelVersion = Utils.EmptyBytes;
336 private readonly IGroupsModule m_GroupsModule; 341 private readonly IGroupsModule m_GroupsModule;
337 342
338 private int m_cachedTextureSerial; 343// private int m_cachedTextureSerial;
339 private PriorityQueue m_entityUpdates; 344 private PriorityQueue m_entityUpdates;
340 private PriorityQueue m_entityProps; 345 private PriorityQueue m_entityProps;
341 private Prioritizer m_prioritizer; 346 private Prioritizer m_prioritizer;
342 private bool m_disableFacelights = false; 347 private bool m_disableFacelights;
343 348
344 // needs optimazation 349 // needs optimazation
345 private HashSet<SceneObjectGroup> GroupsInView = new HashSet<SceneObjectGroup>(); 350 private HashSet<SceneObjectGroup> GroupsInView = new HashSet<SceneObjectGroup>();
346 351#pragma warning disable 0414
347 private bool m_VelocityInterpolate = false; 352 private bool m_VelocityInterpolate;
353#pragma warning restore 0414
348 private const uint MaxTransferBytesPerPacket = 600; 354 private const uint MaxTransferBytesPerPacket = 600;
349 355
350 /// <value> 356 /// <value>
@@ -503,8 +509,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
503 RegisterInterface<IClientChat>(this); 509 RegisterInterface<IClientChat>(this);
504 510
505 m_scene = scene; 511 m_scene = scene;
506 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 512 int pcap = 512;
507 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 513 if(pcap > m_scene.Entities.Count)
514 pcap = m_scene.Entities.Count;
515 m_entityUpdates = new PriorityQueue(pcap);
516 m_entityProps = new PriorityQueue(pcap);
508 m_killRecord = new List<uint>(); 517 m_killRecord = new List<uint>();
509// m_attachmentsSent = new HashSet<uint>(); 518// m_attachmentsSent = new HashSet<uint>();
510 519
@@ -617,6 +626,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
617 ImageManager.Close(); 626 ImageManager.Close();
618 ImageManager = null; 627 ImageManager = null;
619 628
629// m_entityUpdates.Close();
630// m_entityProps.Close();
620 m_entityUpdates = new PriorityQueue(1); 631 m_entityUpdates = new PriorityQueue(1);
621 m_entityProps = new PriorityQueue(1); 632 m_entityProps = new PriorityQueue(1);
622 m_killRecord.Clear(); 633 m_killRecord.Clear();
@@ -11039,9 +11050,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11039 if(muteListRequest.MuteData.MuteCRC == 0) 11050 if(muteListRequest.MuteData.MuteCRC == 0)
11040 SendEmpytMuteList(); 11051 SendEmpytMuteList();
11041 else 11052 else
11042 SendUseCachedMuteList(); 11053 SendUseCachedMuteList();
11043 } 11054 }
11044 return true; 11055 return true;
11045 } 11056 }
11046 11057
11047 private bool HandleUpdateMuteListEntry(IClientAPI client, Packet Packet) 11058 private bool HandleUpdateMuteListEntry(IClientAPI client, Packet Packet)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index b575ed9..552c51e 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Collections.Concurrent;
30using System.Diagnostics; 31using System.Diagnostics;
31using System.IO; 32using System.IO;
32using System.Net; 33using System.Net;
@@ -285,7 +286,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
285 /// <summary>Incoming packets that are awaiting handling</summary> 286 /// <summary>Incoming packets that are awaiting handling</summary>
286 //protected OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 287 //protected OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
287 288
288 protected OpenSim.Framework.BlockingQueue<IncomingPacket> packetInbox = new OpenSim.Framework.BlockingQueue<IncomingPacket>(); 289 protected BlockingCollection<IncomingPacket> packetInbox = new BlockingCollection<IncomingPacket>();
289 290
290 /// <summary>Bandwidth throttle for this UDP server</summary> 291 /// <summary>Bandwidth throttle for this UDP server</summary>
291 public TokenBucket Throttle { get; protected set; } 292 public TokenBucket Throttle { get; protected set; }
@@ -712,7 +713,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
712 scene.Name, 713 scene.Name,
713 StatType.Pull, 714 StatType.Pull,
714 MeasuresOfInterest.AverageChangeOverTime, 715 MeasuresOfInterest.AverageChangeOverTime,
715 stat => stat.Value = packetInbox.Count(), 716 stat => {try{stat.Value = packetInbox.Count;}catch{}},
716 StatVerbosity.Debug)); 717 StatVerbosity.Debug));
717 718
718 // XXX: These stats are also pool stats but we register them separately since they are currently not 719 // XXX: These stats are also pool stats but we register them separately since they are currently not
@@ -898,7 +899,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
898 if (packet.Type == PacketType.CoarseLocationUpdate && allowSplitting) 899 if (packet.Type == PacketType.CoarseLocationUpdate && allowSplitting)
899 allowSplitting = false; 900 allowSplitting = false;
900 901
901 bool packetQueued = false; 902// bool packetQueued = false;
902 903
903 if (allowSplitting && packet.HasVariableBlocks) 904 if (allowSplitting && packet.HasVariableBlocks)
904 { 905 {
@@ -911,15 +912,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
911 for (int i = 0; i < packetCount; i++) 912 for (int i = 0; i < packetCount; i++)
912 { 913 {
913 byte[] data = datas[i]; 914 byte[] data = datas[i];
914 if (!SendPacketData(udpClient, data, packet.Type, category, method)) 915// if (!SendPacketData(udpClient, data, packet.Type, category, method))
915 packetQueued = true; 916// packetQueued = true;
917 SendPacketData(udpClient, data, packet.Type, category, method);
916 } 918 }
917 } 919 }
918 else 920 else
919 { 921 {
920 byte[] data = packet.ToBytes(); 922 byte[] data = packet.ToBytes();
921 if (!SendPacketData(udpClient, data, packet.Type, category, method)) 923// if (!SendPacketData(udpClient, data, packet.Type, category, method))
922 packetQueued = true; 924// packetQueued = true;
925 SendPacketData(udpClient, data, packet.Type, category, method);
923 } 926 }
924 927
925 PacketPool.Instance.ReturnPacket(packet); 928 PacketPool.Instance.ReturnPacket(packet);
@@ -1544,10 +1547,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1544 1547
1545// if (incomingPacket.Packet.Type == PacketType.AgentUpdate || 1548// if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
1546// incomingPacket.Packet.Type == PacketType.ChatFromViewer) 1549// incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1547 if (incomingPacket.Packet.Type == PacketType.ChatFromViewer) 1550// if (incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1548 packetInbox.PriorityEnqueue(incomingPacket); 1551// packetInbox.PriorityEnqueue(incomingPacket);
1549 else 1552// else
1550 packetInbox.Enqueue(incomingPacket); 1553// packetInbox.Enqueue(incomingPacket);
1554 packetInbox.Add(incomingPacket);
1551 1555
1552 } 1556 }
1553 1557
@@ -2016,7 +2020,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2016 Scene.ThreadAlive(1); 2020 Scene.ThreadAlive(1);
2017 try 2021 try
2018 { 2022 {
2019 incomingPacket = packetInbox.Dequeue(250); 2023 packetInbox.TryTake(out incomingPacket, 250);
2020 2024
2021 if (incomingPacket != null && IsRunningInbound) 2025 if (incomingPacket != null && IsRunningInbound)
2022 { 2026 {
@@ -2038,9 +2042,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2038 Watchdog.UpdateThread(); 2042 Watchdog.UpdateThread();
2039 } 2043 }
2040 2044
2041 if (packetInbox.Count() > 0) 2045 if (packetInbox.Count > 0)
2042 m_log.Warn("[LLUDPSERVER]: IncomingPacketHandler is shutting down, dropping " + packetInbox.Count() + " packets"); 2046 m_log.Warn("[LLUDPSERVER]: IncomingPacketHandler is shutting down, dropping " + packetInbox.Count + " packets");
2043 packetInbox.Clear(); 2047 packetInbox.Dispose();
2044 2048
2045 Watchdog.RemoveThread(); 2049 Watchdog.RemoveThread();
2046 } 2050 }