diff options
author | John Hurliman | 2009-10-20 14:41:20 -0700 |
---|---|---|
committer | John Hurliman | 2009-10-20 14:41:20 -0700 |
commit | d38f33736c371cf8c09d78ee5c42b8cc943bb1d7 (patch) | |
tree | ddf8282ad62f955b6be80c6c8adcdcfe26ab9548 /OpenSim/Region | |
parent | Added try/catches in the outgoing packet handler to match the one in the inco... (diff) | |
download | opensim-SC-d38f33736c371cf8c09d78ee5c42b8cc943bb1d7.zip opensim-SC-d38f33736c371cf8c09d78ee5c42b8cc943bb1d7.tar.gz opensim-SC-d38f33736c371cf8c09d78ee5c42b8cc943bb1d7.tar.bz2 opensim-SC-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
Diffstat (limited to 'OpenSim/Region')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | 25 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 116 |
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) |