aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
authorteravus2012-11-05 22:05:10 -0500
committerteravus2012-11-05 22:05:10 -0500
commit182b4872437e97762ac494dbf1815fe63aa29405 (patch)
treeadacb4b0092bdaa69ab7099b07fbd645adf26c64 /OpenSim/Region/ClientStack
parentAnother step in the chain. Pipe the throttle update to the appropriate PollS... (diff)
downloadopensim-SC-182b4872437e97762ac494dbf1815fe63aa29405.zip
opensim-SC-182b4872437e97762ac494dbf1815fe63aa29405.tar.gz
opensim-SC-182b4872437e97762ac494dbf1815fe63aa29405.tar.bz2
opensim-SC-182b4872437e97762ac494dbf1815fe63aa29405.tar.xz
This implements the Caps throttler. After some testing, the system seemed to be OK with me specifying allowing 1 oversized image per 70,000b/sec with at least one. Try it out, start with a low bandwidth setting and then, set your bandwidth setting middle/high and see the difference.
Tested with Two Clients on a region with 1800 textures all visible at once.
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs119
1 files changed, 106 insertions, 13 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
index 4bfdbff..8cba6c8 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
@@ -61,7 +61,7 @@ namespace OpenSim.Region.ClientStack.Linden
61 public Hashtable request; 61 public Hashtable request;
62 } 62 }
63 63
64 public struct aPollResponse 64 public class aPollResponse
65 { 65 {
66 public Hashtable response; 66 public Hashtable response;
67 public int bytes; 67 public int bytes;
@@ -151,13 +151,18 @@ namespace OpenSim.Region.ClientStack.Linden
151 } 151 }
152 152
153 // 0.125f converts from bits to bytes 153 // 0.125f converts from bits to bytes
154 //int resend = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; 154 //int resend = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
155 // int land = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; 155 //pos += 4;
156 // int wind = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; 156 // int land = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
157 // int cloud = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; 157 //pos += 4;
158 // int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; 158 // int wind = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
159 // pos += 4;
160 // int cloud = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
161 // pos += 4;
162 // int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
163 // pos += 4;
159 pos = pos + 20; 164 pos = pos + 20;
160 int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; 165 int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); //pos += 4;
161 //int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); 166 //int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
162 return texture; 167 return texture;
163 } 168 }
@@ -205,7 +210,7 @@ namespace OpenSim.Region.ClientStack.Linden
205 new Dictionary<UUID, aPollResponse>(); 210 new Dictionary<UUID, aPollResponse>();
206 211
207 private Scene m_scene; 212 private Scene m_scene;
208 213 private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000);
209 public PollServiceTextureEventArgs(UUID pId, Scene scene) : 214 public PollServiceTextureEventArgs(UUID pId, Scene scene) :
210 base(null, null, null, null, pId, int.MaxValue) 215 base(null, null, null, null, pId, int.MaxValue)
211 { 216 {
@@ -214,7 +219,12 @@ namespace OpenSim.Region.ClientStack.Linden
214 HasEvents = (x, y) => 219 HasEvents = (x, y) =>
215 { 220 {
216 lock (responses) 221 lock (responses)
217 return responses.ContainsKey(x); 222 {
223 bool ret = m_throttler.hasEvents(x, responses);
224 m_throttler.ProcessTime();
225 return ret;
226
227 }
218 }; 228 };
219 GetEvents = (x, y) => 229 GetEvents = (x, y) =>
220 { 230 {
@@ -281,19 +291,27 @@ namespace OpenSim.Region.ClientStack.Linden
281 response["reusecontext"] = false; 291 response["reusecontext"] = false;
282 292
283 lock (responses) 293 lock (responses)
284 responses[requestID] = new aPollResponse() {bytes = 0,response = response}; 294 responses[requestID] = new aPollResponse() {bytes = 0, response = response};
285 295
286 return; 296 return;
287 } 297 }
288 298
289 response = m_getTextureHandler.Handle(requestinfo.request); 299 response = m_getTextureHandler.Handle(requestinfo.request);
290 lock (responses) 300 lock (responses)
291 responses[requestID] = new aPollResponse() { bytes = (int)response["int_bytes"], response = response}; 301 {
302 responses[requestID] = new aPollResponse()
303 {
304 bytes = (int) response["int_bytes"],
305 response = response
306 };
307
308 }
309 m_throttler.ProcessTime();
292 } 310 }
293 311
294 internal void UpdateThrottle(int pimagethrottle) 312 internal void UpdateThrottle(int pimagethrottle)
295 { 313 {
296 314 m_throttler.ThrottleBytes = pimagethrottle;
297 } 315 }
298 } 316 }
299 317
@@ -347,4 +365,79 @@ namespace OpenSim.Region.ClientStack.Linden
347 } 365 }
348 } 366 }
349 } 367 }
368
369 internal sealed class CapsDataThrottler
370 {
371
372 private volatile int currenttime = 0;
373 private volatile int lastTimeElapsed = 0;
374 private volatile int BytesSent = 0;
375 private int oversizedImages = 0;
376 public CapsDataThrottler(int pBytes, int max, int min)
377 {
378 ThrottleBytes = pBytes;
379 lastTimeElapsed = Util.EnvironmentTickCount();
380 }
381 public bool hasEvents(UUID key, Dictionary<UUID, GetTextureModule.aPollResponse> responses)
382 {
383 PassTime();
384 // Note, this is called IN LOCK
385 bool haskey = responses.ContainsKey(key);
386 if (!haskey)
387 {
388 return false;
389 }
390 GetTextureModule.aPollResponse response;
391 if (responses.TryGetValue(key,out response))
392 {
393
394 // Normal
395 if (BytesSent + response.bytes <= ThrottleBytes)
396 {
397 BytesSent += response.bytes;
398 //TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + 1000, unlockyn = false };
399 //m_actions.Add(timeBasedAction);
400 return true;
401 }
402 // Big textures
403 else if (response.bytes > ThrottleBytes && oversizedImages <= ((ThrottleBytes%50000) + 1))
404 {
405 Interlocked.Increment(ref oversizedImages);
406 BytesSent += response.bytes;
407 //TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + (((response.bytes % ThrottleBytes)+1)*1000) , unlockyn = false };
408 //m_actions.Add(timeBasedAction);
409 return true;
410 }
411 else
412 {
413 return false;
414 }
415 }
416
417 return haskey;
418 }
419 public void ProcessTime()
420 {
421 PassTime();
422 }
423
424
425 private void PassTime()
426 {
427 currenttime = Util.EnvironmentTickCount();
428 int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
429 //processTimeBasedActions(responses);
430 if (Util.EnvironmentTickCountSubtract(currenttime, timeElapsed) >= 1000)
431 {
432 lastTimeElapsed = Util.EnvironmentTickCount();
433 BytesSent -= ThrottleBytes;
434 if (BytesSent < 0) BytesSent = 0;
435 if (BytesSent < ThrottleBytes)
436 {
437 oversizedImages = 0;
438 }
439 }
440 }
441 public int ThrottleBytes;
442 }
350} 443}