aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJohn Hurliman2009-10-20 14:41:20 -0700
committerJohn Hurliman2009-10-20 14:41:20 -0700
commitd38f33736c371cf8c09d78ee5c42b8cc943bb1d7 (patch)
treeddf8282ad62f955b6be80c6c8adcdcfe26ab9548
parentAdded try/catches in the outgoing packet handler to match the one in the inco... (diff)
downloadopensim-SC_OLD-d38f33736c371cf8c09d78ee5c42b8cc943bb1d7.zip
opensim-SC_OLD-d38f33736c371cf8c09d78ee5c42b8cc943bb1d7.tar.gz
opensim-SC_OLD-d38f33736c371cf8c09d78ee5c42b8cc943bb1d7.tar.bz2
opensim-SC_OLD-d38f33736c371cf8c09d78ee5c42b8cc943bb1d7.tar.xz
* Removed the throttle speed optimizations to see if it brings stability back
* Changed the outgoing packet handler to use a real function instead of a closure and to track time on a per-client basis instead of a global basis
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs25
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs116
2 files changed, 69 insertions, 72 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
index 4a3a04e..ec74188 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
@@ -101,6 +101,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
101 public bool IsPaused = true; 101 public bool IsPaused = true;
102 /// <summary>Environment.TickCount when the last packet was received for this client</summary> 102 /// <summary>Environment.TickCount when the last packet was received for this client</summary>
103 public int TickLastPacketReceived; 103 public int TickLastPacketReceived;
104 /// <summary>Environment.TickCount of the last time the outgoing packet handler executed for this client</summary>
105 public int TickLastOutgoingPacketHandler;
104 106
105 /// <summary>Timer granularity. This is set to the measured resolution of Environment.TickCount</summary> 107 /// <summary>Timer granularity. This is set to the measured resolution of Environment.TickCount</summary>
106 public readonly float G; 108 public readonly float G;
@@ -320,27 +322,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
320 bucket.MaxBurst = total; 322 bucket.MaxBurst = total;
321 323
322 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; 324 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend];
323 bucket.DripRate = bucket.MaxBurst = resend; 325 bucket.DripRate = resend;
326 bucket.MaxBurst = resend;
324 327
325 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Land]; 328 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Land];
326 bucket.DripRate = bucket.MaxBurst = land; 329 bucket.DripRate = land;
330 bucket.MaxBurst = land;
327 331
328 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Wind]; 332 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Wind];
329 bucket.DripRate = bucket.MaxBurst = wind; 333 bucket.DripRate = wind;
334 bucket.MaxBurst = wind;
330 335
331 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Cloud]; 336 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Cloud];
332 bucket.DripRate = bucket.MaxBurst = cloud; 337 bucket.DripRate = cloud;
338 bucket.MaxBurst = cloud;
333 339
334 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Asset]; 340 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Asset];
335 bucket.DripRate = bucket.MaxBurst = asset; 341 bucket.DripRate = asset;
342 bucket.MaxBurst = asset;
336 343
337 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task]; 344 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task];
338 bucket.DripRate = task + state + texture; 345 bucket.DripRate = task + state;
339 bucket.MaxBurst = task + state + texture; 346 bucket.MaxBurst = task + state;
340 347
341 bucket = m_throttleCategories[(int)ThrottleOutPacketType.State]; 348 bucket = m_throttleCategories[(int)ThrottleOutPacketType.State];
342 bucket.DripRate = state + texture; 349 bucket.DripRate = state;
343 bucket.MaxBurst = state + texture; 350 bucket.MaxBurst = state;
344 351
345 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture]; 352 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture];
346 bucket.DripRate = texture; 353 bucket.DripRate = texture;
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 3881bdb..80ef95e 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -118,6 +118,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
118 private int m_recvBufferSize; 118 private int m_recvBufferSize;
119 /// <summary>Flag to process packets asynchronously or synchronously</summary> 119 /// <summary>Flag to process packets asynchronously or synchronously</summary>
120 private bool m_asyncPacketHandling; 120 private bool m_asyncPacketHandling;
121 /// <summary>Track whether or not a packet was sent in the
122 /// OutgoingPacketHandler loop so we know when to sleep</summary>
123 private bool m_packetSentLastLoop;
121 124
122 /// <summary>The measured resolution of Environment.TickCount</summary> 125 /// <summary>The measured resolution of Environment.TickCount</summary>
123 public float TickCountResolution { get { return m_tickCountResolution; } } 126 public float TickCountResolution { get { return m_tickCountResolution; } }
@@ -745,10 +748,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
745 748
746 while (base.IsRunning) 749 while (base.IsRunning)
747 { 750 {
748 IncomingPacket incomingPacket = null;
749
750 try 751 try
751 { 752 {
753 IncomingPacket incomingPacket = null;
754
752 if (packetInbox.Dequeue(100, ref incomingPacket)) 755 if (packetInbox.Dequeue(100, ref incomingPacket))
753 Util.FireAndForget(ProcessInPacket, incomingPacket); 756 Util.FireAndForget(ProcessInPacket, incomingPacket);
754 } 757 }
@@ -769,83 +772,70 @@ namespace OpenSim.Region.ClientStack.LindenUDP
769 // on to en-US to avoid number parsing issues 772 // on to en-US to avoid number parsing issues
770 Culture.SetCurrentCulture(); 773 Culture.SetCurrentCulture();
771 774
772 int now = Environment.TickCount;
773 int elapsedMS = 0;
774 int elapsed100MS = 0;
775 int elapsed500MS = 0;
776
777 while (base.IsRunning) 775 while (base.IsRunning)
778 { 776 {
779 try 777 try
780 { 778 {
781 bool resendUnacked = false; 779 m_packetSentLastLoop = false;
782 bool sendAcks = false;
783 bool sendPings = false;
784 bool packetSent = false;
785 780
786 elapsedMS += Environment.TickCount - now; 781 m_scene.ClientManager.ForEachSync(ClientOutgoingPacketHandler);
787 782
788 // Check for pending outgoing resends every 100ms 783 // If no packets at all were sent, sleep to avoid chewing up CPU cycles
789 if (elapsedMS >= 100) 784 // when there is nothing to do
790 { 785 if (!m_packetSentLastLoop)
791 resendUnacked = true; 786 Thread.Sleep(20);
792 elapsedMS -= 100; 787 }
793 ++elapsed100MS; 788 catch (Exception ex)
794 } 789 {
795 // Check for pending outgoing ACKs every 500ms 790 m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler loop threw an exception: " + ex.Message, ex);
796 if (elapsed100MS >= 5) 791 }
797 { 792 }
798 sendAcks = true; 793 }
799 elapsed100MS = 0;
800 ++elapsed500MS;
801 }
802 // Send pings to clients every 5000ms
803 if (elapsed500MS >= 10)
804 {
805 sendPings = true;
806 elapsed500MS = 0;
807 }
808 794
809 m_scene.ClientManager.ForEachSync( 795 private void ClientOutgoingPacketHandler(IClientAPI client)
810 delegate(IClientAPI client) 796 {
797 try
798 {
799 if (client is LLClientView)
800 {
801 LLUDPClient udpClient = ((LLClientView)client).UDPClient;
802
803 int thisTick = Environment.TickCount & Int32.MaxValue;
804 int elapsedMS = thisTick - udpClient.TickLastOutgoingPacketHandler;
805
806 if (udpClient.IsConnected)
807 {
808 // Check for pending outgoing resends every 100ms
809 if (elapsedMS >= 100)
811 { 810 {
812 try 811 ResendUnacked(udpClient);
812
813 // Check for pending outgoing ACKs every 500ms
814 if (elapsedMS >= 500)
813 { 815 {
814 if (client is LLClientView) 816 SendAcks(udpClient);
817
818 // Send pings to clients every 5000ms
819 if (elapsedMS >= 5000)
815 { 820 {
816 LLUDPClient udpClient = ((LLClientView)client).UDPClient; 821 SendPing(udpClient);
817
818 if (udpClient.IsConnected)
819 {
820 if (udpClient.DequeueOutgoing())
821 packetSent = true;
822 if (resendUnacked)
823 ResendUnacked(udpClient);
824 if (sendAcks)
825 {
826 SendAcks(udpClient);
827 udpClient.SendPacketStats();
828 }
829 if (sendPings)
830 SendPing(udpClient);
831 }
832 } 822 }
833 } 823 }
834 catch (Exception ex)
835 {
836 m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name + " threw an exception: " + ex.Message, ex);
837 }
838 } 824 }
839 );
840 825
841 if (!packetSent) 826 // Dequeue any outgoing packets that are within the throttle limits
842 Thread.Sleep(20); 827 if (udpClient.DequeueOutgoing())
843 } 828 m_packetSentLastLoop = true;
844 catch (Exception ex) 829 }
845 { 830
846 m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler loop threw an exception: " + ex.Message, ex); 831 udpClient.TickLastOutgoingPacketHandler = thisTick;
847 } 832 }
848 } 833 }
834 catch (Exception ex)
835 {
836 m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name +
837 " threw an exception: " + ex.Message, ex);
838 }
849 } 839 }
850 840
851 private void ProcessInPacket(object state) 841 private void ProcessInPacket(object state)