aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2013-07-18 21:28:36 +0100
committerDiva Canto2013-07-21 08:56:48 -0700
commit63c42d66022ea7f1c2805b8f77980af5d4ba1fb4 (patch)
tree48bbe3212636cc81f525ba0d4c6ae56ad27b3551
parentMerge branch 'master' of ssh://opensimulator.org/var/git/opensim (diff)
downloadopensim-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.
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs28
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs7
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs69
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs6
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;
31using System.Threading; 31using System.Threading;
32using log4net; 32using log4net;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Framework.Monitoring;
34using OpenMetaverse; 35using OpenMetaverse;
35using OpenMetaverse.Packets; 36using 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)