diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs | 137 |
1 files changed, 83 insertions, 54 deletions
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 |