diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/Caps')
5 files changed, 204 insertions, 138 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 7c9a1c4..9ccfd5d 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; |
@@ -292,8 +292,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
292 | Queue<OSD> queue; | 292 | Queue<OSD> queue; |
293 | Random rnd = new Random(Environment.TickCount); | 293 | Random rnd = new Random(Environment.TickCount); |
294 | int nrnd = rnd.Next(30000000); | 294 | int nrnd = rnd.Next(30000000); |
295 | if (nrnd < 0) | ||
296 | nrnd = -nrnd; | ||
297 | 295 | ||
298 | lock (queues) | 296 | lock (queues) |
299 | { | 297 | { |
@@ -307,21 +305,11 @@ namespace OpenSim.Region.ClientStack.Linden | |||
307 | queue = new Queue<OSD>(); | 305 | queue = new Queue<OSD>(); |
308 | queues[agentID] = queue; | 306 | queues[agentID] = queue; |
309 | 307 | ||
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) | 308 | lock (m_AvatarQueueUUIDMapping) |
317 | { | 309 | { |
318 | eventQueueGetUUID = UUID.Random(); | 310 | eventQueueGetUUID = UUID.Random(); |
319 | if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) | 311 | while(m_AvatarQueueUUIDMapping.ContainsKey(agentID)) |
320 | { | 312 | 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); | 313 | m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); |
326 | } | 314 | } |
327 | lock (m_ids) | 315 | lock (m_ids) |
@@ -329,18 +317,14 @@ namespace OpenSim.Region.ClientStack.Linden | |||
329 | if (!m_ids.ContainsKey(agentID)) | 317 | if (!m_ids.ContainsKey(agentID)) |
330 | m_ids.Add(agentID, nrnd); | 318 | m_ids.Add(agentID, nrnd); |
331 | else | 319 | else |
332 | m_ids[agentID] = nrnd; | 320 | m_ids[agentID]++; |
333 | } | 321 | } |
334 | } | 322 | } |
335 | else | 323 | else |
336 | { | 324 | { |
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); | 325 | queue.Enqueue(null); |
341 | queue.Enqueue(null); // one should be enough | 326 | queue.Enqueue(null); // one should be enough |
342 | 327 | // reuse or not to reuse | |
343 | // reuse or not to reuse TODO FIX | ||
344 | lock (m_AvatarQueueUUIDMapping) | 328 | lock (m_AvatarQueueUUIDMapping) |
345 | { | 329 | { |
346 | // Reuse open queues. The client does! | 330 | // Reuse open queues. The client does! |
@@ -349,30 +333,39 @@ namespace OpenSim.Region.ClientStack.Linden | |||
349 | { | 333 | { |
350 | m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); | 334 | m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); |
351 | eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; | 335 | eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; |
336 | lock (m_ids) | ||
337 | { | ||
338 | // change to negative numbers so they are changed at end of sending first marker | ||
339 | // old data on a queue may be sent on a response for a new caps | ||
340 | // but at least will be sent with coerent IDs | ||
341 | if (!m_ids.ContainsKey(agentID)) | ||
342 | m_ids.Add(agentID, -nrnd); // should not happen | ||
343 | else | ||
344 | m_ids[agentID] = -m_ids[agentID]; | ||
345 | } | ||
352 | } | 346 | } |
353 | else | 347 | else |
354 | { | 348 | { |
355 | eventQueueGetUUID = UUID.Random(); | 349 | eventQueueGetUUID = UUID.Random(); |
350 | while(m_AvatarQueueUUIDMapping.ContainsKey(agentID)) | ||
351 | eventQueueGetUUID = UUID.Random(); | ||
356 | m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); | 352 | m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); |
357 | m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); | 353 | m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); |
354 | lock (m_ids) | ||
355 | { | ||
356 | if (!m_ids.ContainsKey(agentID)) | ||
357 | m_ids.Add(agentID, nrnd); | ||
358 | else | ||
359 | m_ids[agentID]++; | ||
360 | } | ||
358 | } | 361 | } |
359 | } | 362 | } |
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 | } | 363 | } |
371 | } | 364 | } |
372 | 365 | ||
373 | caps.RegisterPollHandler( | 366 | caps.RegisterPollHandler( |
374 | "EventQueueGet", | 367 | "EventQueueGet", |
375 | new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS)); | 368 | new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, Drop, agentID, SERVER_EQ_TIME_NO_EVENTS)); |
376 | } | 369 | } |
377 | 370 | ||
378 | public bool HasEvents(UUID requestID, UUID agentID) | 371 | public bool HasEvents(UUID requestID, UUID agentID) |
@@ -448,7 +441,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
448 | if (DebugLevel > 0) | 441 | if (DebugLevel > 0) |
449 | LogOutboundDebugMessage(element, pAgentId); | 442 | LogOutboundDebugMessage(element, pAgentId); |
450 | array.Add(element); | 443 | array.Add(element); |
451 | thisID++; | ||
452 | } | 444 | } |
453 | } | 445 | } |
454 | 446 | ||
@@ -465,8 +457,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
465 | { | 457 | { |
466 | Random rnd = new Random(Environment.TickCount); | 458 | Random rnd = new Random(Environment.TickCount); |
467 | thisID = rnd.Next(30000000); | 459 | thisID = rnd.Next(30000000); |
468 | if (thisID < 0) | ||
469 | thisID = -thisID; | ||
470 | } | 460 | } |
471 | 461 | ||
472 | lock (m_ids) | 462 | lock (m_ids) |
@@ -474,16 +464,19 @@ namespace OpenSim.Region.ClientStack.Linden | |||
474 | m_ids[pAgentId] = thisID + 1; | 464 | m_ids[pAgentId] = thisID + 1; |
475 | } | 465 | } |
476 | 466 | ||
467 | Hashtable responsedata; | ||
477 | // if there where no elements before a marker send a NoEvents | 468 | // if there where no elements before a marker send a NoEvents |
478 | if (array.Count == 0) | 469 | if (events == null) |
479 | return NoEvents(requestID, pAgentId); | 470 | { |
480 | 471 | return NoEvents(requestID, pAgentId); | |
481 | Hashtable responsedata = new Hashtable(); | 472 | } |
482 | responsedata["int_response_code"] = 200; | 473 | else |
483 | responsedata["content_type"] = "application/xml"; | 474 | { |
484 | responsedata["keepalive"] = false; | 475 | responsedata = new Hashtable(); |
485 | responsedata["reusecontext"] = false; | 476 | responsedata["int_response_code"] = 200; |
486 | responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events); | 477 | responsedata["content_type"] = "application/xml"; |
478 | responsedata["bin_response_data"] = Encoding.UTF8.GetBytes(OSDParser.SerializeLLSDXmlString(events)); | ||
479 | } | ||
487 | //m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", pAgentId, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]); | 480 | //m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", pAgentId, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]); |
488 | return responsedata; | 481 | return responsedata; |
489 | } | 482 | } |
@@ -493,13 +486,13 @@ namespace OpenSim.Region.ClientStack.Linden | |||
493 | Hashtable responsedata = new Hashtable(); | 486 | Hashtable responsedata = new Hashtable(); |
494 | responsedata["int_response_code"] = 502; | 487 | responsedata["int_response_code"] = 502; |
495 | responsedata["content_type"] = "text/plain"; | 488 | responsedata["content_type"] = "text/plain"; |
496 | responsedata["keepalive"] = false; | ||
497 | responsedata["reusecontext"] = false; | ||
498 | responsedata["str_response_string"] = "<llsd></llsd>"; | 489 | responsedata["str_response_string"] = "<llsd></llsd>"; |
499 | responsedata["error_status_text"] = "<llsd></llsd>"; | 490 | responsedata["error_status_text"] = "<llsd></llsd>"; |
500 | responsedata["http_protocol_version"] = "HTTP/1.0"; | 491 | responsedata["http_protocol_version"] = "HTTP/1.0"; |
492 | responsedata["keepalive"] = false; | ||
501 | return responsedata; | 493 | return responsedata; |
502 | } | 494 | } |
495 | |||
503 | /* this is not a event message | 496 | /* this is not a event message |
504 | public void DisableSimulator(ulong handle, UUID avatarID) | 497 | public void DisableSimulator(ulong handle, UUID avatarID) |
505 | { | 498 | { |
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..87ded7b 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs | |||
@@ -76,7 +76,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
76 | { | 76 | { |
77 | public Hashtable response; | 77 | public Hashtable response; |
78 | public int bytes; | 78 | public int bytes; |
79 | public int lod; | ||
80 | } | 79 | } |
81 | 80 | ||
82 | 81 | ||
@@ -231,11 +230,12 @@ namespace OpenSim.Region.ClientStack.Linden | |||
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) |
@@ -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 | { |
351 | lock(dropedResponses) | ||
352 | { | ||
353 | if(dropedResponses.Contains(requestID)) | ||
354 | { | ||
355 | dropedResponses.Remove(requestID); | ||
356 | return; | ||
357 | } | ||
358 | } | ||
359 | |||
330 | responses[requestID] = new aPollResponse() | 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 | ||
@@ -443,7 +472,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
443 | return; | 472 | return; |
444 | int add = (int)(ThrottleBytes * timeElapsed * 0.001); | 473 | int add = (int)(ThrottleBytes * timeElapsed * 0.001); |
445 | if (add >= 1000) | 474 | if (add >= 1000) |
446 | { | 475 | { |
447 | lastTimeElapsed = currenttime; | 476 | lastTimeElapsed = currenttime; |
448 | BytesSent -= add; | 477 | BytesSent -= add; |
449 | if (BytesSent < 0) BytesSent = 0; | 478 | if (BytesSent < 0) BytesSent = 0; |
@@ -451,6 +480,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
451 | } | 480 | } |
452 | 481 | ||
453 | public int ThrottleBytes; | 482 | public int ThrottleBytes; |
454 | } | 483 | } |
455 | } | 484 | } |
456 | } | 485 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index b01c7dc..9a561ea 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs | |||
@@ -146,39 +146,13 @@ namespace OpenSim.Region.ClientStack.Linden | |||
146 | } | 146 | } |
147 | } | 147 | } |
148 | } | 148 | } |
149 | private int ExtractImageThrottle(byte[] pthrottles) | 149 | |
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. | 150 | // 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) | 151 | public void ThrottleUpdate(ScenePresence p) |
178 | { | 152 | { |
179 | byte[] throttles = p.ControllingClient.GetThrottlesPacked(1); | 153 | byte[] throttles = p.ControllingClient.GetThrottlesPacked(1); |
180 | UUID user = p.UUID; | 154 | UUID user = p.UUID; |
181 | int imagethrottle = ExtractImageThrottle(throttles); | 155 | int imagethrottle = p.ControllingClient.GetAgentThrottleSilent((int)ThrottleOutPacketType.Texture); |
182 | PollServiceTextureEventArgs args; | 156 | PollServiceTextureEventArgs args; |
183 | if (m_pollservices.TryGetValue(user,out args)) | 157 | if (m_pollservices.TryGetValue(user,out args)) |
184 | { | 158 | { |
@@ -218,13 +192,15 @@ namespace OpenSim.Region.ClientStack.Linden | |||
218 | new List<Hashtable>(); | 192 | new List<Hashtable>(); |
219 | private Dictionary<UUID, aPollResponse> responses = | 193 | private Dictionary<UUID, aPollResponse> responses = |
220 | new Dictionary<UUID, aPollResponse>(); | 194 | new Dictionary<UUID, aPollResponse>(); |
195 | private HashSet<UUID> dropedResponses = new HashSet<UUID>(); | ||
221 | 196 | ||
222 | private Scene m_scene; | 197 | private Scene m_scene; |
223 | private CapsDataThrottler m_throttler = new CapsDataThrottler(100000); | 198 | private CapsDataThrottler m_throttler; |
224 | public PollServiceTextureEventArgs(UUID pId, Scene scene) : | 199 | public PollServiceTextureEventArgs(UUID pId, Scene scene) : |
225 | base(null, "", null, null, null, pId, int.MaxValue) | 200 | base(null, "", null, null, null, null, pId, int.MaxValue) |
226 | { | 201 | { |
227 | m_scene = scene; | 202 | m_scene = scene; |
203 | m_throttler = new CapsDataThrottler(100000); | ||
228 | // x is request id, y is userid | 204 | // x is request id, y is userid |
229 | HasEvents = (x, y) => | 205 | HasEvents = (x, y) => |
230 | { | 206 | { |
@@ -235,6 +211,16 @@ namespace OpenSim.Region.ClientStack.Linden | |||
235 | 211 | ||
236 | } | 212 | } |
237 | }; | 213 | }; |
214 | |||
215 | Drop = (x, y) => | ||
216 | { | ||
217 | lock (responses) | ||
218 | { | ||
219 | responses.Remove(x); | ||
220 | dropedResponses.Add(x); | ||
221 | } | ||
222 | }; | ||
223 | |||
238 | GetEvents = (x, y) => | 224 | GetEvents = (x, y) => |
239 | { | 225 | { |
240 | lock (responses) | 226 | lock (responses) |
@@ -305,53 +291,72 @@ namespace OpenSim.Region.ClientStack.Linden | |||
305 | if(m_scene.ShuttingDown) | 291 | if(m_scene.ShuttingDown) |
306 | return; | 292 | return; |
307 | 293 | ||
308 | if (requestinfo.send503) | 294 | lock (responses) |
309 | { | 295 | { |
310 | response = new Hashtable(); | 296 | lock(dropedResponses) |
297 | { | ||
298 | if(dropedResponses.Contains(requestID)) | ||
299 | { | ||
300 | dropedResponses.Remove(requestID); | ||
301 | return; | ||
302 | } | ||
303 | } | ||
311 | 304 | ||
312 | response["int_response_code"] = 503; | 305 | if (requestinfo.send503) |
313 | response["str_response_string"] = "Throttled"; | 306 | { |
314 | response["content_type"] = "text/plain"; | 307 | response = new Hashtable(); |
315 | response["keepalive"] = false; | ||
316 | response["reusecontext"] = false; | ||
317 | 308 | ||
318 | Hashtable headers = new Hashtable(); | 309 | response["int_response_code"] = 503; |
319 | headers["Retry-After"] = 30; | 310 | response["str_response_string"] = "Throttled"; |
320 | response["headers"] = headers; | 311 | response["content_type"] = "text/plain"; |
312 | response["keepalive"] = false; | ||
313 | response["reusecontext"] = false; | ||
314 | |||
315 | Hashtable headers = new Hashtable(); | ||
316 | headers["Retry-After"] = 30; | ||
317 | response["headers"] = headers; | ||
321 | 318 | ||
322 | lock (responses) | ||
323 | responses[requestID] = new aPollResponse() {bytes = 0, response = response}; | 319 | responses[requestID] = new aPollResponse() {bytes = 0, response = response}; |
324 | 320 | ||
325 | return; | 321 | return; |
326 | } | 322 | } |
327 | 323 | ||
328 | // If the avatar is gone, don't bother to get the texture | 324 | // If the avatar is gone, don't bother to get the texture |
329 | if (m_scene.GetScenePresence(Id) == null) | 325 | if (m_scene.GetScenePresence(Id) == null) |
330 | { | 326 | { |
331 | response = new Hashtable(); | 327 | response = new Hashtable(); |
332 | 328 | ||
333 | response["int_response_code"] = 500; | 329 | response["int_response_code"] = 500; |
334 | response["str_response_string"] = "Script timeout"; | 330 | response["str_response_string"] = "Script timeout"; |
335 | response["content_type"] = "text/plain"; | 331 | response["content_type"] = "text/plain"; |
336 | response["keepalive"] = false; | 332 | response["keepalive"] = false; |
337 | response["reusecontext"] = false; | 333 | response["reusecontext"] = false; |
338 | 334 | ||
339 | lock (responses) | ||
340 | responses[requestID] = new aPollResponse() {bytes = 0, response = response}; | 335 | responses[requestID] = new aPollResponse() {bytes = 0, response = response}; |
341 | 336 | ||
342 | return; | 337 | return; |
338 | } | ||
343 | } | 339 | } |
344 | 340 | ||
345 | response = m_getTextureHandler.Handle(requestinfo.request); | 341 | response = m_getTextureHandler.Handle(requestinfo.request); |
342 | |||
346 | lock (responses) | 343 | lock (responses) |
347 | { | 344 | { |
345 | lock(dropedResponses) | ||
346 | { | ||
347 | if(dropedResponses.Contains(requestID)) | ||
348 | { | ||
349 | dropedResponses.Remove(requestID); | ||
350 | m_throttler.PassTime(); | ||
351 | return; | ||
352 | } | ||
353 | } | ||
348 | responses[requestID] = new aPollResponse() | 354 | responses[requestID] = new aPollResponse() |
349 | { | 355 | { |
350 | bytes = (int) response["int_bytes"], | 356 | bytes = (int) response["int_bytes"], |
351 | response = response | 357 | response = response |
352 | }; | 358 | }; |
353 | 359 | } | |
354 | } | ||
355 | m_throttler.PassTime(); | 360 | m_throttler.PassTime(); |
356 | } | 361 | } |
357 | 362 | ||
@@ -476,7 +481,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
476 | return; | 481 | return; |
477 | int add = (int)(ThrottleBytes * timeElapsed * 0.001); | 482 | int add = (int)(ThrottleBytes * timeElapsed * 0.001); |
478 | if (add >= 1000) | 483 | if (add >= 1000) |
479 | { | 484 | { |
480 | lastTimeElapsed = currenttime; | 485 | lastTimeElapsed = currenttime; |
481 | BytesSent -= add; | 486 | BytesSent -= add; |
482 | if (BytesSent < 0) BytesSent = 0; | 487 | if (BytesSent < 0) BytesSent = 0; |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 8d4e561..9cfa488 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs | |||
@@ -61,7 +61,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
61 | public UUID reqID; | 61 | public UUID reqID; |
62 | public Hashtable request; | 62 | public Hashtable request; |
63 | public ScenePresence presence; | 63 | public ScenePresence presence; |
64 | public List<UUID> folders; | ||
65 | } | 64 | } |
66 | 65 | ||
67 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 66 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
@@ -250,17 +249,28 @@ namespace OpenSim.Region.ClientStack.Linden | |||
250 | { | 249 | { |
251 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 250 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
252 | 251 | ||
253 | private Dictionary<UUID, Hashtable> responses = | 252 | private Dictionary<UUID, Hashtable> responses = new Dictionary<UUID, Hashtable>(); |
254 | new Dictionary<UUID, Hashtable>(); | 253 | private HashSet<UUID> dropedResponses = new HashSet<UUID>(); |
255 | 254 | ||
256 | private WebFetchInvDescModule m_module; | 255 | private WebFetchInvDescModule m_module; |
257 | 256 | ||
258 | public PollServiceInventoryEventArgs(WebFetchInvDescModule module, string url, UUID pId) : | 257 | public PollServiceInventoryEventArgs(WebFetchInvDescModule module, string url, UUID pId) : |
259 | base(null, url, null, null, null, pId, int.MaxValue) | 258 | base(null, url, null, null, null, null, pId, int.MaxValue) |
260 | { | 259 | { |
261 | m_module = module; | 260 | m_module = module; |
262 | 261 | ||
263 | HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; | 262 | HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; |
263 | |||
264 | Drop = (x, y) => | ||
265 | { | ||
266 | lock (responses) | ||
267 | { | ||
268 | responses.Remove(x); | ||
269 | lock(dropedResponses) | ||
270 | dropedResponses.Add(x); | ||
271 | } | ||
272 | }; | ||
273 | |||
264 | GetEvents = (x, y) => | 274 | GetEvents = (x, y) => |
265 | { | 275 | { |
266 | lock (responses) | 276 | lock (responses) |
@@ -285,8 +295,10 @@ namespace OpenSim.Region.ClientStack.Linden | |||
285 | reqinfo.reqID = x; | 295 | reqinfo.reqID = x; |
286 | reqinfo.request = y; | 296 | reqinfo.request = y; |
287 | reqinfo.presence = sp; | 297 | reqinfo.presence = sp; |
288 | reqinfo.folders = new List<UUID>(); | ||
289 | 298 | ||
299 | /* why where we doing this? just to get cof ? | ||
300 | List<UUID> folders = new List<UUID>(); | ||
301 | |||
290 | // Decode the request here | 302 | // Decode the request here |
291 | string request = y["body"].ToString(); | 303 | string request = y["body"].ToString(); |
292 | 304 | ||
@@ -322,11 +334,11 @@ namespace OpenSim.Region.ClientStack.Linden | |||
322 | UUID folderID; | 334 | UUID folderID; |
323 | if (UUID.TryParse(folder, out folderID)) | 335 | if (UUID.TryParse(folder, out folderID)) |
324 | { | 336 | { |
325 | if (!reqinfo.folders.Contains(folderID)) | 337 | if (!folders.Contains(folderID)) |
326 | { | 338 | { |
327 | if (sp.COF != UUID.Zero && sp.COF == folderID) | 339 | if (sp.COF != UUID.Zero && sp.COF == folderID) |
328 | highPriority = true; | 340 | highPriority = true; |
329 | reqinfo.folders.Add(folderID); | 341 | folders.Add(folderID); |
330 | } | 342 | } |
331 | } | 343 | } |
332 | } | 344 | } |
@@ -334,6 +346,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
334 | if (highPriority) | 346 | if (highPriority) |
335 | m_queue.PriorityEnqueue(reqinfo); | 347 | m_queue.PriorityEnqueue(reqinfo); |
336 | else | 348 | else |
349 | */ | ||
337 | m_queue.Enqueue(reqinfo); | 350 | m_queue.Enqueue(reqinfo); |
338 | }; | 351 | }; |
339 | 352 | ||
@@ -365,6 +378,19 @@ namespace OpenSim.Region.ClientStack.Linden | |||
365 | 378 | ||
366 | UUID requestID = requestinfo.reqID; | 379 | UUID requestID = requestinfo.reqID; |
367 | 380 | ||
381 | |||
382 | lock(responses) | ||
383 | { | ||
384 | lock(dropedResponses) | ||
385 | { | ||
386 | if(dropedResponses.Contains(requestID)) | ||
387 | { | ||
388 | dropedResponses.Remove(requestID); | ||
389 | return; | ||
390 | } | ||
391 | } | ||
392 | } | ||
393 | |||
368 | Hashtable response = new Hashtable(); | 394 | Hashtable response = new Hashtable(); |
369 | 395 | ||
370 | response["int_response_code"] = 200; | 396 | response["int_response_code"] = 200; |
@@ -377,11 +403,21 @@ namespace OpenSim.Region.ClientStack.Linden | |||
377 | 403 | ||
378 | lock (responses) | 404 | lock (responses) |
379 | { | 405 | { |
406 | lock(dropedResponses) | ||
407 | { | ||
408 | if(dropedResponses.Contains(requestID)) | ||
409 | { | ||
410 | dropedResponses.Remove(requestID); | ||
411 | requestinfo.request.Clear(); | ||
412 | WebFetchInvDescModule.ProcessedRequestsCount++; | ||
413 | return; | ||
414 | } | ||
415 | } | ||
416 | |||
380 | if (responses.ContainsKey(requestID)) | 417 | 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"); | 418 | m_log.WarnFormat("[FETCH INVENTORY DESCENDENTS2 MODULE]: Caught in the act of loosing responses! Please report this on mantis #7054"); |
382 | responses[requestID] = response; | 419 | responses[requestID] = response; |
383 | } | 420 | } |
384 | requestinfo.folders.Clear(); | ||
385 | requestinfo.request.Clear(); | 421 | requestinfo.request.Clear(); |
386 | WebFetchInvDescModule.ProcessedRequestsCount++; | 422 | WebFetchInvDescModule.ProcessedRequestsCount++; |
387 | } | 423 | } |