diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs | 120 |
1 files changed, 27 insertions, 93 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs index 542d52a..d4d7b33 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs | |||
@@ -87,7 +87,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
87 | 87 | ||
88 | private Dictionary<UUID, PollServiceMeshEventArgs> m_pollservices = new Dictionary<UUID, PollServiceMeshEventArgs>(); | 88 | private Dictionary<UUID, PollServiceMeshEventArgs> m_pollservices = new Dictionary<UUID, PollServiceMeshEventArgs>(); |
89 | 89 | ||
90 | |||
91 | #region Region Module interfaceBase Members | 90 | #region Region Module interfaceBase Members |
92 | 91 | ||
93 | public Type ReplaceableInterface | 92 | public Type ReplaceableInterface |
@@ -134,7 +133,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
134 | 133 | ||
135 | s.EventManager.OnRegisterCaps -= RegisterCaps; | 134 | s.EventManager.OnRegisterCaps -= RegisterCaps; |
136 | s.EventManager.OnDeregisterCaps -= DeregisterCaps; | 135 | s.EventManager.OnDeregisterCaps -= DeregisterCaps; |
137 | s.EventManager.OnThrottleUpdate -= ThrottleUpdate; | ||
138 | m_NumberScenes--; | 136 | m_NumberScenes--; |
139 | m_scene = null; | 137 | m_scene = null; |
140 | } | 138 | } |
@@ -153,7 +151,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
153 | 151 | ||
154 | s.EventManager.OnRegisterCaps += RegisterCaps; | 152 | s.EventManager.OnRegisterCaps += RegisterCaps; |
155 | s.EventManager.OnDeregisterCaps += DeregisterCaps; | 153 | s.EventManager.OnDeregisterCaps += DeregisterCaps; |
156 | s.EventManager.OnThrottleUpdate += ThrottleUpdate; | ||
157 | 154 | ||
158 | m_NumberScenes++; | 155 | m_NumberScenes++; |
159 | 156 | ||
@@ -212,18 +209,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
212 | } | 209 | } |
213 | } | 210 | } |
214 | 211 | ||
215 | // 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. | ||
216 | public void ThrottleUpdate(ScenePresence p) | ||
217 | { | ||
218 | UUID user = p.UUID; | ||
219 | int imagethrottle = p.ControllingClient.GetAgentThrottleSilent((int)ThrottleOutPacketType.Asset); | ||
220 | PollServiceMeshEventArgs args; | ||
221 | if (m_pollservices.TryGetValue(user, out args)) | ||
222 | { | ||
223 | args.UpdateThrottle(imagethrottle); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | private class PollServiceMeshEventArgs : PollServiceEventArgs | 212 | private class PollServiceMeshEventArgs : PollServiceEventArgs |
228 | { | 213 | { |
229 | private List<Hashtable> requests = | 214 | private List<Hashtable> requests = |
@@ -233,18 +218,28 @@ namespace OpenSim.Region.ClientStack.Linden | |||
233 | private HashSet<UUID> dropedResponses = new HashSet<UUID>(); | 218 | private HashSet<UUID> dropedResponses = new HashSet<UUID>(); |
234 | 219 | ||
235 | private Scene m_scene; | 220 | private Scene m_scene; |
236 | private MeshCapsDataThrottler m_throttler; | 221 | private ScenePresence m_presence; |
237 | public PollServiceMeshEventArgs(string uri, UUID pId, Scene scene) : | 222 | public PollServiceMeshEventArgs(string uri, UUID pId, Scene scene) : |
238 | base(null, uri, null, null, null, null, pId, int.MaxValue) | 223 | base(null, uri, null, null, null, null, pId, int.MaxValue) |
239 | { | 224 | { |
240 | m_scene = scene; | 225 | m_scene = scene; |
241 | m_throttler = new MeshCapsDataThrottler(100000); | 226 | |
242 | // x is request id, y is userid | 227 | // x is request id, y is userid |
243 | HasEvents = (x, y) => | 228 | HasEvents = (x, y) => |
244 | { | 229 | { |
245 | lock (responses) | 230 | lock (responses) |
246 | { | 231 | { |
247 | return m_throttler.hasEvents(x, responses); | 232 | APollResponse response; |
233 | if (responses.TryGetValue(x, out response)) | ||
234 | { | ||
235 | if (m_presence == null) | ||
236 | m_presence = m_scene.GetScenePresence(pId); | ||
237 | |||
238 | if (m_presence == null || m_presence.IsDeleted) | ||
239 | return true; | ||
240 | return m_presence.CapCanSendAsset(1, response.bytes); | ||
241 | } | ||
242 | return false; | ||
248 | } | 243 | } |
249 | }; | 244 | }; |
250 | 245 | ||
@@ -269,7 +264,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
269 | finally | 264 | finally |
270 | { | 265 | { |
271 | responses.Remove(x); | 266 | responses.Remove(x); |
272 | m_throttler.PassTime(); | ||
273 | } | 267 | } |
274 | } | 268 | } |
275 | }; | 269 | }; |
@@ -282,7 +276,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
282 | reqinfo.request = y; | 276 | reqinfo.request = y; |
283 | 277 | ||
284 | m_queue.Add(reqinfo); | 278 | m_queue.Add(reqinfo); |
285 | m_throttler.PassTime(); | ||
286 | }; | 279 | }; |
287 | 280 | ||
288 | // this should never happen except possible on shutdown | 281 | // this should never happen except possible on shutdown |
@@ -307,14 +300,14 @@ namespace OpenSim.Region.ClientStack.Linden | |||
307 | 300 | ||
308 | public void Process(APollRequest requestinfo) | 301 | public void Process(APollRequest requestinfo) |
309 | { | 302 | { |
310 | Hashtable response; | 303 | Hashtable curresponse; |
311 | 304 | ||
312 | UUID requestID = requestinfo.reqID; | 305 | UUID requestID = requestinfo.reqID; |
313 | 306 | ||
314 | if(m_scene.ShuttingDown) | 307 | if(m_scene.ShuttingDown) |
315 | return; | 308 | return; |
316 | 309 | ||
317 | lock(responses) | 310 | lock(responses) |
318 | { | 311 | { |
319 | lock(dropedResponses) | 312 | lock(dropedResponses) |
320 | { | 313 | { |
@@ -324,25 +317,23 @@ namespace OpenSim.Region.ClientStack.Linden | |||
324 | return; | 317 | return; |
325 | } | 318 | } |
326 | } | 319 | } |
327 | 320 | ||
328 | // If the avatar is gone, don't bother to get the texture | 321 | // If the avatar is gone, don't bother to get the texture |
329 | if (m_scene.GetScenePresence(Id) == null) | 322 | if(m_scene.GetScenePresence(Id) == null) |
330 | { | 323 | { |
331 | response = new Hashtable(); | 324 | curresponse = new Hashtable(); |
332 | 325 | curresponse["int_response_code"] = 500; | |
333 | response["int_response_code"] = 500; | 326 | curresponse["str_response_string"] = "Script timeout"; |
334 | response["str_response_string"] = "Script timeout"; | 327 | curresponse["content_type"] = "text/plain"; |
335 | response["content_type"] = "text/plain"; | 328 | curresponse["keepalive"] = false; |
336 | response["keepalive"] = false; | 329 | responses[requestID] = new APollResponse() { bytes = 0, response = curresponse }; |
337 | responses[requestID] = new APollResponse() { bytes = 0, response = response}; | ||
338 | |||
339 | return; | 330 | return; |
340 | } | 331 | } |
341 | } | 332 | } |
342 | 333 | ||
343 | response = m_getMeshHandler.Handle(requestinfo.request); | 334 | curresponse = m_getMeshHandler.Handle(requestinfo.request); |
344 | 335 | ||
345 | lock (responses) | 336 | lock(responses) |
346 | { | 337 | { |
347 | lock(dropedResponses) | 338 | lock(dropedResponses) |
348 | { | 339 | { |
@@ -355,20 +346,10 @@ namespace OpenSim.Region.ClientStack.Linden | |||
355 | 346 | ||
356 | responses[requestID] = new APollResponse() | 347 | responses[requestID] = new APollResponse() |
357 | { | 348 | { |
358 | bytes = (int)response["int_bytes"], | 349 | bytes = (int)curresponse["int_bytes"], |
359 | response = response | 350 | response = curresponse |
360 | }; | 351 | }; |
361 | |||
362 | } | 352 | } |
363 | m_throttler.PassTime(); | ||
364 | } | ||
365 | |||
366 | internal void UpdateThrottle(int pthrottle) | ||
367 | { | ||
368 | int tmp = 2 * pthrottle; | ||
369 | if(tmp < 10000) | ||
370 | tmp = 10000; | ||
371 | m_throttler.ThrottleBytes = tmp; | ||
372 | } | 353 | } |
373 | } | 354 | } |
374 | 355 | ||
@@ -419,52 +400,5 @@ namespace OpenSim.Region.ClientStack.Linden | |||
419 | m_pollservices.Remove(agentID); | 400 | m_pollservices.Remove(agentID); |
420 | } | 401 | } |
421 | } | 402 | } |
422 | |||
423 | internal sealed class MeshCapsDataThrottler | ||
424 | { | ||
425 | private double lastTimeElapsed = 0; | ||
426 | private double BytesSent = 0; | ||
427 | |||
428 | public MeshCapsDataThrottler(int pBytes) | ||
429 | { | ||
430 | if(pBytes < 10000) | ||
431 | pBytes = 10000; | ||
432 | ThrottleBytes = pBytes; | ||
433 | lastTimeElapsed = Util.GetTimeStamp(); | ||
434 | } | ||
435 | |||
436 | public bool hasEvents(UUID key, Dictionary<UUID, APollResponse> responses) | ||
437 | { | ||
438 | PassTime(); | ||
439 | APollResponse response; | ||
440 | if (responses.TryGetValue(key, out response)) | ||
441 | { | ||
442 | // Normal | ||
443 | if (response.bytes == 0 || BytesSent <= ThrottleBytes) | ||
444 | { | ||
445 | BytesSent += response.bytes; | ||
446 | return true; | ||
447 | } | ||
448 | } | ||
449 | return false; | ||
450 | } | ||
451 | |||
452 | public void PassTime() | ||
453 | { | ||
454 | double currenttime = Util.GetTimeStamp(); | ||
455 | double timeElapsed = currenttime - lastTimeElapsed; | ||
456 | if(timeElapsed < .05) | ||
457 | return; | ||
458 | int add = (int)(ThrottleBytes * timeElapsed); | ||
459 | if (add >= 1000) | ||
460 | { | ||
461 | lastTimeElapsed = currenttime; | ||
462 | BytesSent -= add; | ||
463 | if (BytesSent < 0) BytesSent = 0; | ||
464 | } | ||
465 | } | ||
466 | |||
467 | public int ThrottleBytes; | ||
468 | } | ||
469 | } | 403 | } |
470 | } | 404 | } |