aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
diff options
context:
space:
mode:
authorJohn Hurliman2009-10-21 00:18:35 -0700
committerJohn Hurliman2009-10-21 00:18:35 -0700
commitcde47c2b3d7089be556252246eb03365c1f39b54 (patch)
treeb0b1cddc57f786a2d5945c1117cddda75e52b1ed /OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
parent* Added a sanity check to GetScriptAssemblies() and GetScriptStates() for the... (diff)
downloadopensim-SC_OLD-cde47c2b3d7089be556252246eb03365c1f39b54.zip
opensim-SC_OLD-cde47c2b3d7089be556252246eb03365c1f39b54.tar.gz
opensim-SC_OLD-cde47c2b3d7089be556252246eb03365c1f39b54.tar.bz2
opensim-SC_OLD-cde47c2b3d7089be556252246eb03365c1f39b54.tar.xz
Committing Jim's optimization to replace the 20ms sleep in outgoing packet handling with an interruptible wait handle
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs51
1 files changed, 35 insertions, 16 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
index 134cfe5..b9d2c15 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
@@ -105,9 +105,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
105 public int TickLastPacketReceived; 105 public int TickLastPacketReceived;
106 /// <summary>Environment.TickCount of the last time the outgoing packet handler executed for this client</summary> 106 /// <summary>Environment.TickCount of the last time the outgoing packet handler executed for this client</summary>
107 public int TickLastOutgoingPacketHandler; 107 public int TickLastOutgoingPacketHandler;
108 /// <summary>Keeps track of the number of elapsed milliseconds since the last time the outgoing packet handler executed for this client</summary>
109 public int ElapsedMSOutgoingPacketHandler;
110 /// <summary>Keeps track of the number of 100 millisecond periods elapsed in the outgoing packet handler executed for this client</summary>
111 public int Elapsed100MSOutgoingPacketHandler;
112 /// <summary>Keeps track of the number of 500 millisecond periods elapsed in the outgoing packet handler executed for this client</summary>
113 public int Elapsed500MSOutgoingPacketHandler;
108 114
109 /// <summary>Timer granularity. This is set to the measured resolution of Environment.TickCount</summary>
110 public readonly float G;
111 /// <summary>Smoothed round-trip time. A smoothed average of the round-trip time for sending a 115 /// <summary>Smoothed round-trip time. A smoothed average of the round-trip time for sending a
112 /// reliable packet to the client and receiving an ACK</summary> 116 /// reliable packet to the client and receiving an ACK</summary>
113 public float SRTT; 117 public float SRTT;
@@ -182,15 +186,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
182 m_throttleCategories[i] = new TokenBucket(m_throttle, rates.GetLimit(type), rates.GetRate(type)); 186 m_throttleCategories[i] = new TokenBucket(m_throttle, rates.GetLimit(type), rates.GetRate(type));
183 } 187 }
184 188
185 // Set the granularity variable used for retransmission calculations to
186 // the measured resolution of Environment.TickCount
187 G = server.TickCountResolution;
188
189 // Default the retransmission timeout to three seconds 189 // Default the retransmission timeout to three seconds
190 RTO = 3000; 190 RTO = 3000;
191 191
192 // Initialize this to a sane value to prevent early disconnects 192 // Initialize this to a sane value to prevent early disconnects
193 TickLastPacketReceived = Environment.TickCount; 193 TickLastPacketReceived = Environment.TickCount & Int32.MaxValue;
194 ElapsedMSOutgoingPacketHandler = 0;
195 Elapsed100MSOutgoingPacketHandler = 0;
196 Elapsed500MSOutgoingPacketHandler = 0;
194 } 197 }
195 198
196 /// <summary> 199 /// <summary>
@@ -391,6 +394,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
391 { 394 {
392 // Not enough tokens in the bucket, queue this packet 395 // Not enough tokens in the bucket, queue this packet
393 queue.Enqueue(packet); 396 queue.Enqueue(packet);
397 m_udpServer.SignalOutgoingPacketHandler();
394 return true; 398 return true;
395 } 399 }
396 } 400 }
@@ -407,13 +411,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
407 /// </summary> 411 /// </summary>
408 /// <remarks>This function is only called from a synchronous loop in the 412 /// <remarks>This function is only called from a synchronous loop in the
409 /// UDPServer so we don't need to bother making this thread safe</remarks> 413 /// UDPServer so we don't need to bother making this thread safe</remarks>
410 /// <returns>True if any packets were sent, otherwise false</returns> 414 /// <returns>The minimum amount of time before the next packet
411 public bool DequeueOutgoing() 415 /// can be sent to this client</returns>
416 public int DequeueOutgoing()
412 { 417 {
413 OutgoingPacket packet; 418 OutgoingPacket packet;
414 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 419 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
415 TokenBucket bucket; 420 TokenBucket bucket;
416 bool packetSent = false; 421 int dataLength;
422 int minTimeout = Int32.MaxValue;
417 423
418 //string queueDebugOutput = String.Empty; // Serious debug business 424 //string queueDebugOutput = String.Empty; // Serious debug business
419 425
@@ -428,12 +434,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
428 // leaving a dequeued packet still waiting to be sent out. Try to 434 // leaving a dequeued packet still waiting to be sent out. Try to
429 // send it again 435 // send it again
430 OutgoingPacket nextPacket = m_nextPackets[i]; 436 OutgoingPacket nextPacket = m_nextPackets[i];
431 if (bucket.RemoveTokens(nextPacket.Buffer.DataLength)) 437 dataLength = nextPacket.Buffer.DataLength;
438 if (bucket.RemoveTokens(dataLength))
432 { 439 {
433 // Send the packet 440 // Send the packet
434 m_udpServer.SendPacketFinal(nextPacket); 441 m_udpServer.SendPacketFinal(nextPacket);
435 m_nextPackets[i] = null; 442 m_nextPackets[i] = null;
436 packetSent = true; 443 minTimeout = 0;
444 }
445 else if (minTimeout != 0)
446 {
447 // Check the minimum amount of time we would have to wait before this packet can be sent out
448 minTimeout = Math.Min(minTimeout, ((dataLength - bucket.Content) / bucket.DripPerMS) + 1);
437 } 449 }
438 } 450 }
439 else 451 else
@@ -445,16 +457,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
445 { 457 {
446 // A packet was pulled off the queue. See if we have 458 // A packet was pulled off the queue. See if we have
447 // enough tokens in the bucket to send it out 459 // enough tokens in the bucket to send it out
448 if (bucket.RemoveTokens(packet.Buffer.DataLength)) 460 dataLength = packet.Buffer.DataLength;
461 if (bucket.RemoveTokens(dataLength))
449 { 462 {
450 // Send the packet 463 // Send the packet
451 m_udpServer.SendPacketFinal(packet); 464 m_udpServer.SendPacketFinal(packet);
452 packetSent = true; 465 minTimeout = 0;
453 } 466 }
454 else 467 else
455 { 468 {
456 // Save the dequeued packet for the next iteration 469 // Save the dequeued packet for the next iteration
457 m_nextPackets[i] = packet; 470 m_nextPackets[i] = packet;
471
472 if (minTimeout != 0)
473 {
474 // Check the minimum amount of time we would have to wait before this packet can be sent out
475 minTimeout = Math.Min(minTimeout, ((dataLength - bucket.Content) / bucket.DripPerMS) + 1);
476 }
458 } 477 }
459 478
460 // If the queue is empty after this dequeue, fire the queue 479 // If the queue is empty after this dequeue, fire the queue
@@ -473,7 +492,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
473 } 492 }
474 493
475 //m_log.Info("[LLUDPCLIENT]: Queues: " + queueDebugOutput); // Serious debug business 494 //m_log.Info("[LLUDPCLIENT]: Queues: " + queueDebugOutput); // Serious debug business
476 return packetSent; 495 return minTimeout;
477 } 496 }
478 497
479 /// <summary> 498 /// <summary>
@@ -504,7 +523,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
504 } 523 }
505 524
506 // Always round retransmission timeout up to two seconds 525 // Always round retransmission timeout up to two seconds
507 RTO = Math.Max(2000, (int)(SRTT + Math.Max(G, K * RTTVAR))); 526 RTO = Math.Max(2000, (int)(SRTT + Math.Max(m_udpServer.TickCountResolution, K * RTTVAR)));
508 //m_log.Debug("[LLUDPCLIENT]: Setting agent " + this.Agent.FullName + "'s RTO to " + RTO + "ms with an RTTVAR of " + 527 //m_log.Debug("[LLUDPCLIENT]: Setting agent " + this.Agent.FullName + "'s RTO to " + RTO + "ms with an RTTVAR of " +
509 // RTTVAR + " based on new RTT of " + r + "ms"); 528 // RTTVAR + " based on new RTT of " + r + "ms");
510 } 529 }