diff options
author | Justin Clark-Casey (justincc) | 2013-07-18 21:28:36 +0100 |
---|---|---|
committer | Diva Canto | 2013-07-21 08:56:48 -0700 |
commit | 63c42d66022ea7f1c2805b8f77980af5d4ba1fb4 (patch) | |
tree | 48bbe3212636cc81f525ba0d4c6ae56ad27b3551 /OpenSim/Region/ClientStack/Linden/UDP | |
parent | Merge branch 'master' of ssh://opensimulator.org/var/git/opensim (diff) | |
download | opensim-SC_OLD-63c42d66022ea7f1c2805b8f77980af5d4ba1fb4.zip opensim-SC_OLD-63c42d66022ea7f1c2805b8f77980af5d4ba1fb4.tar.gz opensim-SC_OLD-63c42d66022ea7f1c2805b8f77980af5d4ba1fb4.tar.bz2 opensim-SC_OLD-63c42d66022ea7f1c2805b8f77980af5d4ba1fb4.tar.xz |
Do some simple queue empty checks in the main outgoing udp loop instead of always performing these on a separate fired thread.
This appears to improve cpu usage since launching a new thread is more expensive than performing a small amount of inline logic.
However, needs testing at scale.
Diffstat (limited to '')
5 files changed, 92 insertions, 22 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 7229d7c..711a574 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -485,6 +485,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
485 | m_udpServer = udpServer; | 485 | m_udpServer = udpServer; |
486 | m_udpClient = udpClient; | 486 | m_udpClient = udpClient; |
487 | m_udpClient.OnQueueEmpty += HandleQueueEmpty; | 487 | m_udpClient.OnQueueEmpty += HandleQueueEmpty; |
488 | m_udpClient.HasUpdates += HandleHasUpdates; | ||
488 | m_udpClient.OnPacketStats += PopulateStats; | 489 | m_udpClient.OnPacketStats += PopulateStats; |
489 | 490 | ||
490 | m_prioritizer = new Prioritizer(m_scene); | 491 | m_prioritizer = new Prioritizer(m_scene); |
@@ -4133,8 +4134,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4133 | 4134 | ||
4134 | void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) | 4135 | void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) |
4135 | { | 4136 | { |
4137 | // if (!m_udpServer.IsRunningOutbound) | ||
4138 | // return; | ||
4139 | |||
4136 | if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) | 4140 | if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) |
4137 | { | 4141 | { |
4142 | // if (!m_udpServer.IsRunningOutbound) | ||
4143 | // return; | ||
4144 | |||
4138 | if (m_maxUpdates == 0 || m_LastQueueFill == 0) | 4145 | if (m_maxUpdates == 0 || m_LastQueueFill == 0) |
4139 | { | 4146 | { |
4140 | m_maxUpdates = m_udpServer.PrimUpdatesPerCallback; | 4147 | m_maxUpdates = m_udpServer.PrimUpdatesPerCallback; |
@@ -4160,6 +4167,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4160 | ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit); | 4167 | ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit); |
4161 | } | 4168 | } |
4162 | 4169 | ||
4170 | internal bool HandleHasUpdates(ThrottleOutPacketTypeFlags categories) | ||
4171 | { | ||
4172 | bool hasUpdates = false; | ||
4173 | |||
4174 | if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) | ||
4175 | { | ||
4176 | if (m_entityUpdates.Count > 0) | ||
4177 | hasUpdates = true; | ||
4178 | else if (m_entityProps.Count > 0) | ||
4179 | hasUpdates = true; | ||
4180 | } | ||
4181 | |||
4182 | if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) | ||
4183 | { | ||
4184 | if (ImageManager.HasUpdates()) | ||
4185 | hasUpdates = true; | ||
4186 | } | ||
4187 | |||
4188 | return hasUpdates; | ||
4189 | } | ||
4190 | |||
4163 | public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) | 4191 | public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) |
4164 | { | 4192 | { |
4165 | AssetUploadCompletePacket newPack = new AssetUploadCompletePacket(); | 4193 | AssetUploadCompletePacket newPack = new AssetUploadCompletePacket(); |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs index 073c357..41dd4d1 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs | |||
@@ -206,6 +206,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
206 | } | 206 | } |
207 | } | 207 | } |
208 | 208 | ||
209 | public bool HasUpdates() | ||
210 | { | ||
211 | J2KImage image = GetHighestPriorityImage(); | ||
212 | |||
213 | return image != null && image.IsDecoded; | ||
214 | } | ||
215 | |||
209 | public bool ProcessImageQueue(int packetsToSend) | 216 | public bool ProcessImageQueue(int packetsToSend) |
210 | { | 217 | { |
211 | int packetsSent = 0; | 218 | int packetsSent = 0; |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index 7749446..202cc62 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs | |||
@@ -31,6 +31,7 @@ using System.Net; | |||
31 | using System.Threading; | 31 | using System.Threading; |
32 | using log4net; | 32 | using log4net; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Framework.Monitoring; | ||
34 | using OpenMetaverse; | 35 | using OpenMetaverse; |
35 | using OpenMetaverse.Packets; | 36 | using OpenMetaverse.Packets; |
36 | 37 | ||
@@ -81,6 +82,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
81 | /// hooked to put more data on the empty queue</summary> | 82 | /// hooked to put more data on the empty queue</summary> |
82 | public event QueueEmpty OnQueueEmpty; | 83 | public event QueueEmpty OnQueueEmpty; |
83 | 84 | ||
85 | public event Func<ThrottleOutPacketTypeFlags, bool> HasUpdates; | ||
86 | |||
84 | /// <summary>AgentID for this client</summary> | 87 | /// <summary>AgentID for this client</summary> |
85 | public readonly UUID AgentID; | 88 | public readonly UUID AgentID; |
86 | /// <summary>The remote address of the connected client</summary> | 89 | /// <summary>The remote address of the connected client</summary> |
@@ -613,15 +616,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
613 | /// <param name="categories">Throttle categories to fire the callback for</param> | 616 | /// <param name="categories">Throttle categories to fire the callback for</param> |
614 | private void BeginFireQueueEmpty(ThrottleOutPacketTypeFlags categories) | 617 | private void BeginFireQueueEmpty(ThrottleOutPacketTypeFlags categories) |
615 | { | 618 | { |
616 | if (m_nextOnQueueEmpty != 0 && (Environment.TickCount & Int32.MaxValue) >= m_nextOnQueueEmpty) | 619 | // if (m_nextOnQueueEmpty != 0 && (Environment.TickCount & Int32.MaxValue) >= m_nextOnQueueEmpty) |
620 | if (!m_isQueueEmptyRunning && (Environment.TickCount & Int32.MaxValue) >= m_nextOnQueueEmpty) | ||
617 | { | 621 | { |
622 | m_isQueueEmptyRunning = true; | ||
623 | |||
624 | int start = Environment.TickCount & Int32.MaxValue; | ||
625 | const int MIN_CALLBACK_MS = 30; | ||
626 | |||
627 | m_nextOnQueueEmpty = start + MIN_CALLBACK_MS; | ||
628 | if (m_nextOnQueueEmpty == 0) | ||
629 | m_nextOnQueueEmpty = 1; | ||
630 | |||
618 | // Use a value of 0 to signal that FireQueueEmpty is running | 631 | // Use a value of 0 to signal that FireQueueEmpty is running |
619 | m_nextOnQueueEmpty = 0; | 632 | // m_nextOnQueueEmpty = 0; |
620 | // Asynchronously run the callback | 633 | |
621 | Util.FireAndForget(FireQueueEmpty, categories); | 634 | m_categories = categories; |
635 | |||
636 | if (HasUpdates(m_categories)) | ||
637 | { | ||
638 | // Asynchronously run the callback | ||
639 | Util.FireAndForget(FireQueueEmpty, categories); | ||
640 | } | ||
641 | else | ||
642 | { | ||
643 | m_isQueueEmptyRunning = false; | ||
644 | } | ||
622 | } | 645 | } |
623 | } | 646 | } |
624 | 647 | ||
648 | private bool m_isQueueEmptyRunning; | ||
649 | private ThrottleOutPacketTypeFlags m_categories = 0; | ||
650 | |||
625 | /// <summary> | 651 | /// <summary> |
626 | /// Fires the OnQueueEmpty callback and sets the minimum time that it | 652 | /// Fires the OnQueueEmpty callback and sets the minimum time that it |
627 | /// can be called again | 653 | /// can be called again |
@@ -631,22 +657,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
631 | /// signature</param> | 657 | /// signature</param> |
632 | private void FireQueueEmpty(object o) | 658 | private void FireQueueEmpty(object o) |
633 | { | 659 | { |
634 | const int MIN_CALLBACK_MS = 30; | 660 | // int start = Environment.TickCount & Int32.MaxValue; |
661 | // const int MIN_CALLBACK_MS = 30; | ||
635 | 662 | ||
636 | ThrottleOutPacketTypeFlags categories = (ThrottleOutPacketTypeFlags)o; | 663 | // if (m_udpServer.IsRunningOutbound) |
637 | QueueEmpty callback = OnQueueEmpty; | 664 | // { |
638 | 665 | ThrottleOutPacketTypeFlags categories = (ThrottleOutPacketTypeFlags)o; | |
639 | int start = Environment.TickCount & Int32.MaxValue; | 666 | QueueEmpty callback = OnQueueEmpty; |
640 | 667 | ||
641 | if (callback != null) | 668 | if (callback != null) |
642 | { | 669 | { |
643 | try { callback(categories); } | 670 | // if (m_udpServer.IsRunningOutbound) |
644 | catch (Exception e) { m_log.Error("[LLUDPCLIENT]: OnQueueEmpty(" + categories + ") threw an exception: " + e.Message, e); } | 671 | // { |
645 | } | 672 | try { callback(categories); } |
673 | catch (Exception e) { m_log.Error("[LLUDPCLIENT]: OnQueueEmpty(" + categories + ") threw an exception: " + e.Message, e); } | ||
674 | // } | ||
675 | } | ||
676 | // } | ||
677 | |||
678 | // m_nextOnQueueEmpty = start + MIN_CALLBACK_MS; | ||
679 | // if (m_nextOnQueueEmpty == 0) | ||
680 | // m_nextOnQueueEmpty = 1; | ||
681 | |||
682 | // } | ||
646 | 683 | ||
647 | m_nextOnQueueEmpty = start + MIN_CALLBACK_MS; | 684 | m_isQueueEmptyRunning = false; |
648 | if (m_nextOnQueueEmpty == 0) | ||
649 | m_nextOnQueueEmpty = 1; | ||
650 | } | 685 | } |
651 | 686 | ||
652 | /// <summary> | 687 | /// <summary> |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 54cafb2..e871ca2 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -1662,8 +1662,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1662 | // Action generic every round | 1662 | // Action generic every round |
1663 | Action<IClientAPI> clientPacketHandler = ClientOutgoingPacketHandler; | 1663 | Action<IClientAPI> clientPacketHandler = ClientOutgoingPacketHandler; |
1664 | 1664 | ||
1665 | // while (true) | 1665 | while (true) |
1666 | while (base.IsRunningOutbound) | 1666 | // while (base.IsRunningOutbound) |
1667 | { | 1667 | { |
1668 | try | 1668 | try |
1669 | { | 1669 | { |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index f143c32..512f60d 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | |||
@@ -308,8 +308,8 @@ namespace OpenMetaverse | |||
308 | 308 | ||
309 | public void AsyncBeginSend(UDPPacketBuffer buf) | 309 | public void AsyncBeginSend(UDPPacketBuffer buf) |
310 | { | 310 | { |
311 | if (IsRunningOutbound) | 311 | // if (IsRunningOutbound) |
312 | { | 312 | // { |
313 | try | 313 | try |
314 | { | 314 | { |
315 | m_udpSocket.BeginSendTo( | 315 | m_udpSocket.BeginSendTo( |
@@ -323,7 +323,7 @@ namespace OpenMetaverse | |||
323 | } | 323 | } |
324 | catch (SocketException) { } | 324 | catch (SocketException) { } |
325 | catch (ObjectDisposedException) { } | 325 | catch (ObjectDisposedException) { } |
326 | } | 326 | // } |
327 | } | 327 | } |
328 | 328 | ||
329 | void AsyncEndSend(IAsyncResult result) | 329 | void AsyncEndSend(IAsyncResult result) |