aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs1
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs90
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs18
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs11
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs137
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs194
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs1
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs98
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs6
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs34
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;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Net; 31using System.Net;
32using System.Reflection; 32using System.Reflection;
33using System.Threading; 33using System.Text;
34using log4net; 34using log4net;
35using Nini.Config; 35using Nini.Config;
36using Mono.Addins; 36using Mono.Addins;
@@ -44,7 +44,6 @@ using OpenSim.Framework.Servers;
44using OpenSim.Framework.Servers.HttpServer; 44using OpenSim.Framework.Servers.HttpServer;
45using OpenSim.Region.Framework.Interfaces; 45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 46using OpenSim.Region.Framework.Scenes;
47using BlockingLLSDQueue = OpenSim.Framework.BlockingQueue<OpenMetaverse.StructuredData.OSD>;
48using Caps=OpenSim.Framework.Capabilities.Caps; 47using Caps=OpenSim.Framework.Capabilities.Caps;
49 48
50namespace OpenSim.Region.ClientStack.Linden 49namespace OpenSim.Region.ClientStack.Linden
@@ -292,8 +291,6 @@ namespace OpenSim.Region.ClientStack.Linden
292 Queue<OSD> queue; 291 Queue<OSD> queue;
293 Random rnd = new Random(Environment.TickCount); 292 Random rnd = new Random(Environment.TickCount);
294 int nrnd = rnd.Next(30000000); 293 int nrnd = rnd.Next(30000000);
295 if (nrnd < 0)
296 nrnd = -nrnd;
297 294
298 lock (queues) 295 lock (queues)
299 { 296 {
@@ -307,21 +304,11 @@ namespace OpenSim.Region.ClientStack.Linden
307 queue = new Queue<OSD>(); 304 queue = new Queue<OSD>();
308 queues[agentID] = queue; 305 queues[agentID] = queue;
309 306
310 // push markers to handle old responses still waiting
311 // this will cost at most viewer getting two forced noevents
312 // even being a new queue better be safe
313 queue.Enqueue(null);
314 queue.Enqueue(null); // one should be enough
315
316 lock (m_AvatarQueueUUIDMapping) 307 lock (m_AvatarQueueUUIDMapping)
317 { 308 {
318 eventQueueGetUUID = UUID.Random(); 309 eventQueueGetUUID = UUID.Random();
319 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) 310 while(m_AvatarQueueUUIDMapping.ContainsKey(agentID))
320 { 311 eventQueueGetUUID = UUID.Random();
321 // oops this should not happen ?
322 m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID without a queue");
323 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
324 }
325 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); 312 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
326 } 313 }
327 lock (m_ids) 314 lock (m_ids)
@@ -329,18 +316,14 @@ namespace OpenSim.Region.ClientStack.Linden
329 if (!m_ids.ContainsKey(agentID)) 316 if (!m_ids.ContainsKey(agentID))
330 m_ids.Add(agentID, nrnd); 317 m_ids.Add(agentID, nrnd);
331 else 318 else
332 m_ids[agentID] = nrnd; 319 m_ids[agentID]++;
333 } 320 }
334 } 321 }
335 else 322 else
336 { 323 {
337 // push markers to handle old responses still waiting
338 // this will cost at most viewer getting two forced noevents
339 // even being a new queue better be safe
340 queue.Enqueue(null); 324 queue.Enqueue(null);
341 queue.Enqueue(null); // one should be enough 325 queue.Enqueue(null); // one should be enough
342 326 // reuse or not to reuse
343 // reuse or not to reuse TODO FIX
344 lock (m_AvatarQueueUUIDMapping) 327 lock (m_AvatarQueueUUIDMapping)
345 { 328 {
346 // Reuse open queues. The client does! 329 // Reuse open queues. The client does!
@@ -349,30 +332,39 @@ namespace OpenSim.Region.ClientStack.Linden
349 { 332 {
350 m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); 333 m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
351 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; 334 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
335 lock (m_ids)
336 {
337 // change to negative numbers so they are changed at end of sending first marker
338 // old data on a queue may be sent on a response for a new caps
339 // but at least will be sent with coerent IDs
340 if (!m_ids.ContainsKey(agentID))
341 m_ids.Add(agentID, -nrnd); // should not happen
342 else
343 m_ids[agentID] = -m_ids[agentID];
344 }
352 } 345 }
353 else 346 else
354 { 347 {
355 eventQueueGetUUID = UUID.Random(); 348 eventQueueGetUUID = UUID.Random();
349 while(m_AvatarQueueUUIDMapping.ContainsKey(agentID))
350 eventQueueGetUUID = UUID.Random();
356 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); 351 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
357 m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); 352 m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
353 lock (m_ids)
354 {
355 if (!m_ids.ContainsKey(agentID))
356 m_ids.Add(agentID, nrnd);
357 else
358 m_ids[agentID]++;
359 }
358 } 360 }
359 } 361 }
360 lock (m_ids)
361 {
362 // change to negative numbers so they are changed at end of sending first marker
363 // old data on a queue may be sent on a response for a new caps
364 // but at least will be sent with coerent IDs
365 if (!m_ids.ContainsKey(agentID))
366 m_ids.Add(agentID, -nrnd); // should not happen
367 else
368 m_ids[agentID] = -m_ids[agentID];
369 }
370 } 362 }
371 } 363 }
372 364
373 caps.RegisterPollHandler( 365 caps.RegisterPollHandler(
374 "EventQueueGet", 366 "EventQueueGet",
375 new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS)); 367 new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, Drop, agentID, SERVER_EQ_TIME_NO_EVENTS));
376 } 368 }
377 369
378 public bool HasEvents(UUID requestID, UUID agentID) 370 public bool HasEvents(UUID requestID, UUID agentID)
@@ -448,7 +440,6 @@ namespace OpenSim.Region.ClientStack.Linden
448 if (DebugLevel > 0) 440 if (DebugLevel > 0)
449 LogOutboundDebugMessage(element, pAgentId); 441 LogOutboundDebugMessage(element, pAgentId);
450 array.Add(element); 442 array.Add(element);
451 thisID++;
452 } 443 }
453 } 444 }
454 445
@@ -465,8 +456,6 @@ namespace OpenSim.Region.ClientStack.Linden
465 { 456 {
466 Random rnd = new Random(Environment.TickCount); 457 Random rnd = new Random(Environment.TickCount);
467 thisID = rnd.Next(30000000); 458 thisID = rnd.Next(30000000);
468 if (thisID < 0)
469 thisID = -thisID;
470 } 459 }
471 460
472 lock (m_ids) 461 lock (m_ids)
@@ -474,16 +463,19 @@ namespace OpenSim.Region.ClientStack.Linden
474 m_ids[pAgentId] = thisID + 1; 463 m_ids[pAgentId] = thisID + 1;
475 } 464 }
476 465
466 Hashtable responsedata;
477 // if there where no elements before a marker send a NoEvents 467 // if there where no elements before a marker send a NoEvents
478 if (array.Count == 0) 468 if (events == null)
479 return NoEvents(requestID, pAgentId); 469 {
480 470 return NoEvents(requestID, pAgentId);
481 Hashtable responsedata = new Hashtable(); 471 }
482 responsedata["int_response_code"] = 200; 472 else
483 responsedata["content_type"] = "application/xml"; 473 {
484 responsedata["keepalive"] = false; 474 responsedata = new Hashtable();
485 responsedata["reusecontext"] = false; 475 responsedata["int_response_code"] = 200;
486 responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events); 476 responsedata["content_type"] = "application/xml";
477 responsedata["bin_response_data"] = Encoding.UTF8.GetBytes(OSDParser.SerializeLLSDXmlString(events));
478 }
487 //m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", pAgentId, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]); 479 //m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", pAgentId, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
488 return responsedata; 480 return responsedata;
489 } 481 }
@@ -493,13 +485,13 @@ namespace OpenSim.Region.ClientStack.Linden
493 Hashtable responsedata = new Hashtable(); 485 Hashtable responsedata = new Hashtable();
494 responsedata["int_response_code"] = 502; 486 responsedata["int_response_code"] = 502;
495 responsedata["content_type"] = "text/plain"; 487 responsedata["content_type"] = "text/plain";
496 responsedata["keepalive"] = false;
497 responsedata["reusecontext"] = false;
498 responsedata["str_response_string"] = "<llsd></llsd>"; 488 responsedata["str_response_string"] = "<llsd></llsd>";
499 responsedata["error_status_text"] = "<llsd></llsd>"; 489 responsedata["error_status_text"] = "<llsd></llsd>";
500 responsedata["http_protocol_version"] = "HTTP/1.0"; 490 responsedata["http_protocol_version"] = "HTTP/1.0";
491 responsedata["keepalive"] = false;
501 return responsedata; 492 return responsedata;
502 } 493 }
494
503/* this is not a event message 495/* this is not a event message
504 public void DisableSimulator(ulong handle, UUID avatarID) 496 public void DisableSimulator(ulong handle, UUID avatarID)
505 { 497 {
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
index 461f776..52cfd48 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
@@ -43,16 +43,16 @@ namespace OpenSim.Region.ClientStack.Linden
43 private static byte[] ulongToByteArray(ulong uLongValue) 43 private static byte[] ulongToByteArray(ulong uLongValue)
44 { 44 {
45 // Reverse endianness of RegionHandle 45 // Reverse endianness of RegionHandle
46 return new byte[] 46 return new byte[8]
47 { 47 {
48 (byte)((uLongValue >> 56) % 256), 48 (byte)((uLongValue >> 56) & 0xff),
49 (byte)((uLongValue >> 48) % 256), 49 (byte)((uLongValue >> 48) & 0xff),
50 (byte)((uLongValue >> 40) % 256), 50 (byte)((uLongValue >> 40) & 0xff),
51 (byte)((uLongValue >> 32) % 256), 51 (byte)((uLongValue >> 32) & 0xff),
52 (byte)((uLongValue >> 24) % 256), 52 (byte)((uLongValue >> 24) & 0xff),
53 (byte)((uLongValue >> 16) % 256), 53 (byte)((uLongValue >> 16) & 0xff),
54 (byte)((uLongValue >> 8) % 256), 54 (byte)((uLongValue >> 8) & 0xff),
55 (byte)(uLongValue % 256) 55 (byte)(uLongValue & 0xff)
56 }; 56 };
57 } 57 }
58 58
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
index ee3f4f1..080cef9 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Net; 31using System.Net;
32using System.Text;
32using log4net.Config; 33using log4net.Config;
33using Nini.Config; 34using Nini.Config;
34using NUnit.Framework; 35using NUnit.Framework;
@@ -59,13 +60,12 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
59 base.SetUp(); 60 base.SetUp();
60 61
61 uint port = 9999; 62 uint port = 9999;
62 uint sslPort = 9998;
63 63
64 // This is an unfortunate bit of clean up we have to do because MainServer manages things through static 64 // This is an unfortunate bit of clean up we have to do because MainServer manages things through static
65 // variables and the VM is not restarted between tests. 65 // variables and the VM is not restarted between tests.
66 MainServer.RemoveHttpServer(port); 66 MainServer.RemoveHttpServer(port);
67 67
68 BaseHttpServer server = new BaseHttpServer(port, false, sslPort, ""); 68 BaseHttpServer server = new BaseHttpServer(port, false, "","","");
69 MainServer.AddHttpServer(server); 69 MainServer.AddHttpServer(server);
70 MainServer.Instance = server; 70 MainServer.Instance = server;
71 71
@@ -126,7 +126,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
126 Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID); 126 Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID);
127 127
128 // initial queue as null events 128 // initial queue as null events
129 eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID); 129// eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID);
130 if((int)eventsResponse["int_response_code"] != (int)HttpStatusCode.OK) 130 if((int)eventsResponse["int_response_code"] != (int)HttpStatusCode.OK)
131 { 131 {
132 eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID); 132 eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID);
@@ -137,8 +137,11 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
137 Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.OK)); 137 Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.OK));
138 138
139// Console.WriteLine("Response [{0}]", (string)eventsResponse["str_response_string"]); 139// Console.WriteLine("Response [{0}]", (string)eventsResponse["str_response_string"]);
140 string data = String.Empty;
141 if(eventsResponse["bin_response_data"] != null)
142 data = Encoding.UTF8.GetString((byte[])eventsResponse["bin_response_data"]);
140 143
141 OSDMap rawOsd = (OSDMap)OSDParser.DeserializeLLSDXml((string)eventsResponse["str_response_string"]); 144 OSDMap rawOsd = (OSDMap)OSDParser.DeserializeLLSDXml(data);
142 OSDArray eventsOsd = (OSDArray)rawOsd["events"]; 145 OSDArray eventsOsd = (OSDArray)rawOsd["events"];
143 146
144 bool foundUpdate = false; 147 bool foundUpdate = false;
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
index ba917e39..5be75fa 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
@@ -28,17 +28,14 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Collections.Specialized; 31using System.Collections.Concurrent;
32using System.Reflection; 32using System.Reflection;
33using System.IO;
34using System.Threading; 33using System.Threading;
35using System.Web;
36using Mono.Addins; 34using Mono.Addins;
37using OpenSim.Framework.Monitoring; 35using OpenSim.Framework.Monitoring;
38using log4net; 36using log4net;
39using Nini.Config; 37using Nini.Config;
40using OpenMetaverse; 38using OpenMetaverse;
41using OpenMetaverse.StructuredData;
42using OpenSim.Capabilities.Handlers; 39using OpenSim.Capabilities.Handlers;
43using OpenSim.Framework; 40using OpenSim.Framework;
44using OpenSim.Framework.Servers; 41using OpenSim.Framework.Servers;
@@ -57,7 +54,6 @@ namespace OpenSim.Region.ClientStack.Linden
57// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
58 55
59 private Scene m_scene; 56 private Scene m_scene;
60 private IAssetService m_AssetService;
61 private bool m_Enabled = true; 57 private bool m_Enabled = true;
62 private string m_URL; 58 private string m_URL;
63 59
@@ -65,21 +61,19 @@ namespace OpenSim.Region.ClientStack.Linden
65 private string m_RedirectURL = null; 61 private string m_RedirectURL = null;
66 private string m_RedirectURL2 = null; 62 private string m_RedirectURL2 = null;
67 63
68 struct aPollRequest 64 class APollRequest
69 { 65 {
70 public PollServiceMeshEventArgs thepoll; 66 public PollServiceMeshEventArgs thepoll;
71 public UUID reqID; 67 public UUID reqID;
72 public Hashtable request; 68 public Hashtable request;
73 } 69 }
74 70
75 public class aPollResponse 71 public class APollResponse
76 { 72 {
77 public Hashtable response; 73 public Hashtable response;
78 public int bytes; 74 public int bytes;
79 public int lod;
80 } 75 }
81 76
82
83 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
84 78
85 private static GetMeshHandler m_getMeshHandler; 79 private static GetMeshHandler m_getMeshHandler;
@@ -89,8 +83,7 @@ namespace OpenSim.Region.ClientStack.Linden
89 private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>(); 83 private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
90 private static Thread[] m_workerThreads = null; 84 private static Thread[] m_workerThreads = null;
91 private static int m_NumberScenes = 0; 85 private static int m_NumberScenes = 0;
92 private static OpenSim.Framework.BlockingQueue<aPollRequest> m_queue = 86 private static BlockingCollection<APollRequest> m_queue = new BlockingCollection<APollRequest>();
93 new OpenSim.Framework.BlockingQueue<aPollRequest>();
94 87
95 private Dictionary<UUID, PollServiceMeshEventArgs> m_pollservices = new Dictionary<UUID, PollServiceMeshEventArgs>(); 88 private Dictionary<UUID, PollServiceMeshEventArgs> m_pollservices = new Dictionary<UUID, PollServiceMeshEventArgs>();
96 89
@@ -132,33 +125,35 @@ namespace OpenSim.Region.ClientStack.Linden
132 return; 125 return;
133 126
134 m_scene = pScene; 127 m_scene = pScene;
135
136 m_assetService = pScene.AssetService;
137 } 128 }
138 129
139 public void RemoveRegion(Scene scene) 130 public void RemoveRegion(Scene s)
140 { 131 {
141 if (!m_Enabled) 132 if (!m_Enabled)
142 return; 133 return;
143 134
144 m_scene.EventManager.OnRegisterCaps -= RegisterCaps; 135 s.EventManager.OnRegisterCaps -= RegisterCaps;
145 m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps; 136 s.EventManager.OnDeregisterCaps -= DeregisterCaps;
146 m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate; 137 s.EventManager.OnThrottleUpdate -= ThrottleUpdate;
147 m_NumberScenes--; 138 m_NumberScenes--;
148 m_scene = null; 139 m_scene = null;
149 } 140 }
150 141
151 public void RegionLoaded(Scene scene) 142 public void RegionLoaded(Scene s)
152 { 143 {
153 if (!m_Enabled) 144 if (!m_Enabled)
154 return; 145 return;
155 146
156 m_AssetService = m_scene.RequestModuleInterface<IAssetService>(); 147 if(m_assetService == null)
157 m_scene.EventManager.OnRegisterCaps += RegisterCaps; 148 {
158 // We'll reuse the same handler for all requests. 149 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
159 m_getMeshHandler = new GetMeshHandler(m_assetService); 150 // We'll reuse the same handler for all requests.
160 m_scene.EventManager.OnDeregisterCaps += DeregisterCaps; 151 m_getMeshHandler = new GetMeshHandler(m_assetService);
161 m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate; 152 }
153
154 s.EventManager.OnRegisterCaps += RegisterCaps;
155 s.EventManager.OnDeregisterCaps += DeregisterCaps;
156 s.EventManager.OnThrottleUpdate += ThrottleUpdate;
162 157
163 m_NumberScenes++; 158 m_NumberScenes++;
164 159
@@ -190,7 +185,7 @@ namespace OpenSim.Region.ClientStack.Linden
190 // Prevent red ink. 185 // Prevent red ink.
191 try 186 try
192 { 187 {
193 m_queue.Clear(); 188 m_queue.Dispose();
194 } 189 }
195 catch {} 190 catch {}
196 } 191 }
@@ -202,14 +197,18 @@ namespace OpenSim.Region.ClientStack.Linden
202 197
203 private static void DoMeshRequests() 198 private static void DoMeshRequests()
204 { 199 {
205 while(true) 200 while (m_NumberScenes > 0)
206 { 201 {
207 aPollRequest poolreq = m_queue.Dequeue(4500); 202 APollRequest poolreq;
208 Watchdog.UpdateThread(); 203 if(m_queue.TryTake(out poolreq, 4500))
209 if(m_NumberScenes <= 0) 204 {
210 return; 205 if(m_NumberScenes <= 0)
211 if(poolreq.reqID != UUID.Zero) 206 break;
212 poolreq.thepoll.Process(poolreq); 207
208 if(poolreq.reqID != UUID.Zero)
209 poolreq.thepoll.Process(poolreq);
210 }
211 Watchdog.UpdateThread();
213 } 212 }
214 } 213 }
215 214
@@ -229,13 +228,14 @@ namespace OpenSim.Region.ClientStack.Linden
229 { 228 {
230 private List<Hashtable> requests = 229 private List<Hashtable> requests =
231 new List<Hashtable>(); 230 new List<Hashtable>();
232 private Dictionary<UUID, aPollResponse> responses = 231 private Dictionary<UUID, APollResponse> responses =
233 new Dictionary<UUID, aPollResponse>(); 232 new Dictionary<UUID, APollResponse>();
233 private HashSet<UUID> dropedResponses = new HashSet<UUID>();
234 234
235 private Scene m_scene; 235 private Scene m_scene;
236 private MeshCapsDataThrottler m_throttler; 236 private MeshCapsDataThrottler m_throttler;
237 public PollServiceMeshEventArgs(string uri, UUID pId, Scene scene) : 237 public PollServiceMeshEventArgs(string uri, UUID pId, Scene scene) :
238 base(null, uri, null, null, null, pId, int.MaxValue) 238 base(null, uri, null, null, null, null, pId, int.MaxValue)
239 { 239 {
240 m_scene = scene; 240 m_scene = scene;
241 m_throttler = new MeshCapsDataThrottler(100000); 241 m_throttler = new MeshCapsDataThrottler(100000);
@@ -249,6 +249,17 @@ namespace OpenSim.Region.ClientStack.Linden
249 249
250 } 250 }
251 }; 251 };
252
253 Drop = (x, y) =>
254 {
255 lock (responses)
256 {
257 responses.Remove(x);
258 lock(dropedResponses)
259 dropedResponses.Add(x);
260 }
261 };
262
252 GetEvents = (x, y) => 263 GetEvents = (x, y) =>
253 { 264 {
254 lock (responses) 265 lock (responses)
@@ -267,12 +278,12 @@ namespace OpenSim.Region.ClientStack.Linden
267 // x is request id, y is request data hashtable 278 // x is request id, y is request data hashtable
268 Request = (x, y) => 279 Request = (x, y) =>
269 { 280 {
270 aPollRequest reqinfo = new aPollRequest(); 281 APollRequest reqinfo = new APollRequest();
271 reqinfo.thepoll = this; 282 reqinfo.thepoll = this;
272 reqinfo.reqID = x; 283 reqinfo.reqID = x;
273 reqinfo.request = y; 284 reqinfo.request = y;
274 285
275 m_queue.Enqueue(reqinfo); 286 m_queue.Add(reqinfo);
276 m_throttler.PassTime(); 287 m_throttler.PassTime();
277 }; 288 };
278 289
@@ -298,7 +309,7 @@ namespace OpenSim.Region.ClientStack.Linden
298 }; 309 };
299 } 310 }
300 311
301 public void Process(aPollRequest requestinfo) 312 public void Process(APollRequest requestinfo)
302 { 313 {
303 Hashtable response; 314 Hashtable response;
304 315
@@ -307,30 +318,48 @@ namespace OpenSim.Region.ClientStack.Linden
307 if(m_scene.ShuttingDown) 318 if(m_scene.ShuttingDown)
308 return; 319 return;
309 320
310 // If the avatar is gone, don't bother to get the texture 321 lock(responses)
311 if (m_scene.GetScenePresence(Id) == null)
312 { 322 {
313 response = new Hashtable(); 323 lock(dropedResponses)
314 324 {
315 response["int_response_code"] = 500; 325 if(dropedResponses.Contains(requestID))
316 response["str_response_string"] = "Script timeout"; 326 {
317 response["content_type"] = "text/plain"; 327 dropedResponses.Remove(requestID);
318 response["keepalive"] = false; 328 return;
319 response["reusecontext"] = false; 329 }
330 }
331
332 // If the avatar is gone, don't bother to get the texture
333 if (m_scene.GetScenePresence(Id) == null)
334 {
335 response = new Hashtable();
320 336
321 lock (responses) 337 response["int_response_code"] = 500;
322 responses[requestID] = new aPollResponse() { bytes = 0, response = response, lod = 0 }; 338 response["str_response_string"] = "Script timeout";
339 response["content_type"] = "text/plain";
340 response["keepalive"] = false;
341 responses[requestID] = new APollResponse() { bytes = 0, response = response};
323 342
324 return; 343 return;
344 }
325 } 345 }
326 346
327 response = m_getMeshHandler.Handle(requestinfo.request); 347 response = m_getMeshHandler.Handle(requestinfo.request);
348
328 lock (responses) 349 lock (responses)
329 { 350 {
330 responses[requestID] = new aPollResponse() 351 lock(dropedResponses)
352 {
353 if(dropedResponses.Contains(requestID))
354 {
355 dropedResponses.Remove(requestID);
356 return;
357 }
358 }
359
360 responses[requestID] = new APollResponse()
331 { 361 {
332 bytes = (int)response["int_bytes"], 362 bytes = (int)response["int_bytes"],
333 lod = (int)response["int_lod"],
334 response = response 363 response = response
335 }; 364 };
336 365
@@ -408,7 +437,7 @@ namespace OpenSim.Region.ClientStack.Linden
408 lastTimeElapsed = Util.GetTimeStampMS(); 437 lastTimeElapsed = Util.GetTimeStampMS();
409 } 438 }
410 439
411 public bool hasEvents(UUID key, Dictionary<UUID, aPollResponse> responses) 440 public bool hasEvents(UUID key, Dictionary<UUID, APollResponse> responses)
412 { 441 {
413 PassTime(); 442 PassTime();
414 // Note, this is called IN LOCK 443 // Note, this is called IN LOCK
@@ -418,7 +447,7 @@ namespace OpenSim.Region.ClientStack.Linden
418 { 447 {
419 return false; 448 return false;
420 } 449 }
421 aPollResponse response; 450 APollResponse response;
422 if (responses.TryGetValue(key, out response)) 451 if (responses.TryGetValue(key, out response))
423 { 452 {
424 // Normal 453 // Normal
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
index b01c7dc..736e18f 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Collections.Concurrent;
31using System.Reflection; 32using System.Reflection;
32using System.Threading; 33using System.Threading;
33using log4net; 34using log4net;
@@ -51,7 +52,7 @@ namespace OpenSim.Region.ClientStack.Linden
51 public class GetTextureModule : INonSharedRegionModule 52 public class GetTextureModule : INonSharedRegionModule
52 { 53 {
53 54
54 struct aPollRequest 55 class APollRequest
55 { 56 {
56 public PollServiceTextureEventArgs thepoll; 57 public PollServiceTextureEventArgs thepoll;
57 public UUID reqID; 58 public UUID reqID;
@@ -59,7 +60,7 @@ namespace OpenSim.Region.ClientStack.Linden
59 public bool send503; 60 public bool send503;
60 } 61 }
61 62
62 public class aPollResponse 63 public class APollResponse
63 { 64 {
64 public Hashtable response; 65 public Hashtable response;
65 public int bytes; 66 public int bytes;
@@ -77,8 +78,7 @@ namespace OpenSim.Region.ClientStack.Linden
77 private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>(); 78 private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
78 private static Thread[] m_workerThreads = null; 79 private static Thread[] m_workerThreads = null;
79 private static int m_NumberScenes = 0; 80 private static int m_NumberScenes = 0;
80 private static OpenSim.Framework.BlockingQueue<aPollRequest> m_queue = 81 private static BlockingCollection<APollRequest> m_queue = new BlockingCollection<APollRequest>();
81 new OpenSim.Framework.BlockingQueue<aPollRequest>();
82 82
83 private Dictionary<UUID,PollServiceTextureEventArgs> m_pollservices = new Dictionary<UUID,PollServiceTextureEventArgs>(); 83 private Dictionary<UUID,PollServiceTextureEventArgs> m_pollservices = new Dictionary<UUID,PollServiceTextureEventArgs>();
84 84
@@ -107,26 +107,29 @@ namespace OpenSim.Region.ClientStack.Linden
107 public void AddRegion(Scene s) 107 public void AddRegion(Scene s)
108 { 108 {
109 m_scene = s; 109 m_scene = s;
110 m_assetService = s.AssetService;
111 } 110 }
112 111
113 public void RemoveRegion(Scene s) 112 public void RemoveRegion(Scene s)
114 { 113 {
115 m_scene.EventManager.OnRegisterCaps -= RegisterCaps; 114 s.EventManager.OnRegisterCaps -= RegisterCaps;
116 m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps; 115 s.EventManager.OnDeregisterCaps -= DeregisterCaps;
117 m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate; 116 s.EventManager.OnThrottleUpdate -= ThrottleUpdate;
118 m_NumberScenes--; 117 m_NumberScenes--;
119 m_scene = null; 118 m_scene = null;
120 } 119 }
121 120
122 public void RegionLoaded(Scene s) 121 public void RegionLoaded(Scene s)
123 { 122 {
124 // We'll reuse the same handler for all requests. 123 if(m_assetService == null)
125 m_getTextureHandler = new GetTextureHandler(m_assetService); 124 {
125 m_assetService = s.RequestModuleInterface<IAssetService>();
126 // We'll reuse the same handler for all requests.
127 m_getTextureHandler = new GetTextureHandler(m_assetService);
128 }
126 129
127 m_scene.EventManager.OnRegisterCaps += RegisterCaps; 130 s.EventManager.OnRegisterCaps += RegisterCaps;
128 m_scene.EventManager.OnDeregisterCaps += DeregisterCaps; 131 s.EventManager.OnDeregisterCaps += DeregisterCaps;
129 m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate; 132 s.EventManager.OnThrottleUpdate += ThrottleUpdate;
130 133
131 m_NumberScenes++; 134 m_NumberScenes++;
132 135
@@ -146,39 +149,13 @@ namespace OpenSim.Region.ClientStack.Linden
146 } 149 }
147 } 150 }
148 } 151 }
149 private int ExtractImageThrottle(byte[] pthrottles) 152
150 {
151
152 byte[] adjData;
153 int pos = 0;
154
155 if (!BitConverter.IsLittleEndian)
156 {
157 byte[] newData = new byte[7 * 4];
158 Buffer.BlockCopy(pthrottles, 0, newData, 0, 7 * 4);
159
160 for (int i = 0; i < 7; i++)
161 Array.Reverse(newData, i * 4, 4);
162
163 adjData = newData;
164 }
165 else
166 {
167 adjData = pthrottles;
168 }
169
170 pos = pos + 20;
171 int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); //pos += 4;
172 //int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
173 return texture;
174 }
175
176 // Now we know when the throttle is changed by the client in the case of a root agent or by a neighbor region in the case of a child agent. 153 // Now we know when the throttle is changed by the client in the case of a root agent or by a neighbor region in the case of a child agent.
177 public void ThrottleUpdate(ScenePresence p) 154 public void ThrottleUpdate(ScenePresence p)
178 { 155 {
179 byte[] throttles = p.ControllingClient.GetThrottlesPacked(1); 156 byte[] throttles = p.ControllingClient.GetThrottlesPacked(1);
180 UUID user = p.UUID; 157 UUID user = p.UUID;
181 int imagethrottle = ExtractImageThrottle(throttles); 158 int imagethrottle = p.ControllingClient.GetAgentThrottleSilent((int)ThrottleOutPacketType.Texture);
182 PollServiceTextureEventArgs args; 159 PollServiceTextureEventArgs args;
183 if (m_pollservices.TryGetValue(user,out args)) 160 if (m_pollservices.TryGetValue(user,out args))
184 { 161 {
@@ -199,7 +176,7 @@ namespace OpenSim.Region.ClientStack.Linden
199 foreach (Thread t in m_workerThreads) 176 foreach (Thread t in m_workerThreads)
200 Watchdog.AbortThread(t.ManagedThreadId); 177 Watchdog.AbortThread(t.ManagedThreadId);
201 178
202 m_queue.Clear(); 179 m_queue.Dispose();
203 } 180 }
204 } 181 }
205 182
@@ -216,15 +193,17 @@ namespace OpenSim.Region.ClientStack.Linden
216 { 193 {
217 private List<Hashtable> requests = 194 private List<Hashtable> requests =
218 new List<Hashtable>(); 195 new List<Hashtable>();
219 private Dictionary<UUID, aPollResponse> responses = 196 private Dictionary<UUID, APollResponse> responses =
220 new Dictionary<UUID, aPollResponse>(); 197 new Dictionary<UUID, APollResponse>();
198 private HashSet<UUID> dropedResponses = new HashSet<UUID>();
221 199
222 private Scene m_scene; 200 private Scene m_scene;
223 private CapsDataThrottler m_throttler = new CapsDataThrottler(100000); 201 private CapsDataThrottler m_throttler;
224 public PollServiceTextureEventArgs(UUID pId, Scene scene) : 202 public PollServiceTextureEventArgs(UUID pId, Scene scene) :
225 base(null, "", null, null, null, pId, int.MaxValue) 203 base(null, "", null, null, null, null, pId, int.MaxValue)
226 { 204 {
227 m_scene = scene; 205 m_scene = scene;
206 m_throttler = new CapsDataThrottler(100000);
228 // x is request id, y is userid 207 // x is request id, y is userid
229 HasEvents = (x, y) => 208 HasEvents = (x, y) =>
230 { 209 {
@@ -235,6 +214,16 @@ namespace OpenSim.Region.ClientStack.Linden
235 214
236 } 215 }
237 }; 216 };
217
218 Drop = (x, y) =>
219 {
220 lock (responses)
221 {
222 responses.Remove(x);
223 dropedResponses.Add(x);
224 }
225 };
226
238 GetEvents = (x, y) => 227 GetEvents = (x, y) =>
239 { 228 {
240 lock (responses) 229 lock (responses)
@@ -253,7 +242,7 @@ namespace OpenSim.Region.ClientStack.Linden
253 // x is request id, y is request data hashtable 242 // x is request id, y is request data hashtable
254 Request = (x, y) => 243 Request = (x, y) =>
255 { 244 {
256 aPollRequest reqinfo = new aPollRequest(); 245 APollRequest reqinfo = new APollRequest();
257 reqinfo.thepoll = this; 246 reqinfo.thepoll = this;
258 reqinfo.reqID = x; 247 reqinfo.reqID = x;
259 reqinfo.request = y; 248 reqinfo.request = y;
@@ -263,14 +252,14 @@ namespace OpenSim.Region.ClientStack.Linden
263 { 252 {
264 if (responses.Count > 0) 253 if (responses.Count > 0)
265 { 254 {
266 if (m_queue.Count() >= 4) 255 if (m_queue.Count >= 4)
267 { 256 {
268 // Never allow more than 4 fetches to wait 257 // Never allow more than 4 fetches to wait
269 reqinfo.send503 = true; 258 reqinfo.send503 = true;
270 } 259 }
271 } 260 }
272 } 261 }
273 m_queue.Enqueue(reqinfo); 262 m_queue.Add(reqinfo);
274 m_throttler.PassTime(); 263 m_throttler.PassTime();
275 }; 264 };
276 265
@@ -296,7 +285,7 @@ namespace OpenSim.Region.ClientStack.Linden
296 }; 285 };
297 } 286 }
298 287
299 public void Process(aPollRequest requestinfo) 288 public void Process(APollRequest requestinfo)
300 { 289 {
301 Hashtable response; 290 Hashtable response;
302 291
@@ -305,53 +294,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 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Collections.Concurrent;
31using System.Reflection; 32using System.Reflection;
32using System.Threading; 33using System.Threading;
33using log4net; 34using log4net;
34using Nini.Config; 35using Nini.Config;
35using Mono.Addins; 36using Mono.Addins;
36using OpenMetaverse; 37using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Framework.Servers;
39using OpenSim.Framework.Servers.HttpServer; 38using OpenSim.Framework.Servers.HttpServer;
40using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
@@ -55,13 +54,12 @@ namespace OpenSim.Region.ClientStack.Linden
55 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebFetchInvDescModule")] 54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebFetchInvDescModule")]
56 public class WebFetchInvDescModule : INonSharedRegionModule 55 public class WebFetchInvDescModule : INonSharedRegionModule
57 { 56 {
58 class aPollRequest 57 class APollRequest
59 { 58 {
60 public PollServiceInventoryEventArgs thepoll; 59 public PollServiceInventoryEventArgs thepoll;
61 public UUID reqID; 60 public UUID reqID;
62 public Hashtable request; 61 public Hashtable request;
63 public ScenePresence presence; 62 public ScenePresence presence;
64 public List<UUID> folders;
65 } 63 }
66 64
67 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 65 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -99,8 +97,7 @@ namespace OpenSim.Region.ClientStack.Linden
99 97
100 private static Thread[] m_workerThreads = null; 98 private static Thread[] m_workerThreads = null;
101 99
102 private static OpenSim.Framework.BlockingQueue<aPollRequest> m_queue = 100 private static BlockingCollection<APollRequest> m_queue = new BlockingCollection<APollRequest>();
103 new OpenSim.Framework.BlockingQueue<aPollRequest>();
104 101
105 private static int m_NumberScenes = 0; 102 private static int m_NumberScenes = 0;
106 103
@@ -181,7 +178,7 @@ namespace OpenSim.Region.ClientStack.Linden
181 "httpfetch", 178 "httpfetch",
182 StatType.Pull, 179 StatType.Pull,
183 MeasuresOfInterest.AverageChangeOverTime, 180 MeasuresOfInterest.AverageChangeOverTime,
184 stat => { stat.Value = m_queue.Count(); }, 181 stat => { stat.Value = m_queue.Count; },
185 StatVerbosity.Debug); 182 StatVerbosity.Debug);
186 183
187 StatsManager.RegisterStat(s_processedRequestsStat); 184 StatsManager.RegisterStat(s_processedRequestsStat);
@@ -235,6 +232,7 @@ namespace OpenSim.Region.ClientStack.Linden
235 m_workerThreads = null; 232 m_workerThreads = null;
236 } 233 }
237 } 234 }
235// m_queue.Dispose();
238 } 236 }
239 237
240 public string Name { get { return "WebFetchInvDescModule"; } } 238 public string Name { get { return "WebFetchInvDescModule"; } }
@@ -250,17 +248,28 @@ namespace OpenSim.Region.ClientStack.Linden
250 { 248 {
251 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 249 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
252 250
253 private Dictionary<UUID, Hashtable> responses = 251 private Dictionary<UUID, Hashtable> responses = new Dictionary<UUID, Hashtable>();
254 new Dictionary<UUID, Hashtable>(); 252 private HashSet<UUID> dropedResponses = new HashSet<UUID>();
255 253
256 private WebFetchInvDescModule m_module; 254 private WebFetchInvDescModule m_module;
257 255
258 public PollServiceInventoryEventArgs(WebFetchInvDescModule module, string url, UUID pId) : 256 public PollServiceInventoryEventArgs(WebFetchInvDescModule module, string url, UUID pId) :
259 base(null, url, null, null, null, pId, int.MaxValue) 257 base(null, url, null, null, null, null, pId, int.MaxValue)
260 { 258 {
261 m_module = module; 259 m_module = module;
262 260
263 HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; 261 HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); };
262
263 Drop = (x, y) =>
264 {
265 lock (responses)
266 {
267 responses.Remove(x);
268 lock(dropedResponses)
269 dropedResponses.Add(x);
270 }
271 };
272
264 GetEvents = (x, y) => 273 GetEvents = (x, y) =>
265 { 274 {
266 lock (responses) 275 lock (responses)
@@ -280,13 +289,15 @@ namespace OpenSim.Region.ClientStack.Linden
280 { 289 {
281 ScenePresence sp = m_module.Scene.GetScenePresence(Id); 290 ScenePresence sp = m_module.Scene.GetScenePresence(Id);
282 291
283 aPollRequest reqinfo = new aPollRequest(); 292 APollRequest reqinfo = new APollRequest();
284 reqinfo.thepoll = this; 293 reqinfo.thepoll = this;
285 reqinfo.reqID = x; 294 reqinfo.reqID = x;
286 reqinfo.request = y; 295 reqinfo.request = y;
287 reqinfo.presence = sp; 296 reqinfo.presence = sp;
288 reqinfo.folders = new List<UUID>();
289 297
298/* why where we doing this? just to get cof ?
299 List<UUID> folders = new List<UUID>();
300
290 // Decode the request here 301 // Decode the request here
291 string request = y["body"].ToString(); 302 string request = y["body"].ToString();
292 303
@@ -322,11 +333,11 @@ namespace OpenSim.Region.ClientStack.Linden
322 UUID folderID; 333 UUID folderID;
323 if (UUID.TryParse(folder, out folderID)) 334 if (UUID.TryParse(folder, out folderID))
324 { 335 {
325 if (!reqinfo.folders.Contains(folderID)) 336 if (!folders.Contains(folderID))
326 { 337 {
327 if (sp.COF != UUID.Zero && sp.COF == folderID) 338 if (sp.COF != UUID.Zero && sp.COF == folderID)
328 highPriority = true; 339 highPriority = true;
329 reqinfo.folders.Add(folderID); 340 folders.Add(folderID);
330 } 341 }
331 } 342 }
332 } 343 }
@@ -334,7 +345,8 @@ namespace OpenSim.Region.ClientStack.Linden
334 if (highPriority) 345 if (highPriority)
335 m_queue.PriorityEnqueue(reqinfo); 346 m_queue.PriorityEnqueue(reqinfo);
336 else 347 else
337 m_queue.Enqueue(reqinfo); 348*/
349 m_queue.Add(reqinfo);
338 }; 350 };
339 351
340 NoEvents = (x, y) => 352 NoEvents = (x, y) =>
@@ -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
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Collections.Concurrent;
30using System.Diagnostics; 31using System.Diagnostics;
31using System.IO; 32using System.IO;
32using System.Net; 33using System.Net;
@@ -285,7 +286,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
285 /// <summary>Incoming packets that are awaiting handling</summary> 286 /// <summary>Incoming packets that are awaiting handling</summary>
286 //protected OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 287 //protected OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
287 288
288 protected OpenSim.Framework.BlockingQueue<IncomingPacket> packetInbox = new OpenSim.Framework.BlockingQueue<IncomingPacket>(); 289 protected BlockingCollection<IncomingPacket> packetInbox = new BlockingCollection<IncomingPacket>();
289 290
290 /// <summary>Bandwidth throttle for this UDP server</summary> 291 /// <summary>Bandwidth throttle for this UDP server</summary>
291 public TokenBucket Throttle { get; protected set; } 292 public TokenBucket Throttle { get; protected set; }
@@ -712,7 +713,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
712 scene.Name, 713 scene.Name,
713 StatType.Pull, 714 StatType.Pull,
714 MeasuresOfInterest.AverageChangeOverTime, 715 MeasuresOfInterest.AverageChangeOverTime,
715 stat => stat.Value = packetInbox.Count(), 716 stat => {try{stat.Value = packetInbox.Count;}catch{}},
716 StatVerbosity.Debug)); 717 StatVerbosity.Debug));
717 718
718 // XXX: These stats are also pool stats but we register them separately since they are currently not 719 // XXX: These stats are also pool stats but we register them separately since they are currently not
@@ -898,7 +899,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
898 if (packet.Type == PacketType.CoarseLocationUpdate && allowSplitting) 899 if (packet.Type == PacketType.CoarseLocationUpdate && allowSplitting)
899 allowSplitting = false; 900 allowSplitting = false;
900 901
901 bool packetQueued = false; 902// bool packetQueued = false;
902 903
903 if (allowSplitting && packet.HasVariableBlocks) 904 if (allowSplitting && packet.HasVariableBlocks)
904 { 905 {
@@ -911,15 +912,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
911 for (int i = 0; i < packetCount; i++) 912 for (int i = 0; i < packetCount; i++)
912 { 913 {
913 byte[] data = datas[i]; 914 byte[] data = datas[i];
914 if (!SendPacketData(udpClient, data, packet.Type, category, method)) 915// if (!SendPacketData(udpClient, data, packet.Type, category, method))
915 packetQueued = true; 916// packetQueued = true;
917 SendPacketData(udpClient, data, packet.Type, category, method);
916 } 918 }
917 } 919 }
918 else 920 else
919 { 921 {
920 byte[] data = packet.ToBytes(); 922 byte[] data = packet.ToBytes();
921 if (!SendPacketData(udpClient, data, packet.Type, category, method)) 923// if (!SendPacketData(udpClient, data, packet.Type, category, method))
922 packetQueued = true; 924// packetQueued = true;
925 SendPacketData(udpClient, data, packet.Type, category, method);
923 } 926 }
924 927
925 PacketPool.Instance.ReturnPacket(packet); 928 PacketPool.Instance.ReturnPacket(packet);
@@ -1544,10 +1547,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1544 1547
1545// if (incomingPacket.Packet.Type == PacketType.AgentUpdate || 1548// if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
1546// incomingPacket.Packet.Type == PacketType.ChatFromViewer) 1549// incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1547 if (incomingPacket.Packet.Type == PacketType.ChatFromViewer) 1550// if (incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1548 packetInbox.PriorityEnqueue(incomingPacket); 1551// packetInbox.PriorityEnqueue(incomingPacket);
1549 else 1552// else
1550 packetInbox.Enqueue(incomingPacket); 1553// packetInbox.Enqueue(incomingPacket);
1554 packetInbox.Add(incomingPacket);
1551 1555
1552 } 1556 }
1553 1557
@@ -2016,7 +2020,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2016 Scene.ThreadAlive(1); 2020 Scene.ThreadAlive(1);
2017 try 2021 try
2018 { 2022 {
2019 incomingPacket = packetInbox.Dequeue(250); 2023 packetInbox.TryTake(out incomingPacket, 250);
2020 2024
2021 if (incomingPacket != null && IsRunningInbound) 2025 if (incomingPacket != null && IsRunningInbound)
2022 { 2026 {
@@ -2038,9 +2042,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2038 Watchdog.UpdateThread(); 2042 Watchdog.UpdateThread();
2039 } 2043 }
2040 2044
2041 if (packetInbox.Count() > 0) 2045 if (packetInbox.Count > 0)
2042 m_log.Warn("[LLUDPSERVER]: IncomingPacketHandler is shutting down, dropping " + packetInbox.Count() + " packets"); 2046 m_log.Warn("[LLUDPSERVER]: IncomingPacketHandler is shutting down, dropping " + packetInbox.Count + " packets");
2043 packetInbox.Clear(); 2047 packetInbox.Dispose();
2044 2048
2045 Watchdog.RemoveThread(); 2049 Watchdog.RemoveThread();
2046 } 2050 }