diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs | 61 |
1 files changed, 36 insertions, 25 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index f91abfe..45013b3 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs | |||
@@ -144,8 +144,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
144 | get { return m_throttleClient; } | 144 | get { return m_throttleClient; } |
145 | } | 145 | } |
146 | 146 | ||
147 | /// <summary>Throttle bucket for this agent's connection</summary> | ||
148 | private readonly TokenBucket m_throttleCategory; | ||
149 | /// <summary>Throttle buckets for each packet category</summary> | 147 | /// <summary>Throttle buckets for each packet category</summary> |
150 | private readonly TokenBucket[] m_throttleCategories; | 148 | private readonly TokenBucket[] m_throttleCategories; |
151 | /// <summary>Outgoing queues for throttled packets</summary> | 149 | /// <summary>Outgoing queues for throttled packets</summary> |
@@ -163,6 +161,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
163 | private int m_maxRTO = 60000; | 161 | private int m_maxRTO = 60000; |
164 | public bool m_deliverPackets = true; | 162 | public bool m_deliverPackets = true; |
165 | 163 | ||
164 | private float m_burstTime; | ||
165 | |||
166 | public int m_lastStartpingTimeMS; | 166 | public int m_lastStartpingTimeMS; |
167 | public int m_pingMS; | 167 | public int m_pingMS; |
168 | 168 | ||
@@ -216,17 +216,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
216 | if (maxRTO != 0) | 216 | if (maxRTO != 0) |
217 | m_maxRTO = maxRTO; | 217 | m_maxRTO = maxRTO; |
218 | 218 | ||
219 | m_burstTime = rates.BrustTime; | ||
220 | float m_burst = rates.ClientMaxRate * m_burstTime; | ||
221 | |||
219 | // Create a token bucket throttle for this client that has the scene token bucket as a parent | 222 | // Create a token bucket throttle for this client that has the scene token bucket as a parent |
220 | m_throttleClient = new AdaptiveTokenBucket(parentThrottle, rates.Total, rates.AdaptiveThrottlesEnabled); | 223 | m_throttleClient = new AdaptiveTokenBucket(parentThrottle, rates.ClientMaxRate, m_burst, rates.AdaptiveThrottlesEnabled); |
221 | // Create a token bucket throttle for the total categary with the client bucket as a throttle | ||
222 | m_throttleCategory = new TokenBucket(m_throttleClient, 0); | ||
223 | // Create an array of token buckets for this clients different throttle categories | 224 | // Create an array of token buckets for this clients different throttle categories |
224 | m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; | 225 | m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; |
225 | 226 | ||
226 | m_cannibalrate = rates.CannibalizeTextureRate; | 227 | m_cannibalrate = rates.CannibalizeTextureRate; |
227 | 228 | ||
228 | long totalrate = 0; | 229 | m_burst = rates.Total * rates.BrustTime; |
229 | long catrate = 0; | ||
230 | 230 | ||
231 | for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) | 231 | for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) |
232 | { | 232 | { |
@@ -235,13 +235,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
235 | // Initialize the packet outboxes, where packets sit while they are waiting for tokens | 235 | // Initialize the packet outboxes, where packets sit while they are waiting for tokens |
236 | m_packetOutboxes[i] = new DoubleLocklessQueue<OutgoingPacket>(); | 236 | m_packetOutboxes[i] = new DoubleLocklessQueue<OutgoingPacket>(); |
237 | // Initialize the token buckets that control the throttling for each category | 237 | // Initialize the token buckets that control the throttling for each category |
238 | catrate = rates.GetRate(type); | 238 | m_throttleCategories[i] = new TokenBucket(m_throttleClient, rates.GetRate(type), m_burst); |
239 | totalrate += catrate; | ||
240 | m_throttleCategories[i] = new TokenBucket(m_throttleCategory, catrate); | ||
241 | } | 239 | } |
242 | 240 | ||
243 | m_throttleCategory.RequestedDripRate = totalrate; | ||
244 | |||
245 | // Default the retransmission timeout to one second | 241 | // Default the retransmission timeout to one second |
246 | RTO = m_defaultRTO; | 242 | RTO = m_defaultRTO; |
247 | 243 | ||
@@ -285,7 +281,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
285 | m_info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; | 281 | m_info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; |
286 | m_info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; | 282 | m_info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; |
287 | m_info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; | 283 | m_info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; |
288 | m_info.totalThrottle = (int)m_throttleCategory.DripRate; | 284 | m_info.totalThrottle = (int)m_throttleClient.DripRate; |
289 | 285 | ||
290 | return m_info; | 286 | return m_info; |
291 | } | 287 | } |
@@ -373,6 +369,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
373 | 369 | ||
374 | // Make sure none of the throttles are set below our packet MTU, | 370 | // Make sure none of the throttles are set below our packet MTU, |
375 | // otherwise a throttle could become permanently clogged | 371 | // otherwise a throttle could become permanently clogged |
372 | |||
373 | /* not using floats | ||
376 | resend = Math.Max(resend, LLUDPServer.MTU); | 374 | resend = Math.Max(resend, LLUDPServer.MTU); |
377 | land = Math.Max(land, LLUDPServer.MTU); | 375 | land = Math.Max(land, LLUDPServer.MTU); |
378 | wind = Math.Max(wind, LLUDPServer.MTU); | 376 | wind = Math.Max(wind, LLUDPServer.MTU); |
@@ -380,6 +378,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
380 | task = Math.Max(task, LLUDPServer.MTU); | 378 | task = Math.Max(task, LLUDPServer.MTU); |
381 | texture = Math.Max(texture, LLUDPServer.MTU); | 379 | texture = Math.Max(texture, LLUDPServer.MTU); |
382 | asset = Math.Max(asset, LLUDPServer.MTU); | 380 | asset = Math.Max(asset, LLUDPServer.MTU); |
381 | */ | ||
383 | 382 | ||
384 | // Since most textures are now delivered through http, make it possible | 383 | // Since most textures are now delivered through http, make it possible |
385 | // to cannibalize some of the bw from the texture throttle to use for | 384 | // to cannibalize some of the bw from the texture throttle to use for |
@@ -388,7 +387,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
388 | texture = (int)((1 - m_cannibalrate) * texture); | 387 | texture = (int)((1 - m_cannibalrate) * texture); |
389 | 388 | ||
390 | int total = resend + land + wind + cloud + task + texture + asset; | 389 | int total = resend + land + wind + cloud + task + texture + asset; |
391 | 390 | ||
391 | float m_burst = total * m_burstTime; | ||
392 | |||
392 | //m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, Total={8}", | 393 | //m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, Total={8}", |
393 | // AgentID, resend, land, wind, cloud, task, texture, asset, total); | 394 | // AgentID, resend, land, wind, cloud, task, texture, asset, total); |
394 | 395 | ||
@@ -397,26 +398,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
397 | 398 | ||
398 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; | 399 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; |
399 | bucket.RequestedDripRate = resend; | 400 | bucket.RequestedDripRate = resend; |
401 | bucket.RequestedBurst = m_burst; | ||
400 | 402 | ||
401 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Land]; | 403 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Land]; |
402 | bucket.RequestedDripRate = land; | 404 | bucket.RequestedDripRate = land; |
405 | bucket.RequestedBurst = m_burst; | ||
403 | 406 | ||
404 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Wind]; | 407 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Wind]; |
405 | bucket.RequestedDripRate = wind; | 408 | bucket.RequestedDripRate = wind; |
409 | bucket.RequestedBurst = m_burst; | ||
406 | 410 | ||
407 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Cloud]; | 411 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Cloud]; |
408 | bucket.RequestedDripRate = cloud; | 412 | bucket.RequestedDripRate = cloud; |
413 | bucket.RequestedBurst = m_burst; | ||
409 | 414 | ||
410 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Asset]; | 415 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Asset]; |
411 | bucket.RequestedDripRate = asset; | 416 | bucket.RequestedDripRate = asset; |
417 | bucket.RequestedBurst = m_burst; | ||
412 | 418 | ||
413 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task]; | 419 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task]; |
414 | bucket.RequestedDripRate = task; | 420 | bucket.RequestedDripRate = task; |
421 | bucket.RequestedBurst = m_burst; | ||
415 | 422 | ||
416 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture]; | 423 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture]; |
417 | bucket.RequestedDripRate = texture; | 424 | bucket.RequestedDripRate = texture; |
418 | 425 | bucket.RequestedBurst = m_burst; | |
419 | m_throttleCategory.RequestedDripRate = total; | ||
420 | 426 | ||
421 | // Reset the packed throttles cached data | 427 | // Reset the packed throttles cached data |
422 | m_packedThrottles = null; | 428 | m_packedThrottles = null; |
@@ -465,10 +471,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
465 | 471 | ||
466 | public int GetCatBytesCanSend(ThrottleOutPacketType cat, int timeMS) | 472 | public int GetCatBytesCanSend(ThrottleOutPacketType cat, int timeMS) |
467 | { | 473 | { |
468 | TokenBucket bucket = m_throttleCategories[(int)cat]; | 474 | int icat = (int)cat; |
469 | int bytes = timeMS * (int)(bucket.RequestedDripRate / 1000); | 475 | if (icat > 0 && icat < THROTTLE_CATEGORY_COUNT) |
470 | bytes += (int)bucket.CurrentTokenCount(); | 476 | { |
471 | return bytes; | 477 | TokenBucket bucket = m_throttleCategories[icat]; |
478 | return bucket.GetCatBytesCanSend(timeMS); | ||
479 | } | ||
480 | else | ||
481 | return 0; | ||
472 | } | 482 | } |
473 | 483 | ||
474 | /// <summary> | 484 | /// <summary> |
@@ -572,6 +582,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
572 | m_udpServer.SendPacketFinal(nextPacket); | 582 | m_udpServer.SendPacketFinal(nextPacket); |
573 | m_nextPackets[i] = null; | 583 | m_nextPackets[i] = null; |
574 | packetSent = true; | 584 | packetSent = true; |
585 | |||
586 | if (m_packetOutboxes[i].Count < 5) | ||
587 | emptyCategories |= CategoryToFlag(i); | ||
575 | } | 588 | } |
576 | } | 589 | } |
577 | else | 590 | else |
@@ -599,6 +612,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
599 | // Send the packet | 612 | // Send the packet |
600 | m_udpServer.SendPacketFinal(packet); | 613 | m_udpServer.SendPacketFinal(packet); |
601 | packetSent = true; | 614 | packetSent = true; |
615 | |||
616 | if (queue.Count < 5) | ||
617 | emptyCategories |= CategoryToFlag(i); | ||
602 | } | 618 | } |
603 | else | 619 | else |
604 | { | 620 | { |
@@ -606,11 +622,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
606 | m_nextPackets[i] = packet; | 622 | m_nextPackets[i] = packet; |
607 | } | 623 | } |
608 | 624 | ||
609 | // If the queue is empty after this dequeue, fire the queue | ||
610 | // empty callback now so it has a chance to fill before we | ||
611 | // get back here | ||
612 | if (queue.Count == 0) | ||
613 | emptyCategories |= CategoryToFlag(i); | ||
614 | } | 625 | } |
615 | else | 626 | else |
616 | { | 627 | { |