aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs96
1 files changed, 65 insertions, 31 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index e52ac37..d52ad7e 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>
@@ -160,6 +163,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
160 private int m_maxRTO = 60000; 163 private int m_maxRTO = 60000;
161 public bool m_deliverPackets = true; 164 public bool m_deliverPackets = true;
162 165
166 private ClientInfo m_info = new ClientInfo();
167
163 /// <summary> 168 /// <summary>
164 /// Default constructor 169 /// Default constructor
165 /// </summary> 170 /// </summary>
@@ -241,20 +246,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
241 // TODO: This data structure is wrong in so many ways. Locking and copying the entire lists 246 // TODO: This data structure is wrong in so many ways. Locking and copying the entire lists
242 // of pending and needed ACKs for every client every time some method wants information about 247 // of pending and needed ACKs for every client every time some method wants information about
243 // this connection is a recipe for poor performance 248 // this connection is a recipe for poor performance
244 ClientInfo info = new ClientInfo(); 249
245 info.pendingAcks = new Dictionary<uint, uint>(); 250 m_info.resendThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Resend].DripRate;
246 info.needAck = new Dictionary<uint, byte[]>(); 251 m_info.landThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate;
247 252 m_info.windThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate;
248 info.resendThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Resend].DripRate; 253 m_info.cloudThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate;
249 info.landThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate; 254 m_info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate;
250 info.windThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate; 255 m_info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate;
251 info.cloudThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate; 256 m_info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate;
252 info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; 257 m_info.totalThrottle = (int)m_throttleCategory.DripRate;
253 info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; 258
254 info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; 259 return m_info;
255 info.totalThrottle = (int)m_throttleCategory.DripRate;
256
257 return info;
258 } 260 }
259 261
260 /// <summary> 262 /// <summary>
@@ -646,15 +648,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP
646 /// <param name="categories">Throttle categories to fire the callback for</param> 648 /// <param name="categories">Throttle categories to fire the callback for</param>
647 private void BeginFireQueueEmpty(ThrottleOutPacketTypeFlags categories) 649 private void BeginFireQueueEmpty(ThrottleOutPacketTypeFlags categories)
648 { 650 {
649 if (m_nextOnQueueEmpty != 0 && (Environment.TickCount & Int32.MaxValue) >= m_nextOnQueueEmpty) 651// if (m_nextOnQueueEmpty != 0 && (Environment.TickCount & Int32.MaxValue) >= m_nextOnQueueEmpty)
652 if (!m_isQueueEmptyRunning && (Environment.TickCount & Int32.MaxValue) >= m_nextOnQueueEmpty)
650 { 653 {
654 m_isQueueEmptyRunning = true;
655
656 int start = Environment.TickCount & Int32.MaxValue;
657 const int MIN_CALLBACK_MS = 30;
658
659 m_nextOnQueueEmpty = start + MIN_CALLBACK_MS;
660 if (m_nextOnQueueEmpty == 0)
661 m_nextOnQueueEmpty = 1;
662
651 // Use a value of 0 to signal that FireQueueEmpty is running 663 // Use a value of 0 to signal that FireQueueEmpty is running
652 m_nextOnQueueEmpty = 0; 664// m_nextOnQueueEmpty = 0;
653 // Asynchronously run the callback 665
654 Util.FireAndForget(FireQueueEmpty, categories); 666 m_categories = categories;
667
668 if (HasUpdates(m_categories))
669 {
670 // Asynchronously run the callback
671 Util.FireAndForget(FireQueueEmpty, categories);
672 }
673 else
674 {
675 m_isQueueEmptyRunning = false;
676 }
655 } 677 }
656 } 678 }
657 679
680 private bool m_isQueueEmptyRunning;
681 private ThrottleOutPacketTypeFlags m_categories = 0;
682
658 /// <summary> 683 /// <summary>
659 /// Fires the OnQueueEmpty callback and sets the minimum time that it 684 /// Fires the OnQueueEmpty callback and sets the minimum time that it
660 /// can be called again 685 /// can be called again
@@ -664,22 +689,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP
664 /// signature</param> 689 /// signature</param>
665 private void FireQueueEmpty(object o) 690 private void FireQueueEmpty(object o)
666 { 691 {
667 const int MIN_CALLBACK_MS = 30; 692// int start = Environment.TickCount & Int32.MaxValue;
693// const int MIN_CALLBACK_MS = 30;
668 694
669 ThrottleOutPacketTypeFlags categories = (ThrottleOutPacketTypeFlags)o; 695// if (m_udpServer.IsRunningOutbound)
670 QueueEmpty callback = OnQueueEmpty; 696// {
671 697 ThrottleOutPacketTypeFlags categories = (ThrottleOutPacketTypeFlags)o;
672 int start = Environment.TickCount & Int32.MaxValue; 698 QueueEmpty callback = OnQueueEmpty;
673 699
674 if (callback != null) 700 if (callback != null)
675 { 701 {
676 try { callback(categories); } 702// if (m_udpServer.IsRunningOutbound)
677 catch (Exception e) { m_log.Error("[LLUDPCLIENT]: OnQueueEmpty(" + categories + ") threw an exception: " + e.Message, e); } 703// {
678 } 704 try { callback(categories); }
705 catch (Exception e) { m_log.Error("[LLUDPCLIENT]: OnQueueEmpty(" + categories + ") threw an exception: " + e.Message, e); }
706// }
707 }
708// }
709
710// m_nextOnQueueEmpty = start + MIN_CALLBACK_MS;
711// if (m_nextOnQueueEmpty == 0)
712// m_nextOnQueueEmpty = 1;
713
714// }
679 715
680 m_nextOnQueueEmpty = start + MIN_CALLBACK_MS; 716 m_isQueueEmptyRunning = false;
681 if (m_nextOnQueueEmpty == 0)
682 m_nextOnQueueEmpty = 1;
683 } 717 }
684 internal void ForceThrottleSetting(int throttle, int setting) 718 internal void ForceThrottleSetting(int throttle, int setting)
685 { 719 {