diff options
Diffstat (limited to 'OpenSim/Region/ClientStack')
10 files changed, 335 insertions, 255 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 6f5775a..daa40c4 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; |
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/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..736e18f 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,72 @@ 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; | 336 | response["reusecontext"] = false; |
338 | 337 | ||
339 | lock (responses) | 338 | responses[requestID] = new APollResponse() {bytes = 0, response = response}; |
340 | responses[requestID] = new aPollResponse() {bytes = 0, response = response}; | ||
341 | 339 | ||
342 | return; | 340 | return; |
341 | } | ||
343 | } | 342 | } |
344 | 343 | ||
345 | response = m_getTextureHandler.Handle(requestinfo.request); | 344 | response = m_getTextureHandler.Handle(requestinfo.request); |
345 | |||
346 | lock (responses) | 346 | lock (responses) |
347 | { | 347 | { |
348 | responses[requestID] = new aPollResponse() | 348 | lock(dropedResponses) |
349 | { | 349 | { |
350 | bytes = (int) response["int_bytes"], | 350 | if(dropedResponses.Contains(requestID)) |
351 | response = response | 351 | { |
352 | }; | 352 | dropedResponses.Remove(requestID); |
353 | 353 | m_throttler.PassTime(); | |
354 | } | 354 | return; |
355 | } | ||
356 | } | ||
357 | responses[requestID] = new APollResponse() | ||
358 | { | ||
359 | bytes = (int) response["int_bytes"], | ||
360 | response = response | ||
361 | }; | ||
362 | } | ||
355 | m_throttler.PassTime(); | 363 | m_throttler.PassTime(); |
356 | } | 364 | } |
357 | 365 | ||
@@ -415,12 +423,20 @@ namespace OpenSim.Region.ClientStack.Linden | |||
415 | 423 | ||
416 | private static void DoTextureRequests() | 424 | private static void DoTextureRequests() |
417 | { | 425 | { |
418 | while (true) | 426 | APollRequest poolreq; |
427 | while (m_NumberScenes > 0) | ||
419 | { | 428 | { |
420 | aPollRequest poolreq = m_queue.Dequeue(4500); | 429 | poolreq = null; |
421 | Watchdog.UpdateThread(); | 430 | if(!m_queue.TryTake(out poolreq, 4500) || poolreq == null) |
431 | { | ||
432 | Watchdog.UpdateThread(); | ||
433 | continue; | ||
434 | } | ||
435 | |||
422 | if(m_NumberScenes <= 0) | 436 | if(m_NumberScenes <= 0) |
423 | return; | 437 | break; |
438 | |||
439 | Watchdog.UpdateThread(); | ||
424 | if(poolreq.reqID != UUID.Zero) | 440 | if(poolreq.reqID != UUID.Zero) |
425 | poolreq.thepoll.Process(poolreq); | 441 | poolreq.thepoll.Process(poolreq); |
426 | } | 442 | } |
@@ -437,7 +453,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
437 | ThrottleBytes = pBytes; | 453 | ThrottleBytes = pBytes; |
438 | lastTimeElapsed = Util.GetTimeStampMS(); | 454 | lastTimeElapsed = Util.GetTimeStampMS(); |
439 | } | 455 | } |
440 | public bool hasEvents(UUID key, Dictionary<UUID, GetTextureModule.aPollResponse> responses) | 456 | public bool hasEvents(UUID key, Dictionary<UUID, GetTextureModule.APollResponse> responses) |
441 | { | 457 | { |
442 | PassTime(); | 458 | PassTime(); |
443 | // Note, this is called IN LOCK | 459 | // Note, this is called IN LOCK |
@@ -446,7 +462,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
446 | { | 462 | { |
447 | return false; | 463 | return false; |
448 | } | 464 | } |
449 | GetTextureModule.aPollResponse response; | 465 | GetTextureModule.APollResponse response; |
450 | if (responses.TryGetValue(key, out response)) | 466 | if (responses.TryGetValue(key, out response)) |
451 | { | 467 | { |
452 | // This is any error response | 468 | // This is any error response |
@@ -476,7 +492,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
476 | return; | 492 | return; |
477 | int add = (int)(ThrottleBytes * timeElapsed * 0.001); | 493 | int add = (int)(ThrottleBytes * timeElapsed * 0.001); |
478 | if (add >= 1000) | 494 | if (add >= 1000) |
479 | { | 495 | { |
480 | lastTimeElapsed = currenttime; | 496 | lastTimeElapsed = currenttime; |
481 | BytesSent -= add; | 497 | BytesSent -= add; |
482 | if (BytesSent < 0) BytesSent = 0; | 498 | 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..f6d49ee 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) => |
@@ -358,13 +370,26 @@ namespace OpenSim.Region.ClientStack.Linden | |||
358 | }; | 370 | }; |
359 | } | 371 | } |
360 | 372 | ||
361 | public void Process(aPollRequest requestinfo) | 373 | public void Process(APollRequest requestinfo) |
362 | { | 374 | { |
363 | if(m_module == null || m_module.Scene == null || m_module.Scene.ShuttingDown) | 375 | if(m_module == null || m_module.Scene == null || m_module.Scene.ShuttingDown) |
364 | return; | 376 | return; |
365 | 377 | ||
366 | UUID requestID = requestinfo.reqID; | 378 | UUID requestID = requestinfo.reqID; |
367 | 379 | ||
380 | |||
381 | lock(responses) | ||
382 | { | ||
383 | lock(dropedResponses) | ||
384 | { | ||
385 | if(dropedResponses.Contains(requestID)) | ||
386 | { | ||
387 | dropedResponses.Remove(requestID); | ||
388 | return; | ||
389 | } | ||
390 | } | ||
391 | } | ||
392 | |||
368 | Hashtable response = new Hashtable(); | 393 | Hashtable response = new Hashtable(); |
369 | 394 | ||
370 | response["int_response_code"] = 200; | 395 | response["int_response_code"] = 200; |
@@ -377,11 +402,21 @@ namespace OpenSim.Region.ClientStack.Linden | |||
377 | 402 | ||
378 | lock (responses) | 403 | lock (responses) |
379 | { | 404 | { |
405 | lock(dropedResponses) | ||
406 | { | ||
407 | if(dropedResponses.Contains(requestID)) | ||
408 | { | ||
409 | dropedResponses.Remove(requestID); | ||
410 | requestinfo.request.Clear(); | ||
411 | WebFetchInvDescModule.ProcessedRequestsCount++; | ||
412 | return; | ||
413 | } | ||
414 | } | ||
415 | |||
380 | if (responses.ContainsKey(requestID)) | 416 | 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"); | 417 | m_log.WarnFormat("[FETCH INVENTORY DESCENDENTS2 MODULE]: Caught in the act of loosing responses! Please report this on mantis #7054"); |
382 | responses[requestID] = response; | 418 | responses[requestID] = response; |
383 | } | 419 | } |
384 | requestinfo.folders.Clear(); | ||
385 | requestinfo.request.Clear(); | 420 | requestinfo.request.Clear(); |
386 | WebFetchInvDescModule.ProcessedRequestsCount++; | 421 | WebFetchInvDescModule.ProcessedRequestsCount++; |
387 | } | 422 | } |
@@ -441,23 +476,26 @@ namespace OpenSim.Region.ClientStack.Linden | |||
441 | 476 | ||
442 | private static void DoInventoryRequests() | 477 | private static void DoInventoryRequests() |
443 | { | 478 | { |
479 | APollRequest poolreq; | ||
444 | while (true) | 480 | while (true) |
445 | { | 481 | { |
446 | aPollRequest poolreq = m_queue.Dequeue(4500); | 482 | if(!m_queue.TryTake(out poolreq, 4500) || poolreq == null || poolreq.thepoll == null) |
447 | Watchdog.UpdateThread(); | 483 | { |
484 | Watchdog.UpdateThread(); | ||
485 | continue; | ||
486 | } | ||
448 | 487 | ||
449 | if (poolreq != null && poolreq.thepoll != null) | 488 | Watchdog.UpdateThread(); |
489 | try | ||
450 | { | 490 | { |
451 | try | 491 | APollRequest req = poolreq; |
452 | { | 492 | req.thepoll.Process(req); |
453 | poolreq.thepoll.Process(poolreq); | 493 | } |
454 | } | 494 | catch (Exception e) |
455 | catch (Exception e) | 495 | { |
456 | { | 496 | m_log.ErrorFormat( |
457 | m_log.ErrorFormat( | 497 | "[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}", | 498 | poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", e); |
459 | poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", e); | ||
460 | } | ||
461 | } | 499 | } |
462 | } | 500 | } |
463 | } | 501 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 2ff6ced..ee7df5a 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -335,7 +335,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
335 | private readonly byte[] m_channelVersion = Utils.EmptyBytes; | 335 | private readonly byte[] m_channelVersion = Utils.EmptyBytes; |
336 | private readonly IGroupsModule m_GroupsModule; | 336 | private readonly IGroupsModule m_GroupsModule; |
337 | 337 | ||
338 | private int m_cachedTextureSerial; | 338 | // private int m_cachedTextureSerial; |
339 | private PriorityQueue m_entityUpdates; | 339 | private PriorityQueue m_entityUpdates; |
340 | private PriorityQueue m_entityProps; | 340 | private PriorityQueue m_entityProps; |
341 | private Prioritizer m_prioritizer; | 341 | private Prioritizer m_prioritizer; |
@@ -11039,9 +11039,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11039 | if(muteListRequest.MuteData.MuteCRC == 0) | 11039 | if(muteListRequest.MuteData.MuteCRC == 0) |
11040 | SendEmpytMuteList(); | 11040 | SendEmpytMuteList(); |
11041 | else | 11041 | else |
11042 | SendUseCachedMuteList(); | 11042 | SendUseCachedMuteList(); |
11043 | } | 11043 | } |
11044 | return true; | 11044 | return true; |
11045 | } | 11045 | } |
11046 | 11046 | ||
11047 | private bool HandleUpdateMuteListEntry(IClientAPI client, Packet Packet) | 11047 | 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 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Collections.Concurrent; | ||
30 | using System.Diagnostics; | 31 | using System.Diagnostics; |
31 | using System.IO; | 32 | using System.IO; |
32 | using System.Net; | 33 | using 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 | } |