aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs6
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs71
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs9
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs64
4 files changed, 60 insertions, 90 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
index 1448722..b958b01 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
@@ -232,6 +232,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
232 232
233 m_packetNumber = m_requestedPacketNumber; 233 m_packetNumber = m_requestedPacketNumber;
234 } 234 }
235
236 if (m_imageManager.Client.PacketHandler.GetQueueCount(ThrottleOutPacketType.Texture) == 0)
237 {
238 m_log.Debug("No textures queued, sending one packet to kickstart it");
239 SendPacket(m_imageManager.Client);
240 }
235 } 241 }
236 } 242 }
237 } 243 }
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 460f94e..23fa1a3 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -81,8 +81,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
81 private List<ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates = 81 private List<ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates =
82 new List<ObjectUpdatePacket.ObjectDataBlock>(); 82 new List<ObjectUpdatePacket.ObjectDataBlock>();
83 83
84 private Timer m_textureRequestTimer;
85
86 private bool m_clientBlocked; 84 private bool m_clientBlocked;
87 85
88 private int m_probesWithNoIngressPackets; 86 private int m_probesWithNoIngressPackets;
@@ -143,9 +141,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
143 protected int m_primTerseUpdateRate = 10; 141 protected int m_primTerseUpdateRate = 10;
144 protected int m_primFullUpdateRate = 14; 142 protected int m_primFullUpdateRate = 14;
145 143
146 protected int m_textureRequestRate = 100; 144 protected int m_textureSendLimit = 100;
147 protected int m_textureSendLimit = 10; 145 protected int m_textureDataLimit = 10;
148 protected int m_textureDataLimit = 5;
149 146
150 protected int m_packetMTU = 1400; 147 protected int m_packetMTU = 1400;
151 148
@@ -534,6 +531,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
534 m_PacketHandler = new LLPacketHandler(this, m_networkServer, userSettings); 531 m_PacketHandler = new LLPacketHandler(this, m_networkServer, userSettings);
535 m_PacketHandler.SynchronizeClient = SynchronizeClient; 532 m_PacketHandler.SynchronizeClient = SynchronizeClient;
536 m_PacketHandler.OnPacketStats += PopulateStats; 533 m_PacketHandler.OnPacketStats += PopulateStats;
534 m_PacketHandler.OnQueueEmpty += HandleQueueEmpty;
537 535
538 if (scene.Config != null) 536 if (scene.Config != null)
539 { 537 {
@@ -555,9 +553,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
555 m_primFullUpdateRate = clientConfig.GetInt("FullUpdateRate", 553 m_primFullUpdateRate = clientConfig.GetInt("FullUpdateRate",
556 m_primFullUpdateRate); 554 m_primFullUpdateRate);
557 555
558 m_textureRequestRate = clientConfig.GetInt("TextureRequestRate",
559 m_textureRequestRate);
560
561 m_textureSendLimit = clientConfig.GetInt("TextureSendLimit", 556 m_textureSendLimit = clientConfig.GetInt("TextureSendLimit",
562 m_textureSendLimit); 557 m_textureSendLimit);
563 558
@@ -607,9 +602,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
607 if (m_primFullUpdateTimer.Enabled) 602 if (m_primFullUpdateTimer.Enabled)
608 lock (m_primFullUpdateTimer) 603 lock (m_primFullUpdateTimer)
609 m_primFullUpdateTimer.Stop(); 604 m_primFullUpdateTimer.Stop();
610 if (m_textureRequestTimer.Enabled)
611 lock (m_textureRequestTimer)
612 m_textureRequestTimer.Stop();
613 605
614 // This is just to give the client a reasonable chance of 606 // This is just to give the client a reasonable chance of
615 // flushing out all it's packets. There should probably 607 // flushing out all it's packets. There should probably
@@ -706,10 +698,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
706 if (m_primFullUpdateTimer.Enabled) 698 if (m_primFullUpdateTimer.Enabled)
707 lock (m_primFullUpdateTimer) 699 lock (m_primFullUpdateTimer)
708 m_primFullUpdateTimer.Stop(); 700 m_primFullUpdateTimer.Stop();
709
710 if (m_textureRequestTimer.Enabled)
711 lock (m_textureRequestTimer)
712 m_textureRequestTimer.Stop();
713 } 701 }
714 702
715 public void Restart() 703 public void Restart()
@@ -732,11 +720,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
732 m_primFullUpdateTimer = new Timer(m_primFullUpdateRate); 720 m_primFullUpdateTimer = new Timer(m_primFullUpdateRate);
733 m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); 721 m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates);
734 m_primFullUpdateTimer.AutoReset = false; 722 m_primFullUpdateTimer.AutoReset = false;
735
736 m_textureRequestTimer = new Timer(m_textureRequestRate);
737 m_textureRequestTimer.Elapsed += new ElapsedEventHandler(ProcessTextureRequests);
738 m_textureRequestTimer.AutoReset = false;
739
740 } 723 }
741 724
742 private void Terminate() 725 private void Terminate()
@@ -747,7 +730,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
747 m_avatarTerseUpdateTimer.Close(); 730 m_avatarTerseUpdateTimer.Close();
748 m_primTerseUpdateTimer.Close(); 731 m_primTerseUpdateTimer.Close();
749 m_primFullUpdateTimer.Close(); 732 m_primFullUpdateTimer.Close();
750 m_textureRequestTimer.Close();
751 733
752 m_PacketHandler.OnPacketStats -= PopulateStats; 734 m_PacketHandler.OnPacketStats -= PopulateStats;
753 m_PacketHandler.Dispose(); 735 m_PacketHandler.Dispose();
@@ -982,10 +964,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
982 m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); 964 m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates);
983 m_primFullUpdateTimer.AutoReset = false; 965 m_primFullUpdateTimer.AutoReset = false;
984 966
985 m_textureRequestTimer = new Timer(m_textureRequestRate);
986 m_textureRequestTimer.Elapsed += new ElapsedEventHandler(ProcessTextureRequests);
987 m_textureRequestTimer.AutoReset = false;
988
989 m_scene.AddNewClient(this); 967 m_scene.AddNewClient(this);
990 968
991 RefreshGroupMembership(); 969 RefreshGroupMembership();
@@ -1057,26 +1035,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1057 } 1035 }
1058 } 1036 }
1059 1037
1060 protected virtual void TextureRequestHandler()
1061 {
1062 m_log.DebugFormat("[TRH] Thread started");
1063 while (m_imageManager != null)
1064 {
1065 try
1066 {
1067 while (m_imageManager != null)
1068 {
1069 }
1070 }
1071 catch (Exception e)
1072 {
1073 m_log.WarnFormat("[TRH] Exception in handler loop: {0}", e.Message);
1074 m_log.Debug(e);
1075 }
1076 }
1077 m_log.DebugFormat("[TRH] Thread terminated");
1078 }
1079
1080 # endregion 1038 # endregion
1081 1039
1082 // Previously ClientView.API partial class 1040 // Previously ClientView.API partial class
@@ -3176,16 +3134,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3176 // Unlike the other timers, this one is only started after 3134 // Unlike the other timers, this one is only started after
3177 // the first request is seen. 3135 // the first request is seen.
3178 3136
3179 void ProcessTextureRequests(object sender, ElapsedEventArgs e) 3137 void HandleQueueEmpty(ThrottleOutPacketType queue)
3138 {
3139 switch (queue)
3140 {
3141 case ThrottleOutPacketType.Texture:
3142 m_log.Debug("Texture queue empty");
3143 ProcessTextureRequests();
3144 break;
3145 }
3146 }
3147
3148 void ProcessTextureRequests()
3180 { 3149 {
3181 if (m_imageManager != null) 3150 if (m_imageManager != null)
3182 { 3151 {
3183 if (m_imageManager.ProcessImageQueue(m_textureSendLimit, 3152 m_imageManager.ProcessImageQueue(m_textureSendLimit,
3184 m_textureDataLimit)) 3153 m_textureDataLimit);
3185 {
3186 lock (m_textureRequestTimer)
3187 m_textureRequestTimer.Start();
3188 }
3189 } 3154 }
3190 } 3155 }
3191 3156
@@ -6638,8 +6603,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6638 if (m_imageManager != null) 6603 if (m_imageManager != null)
6639 { 6604 {
6640 m_imageManager.EnqueueReq(args); 6605 m_imageManager.EnqueueReq(args);
6641 lock (m_textureRequestTimer)
6642 m_textureRequestTimer.Start();
6643 } 6606 }
6644 } 6607 }
6645 } 6608 }
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
index 70af8e8..1556d01 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
@@ -65,6 +65,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
65 m_j2kDecodeModule = pJ2kDecodeModule; 65 m_j2kDecodeModule = pJ2kDecodeModule;
66 } 66 }
67 67
68 public LLClientView Client
69 {
70 get { return m_client; }
71 }
72
68 public void EnqueueReq(TextureRequestArgs newRequest) 73 public void EnqueueReq(TextureRequestArgs newRequest)
69 { 74 {
70 //newRequest is the properties of our new texture fetch request. 75 //newRequest is the properties of our new texture fetch request.
@@ -207,8 +212,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
207 threshold = 10; 212 threshold = 10;
208 213
209 //Uncomment this to see what the texture stack is doing 214 //Uncomment this to see what the texture stack is doing
210 //m_log.Debug("Queue: " + m_client.PacketHandler.PacketQueue.TextureOutgoingPacketQueueCount.ToString() + " Threshold: " + threshold.ToString() + " outstanding: " + m_outstandingtextures.ToString()); 215 //m_log.Debug("Queue: " + m_client.PacketHandler.PacketQueue.getQueueCount(ThrottleOutPacketType.Texture).ToString() + " Threshold: " + threshold.ToString() + " outstanding: " + m_outstandingtextures.ToString());
211 if (m_client.PacketHandler.PacketQueue.TextureOutgoingPacketQueueCount < threshold) 216 if (m_client.PacketHandler.PacketQueue.GetQueueCount(ThrottleOutPacketType.Texture) < threshold)
212 { 217 {
213 while (m_priorityQueue.Count > 0) 218 while (m_priorityQueue.Count > 0)
214 { 219 {
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs
index d4d654f..8484846 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs
@@ -62,6 +62,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
62 private Queue<LLQueItem> TextureOutgoingPacketQueue; 62 private Queue<LLQueItem> TextureOutgoingPacketQueue;
63 private Queue<LLQueItem> AssetOutgoingPacketQueue; 63 private Queue<LLQueItem> AssetOutgoingPacketQueue;
64 64
65 private List<ThrottleOutPacketType> Empty = new List<ThrottleOutPacketType>();
66 // m_log.Info("[THROTTLE]: Entering Throttle");
65 // private Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>(); 67 // private Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>();
66 // private Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>(); 68 // private Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>();
67 69
@@ -85,20 +87,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
85 87
86 private Dictionary<uint,int> contents = new Dictionary<uint, int>(); 88 private Dictionary<uint,int> contents = new Dictionary<uint, int>();
87 89
88 /// <summary>
89 /// The number of packets in the OutgoingPacketQueue
90 ///
91 /// </summary>
92 internal int TextureOutgoingPacketQueueCount
93 {
94 get
95 {
96 if (TextureOutgoingPacketQueue == null)
97 return 0;
98 return TextureOutgoingPacketQueue.Count;
99 }
100 }
101
102 // private long LastThrottle; 90 // private long LastThrottle;
103 // private long ThrottleInterval; 91 // private long ThrottleInterval;
104 private Timer throttleTimer; 92 private Timer throttleTimer;
@@ -212,28 +200,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
212 switch (item.throttleType & ThrottleOutPacketType.TypeMask) 200 switch (item.throttleType & ThrottleOutPacketType.TypeMask)
213 { 201 {
214 case ThrottleOutPacketType.Resend: 202 case ThrottleOutPacketType.Resend:
215 ThrottleCheck(ref ResendThrottle, ref ResendOutgoingPacketQueue, item); 203 ThrottleCheck(ref ResendThrottle, ref ResendOutgoingPacketQueue, item, ThrottleOutPacketType.Resend);
216 break; 204 break;
217 case ThrottleOutPacketType.Texture: 205 case ThrottleOutPacketType.Texture:
218 ThrottleCheck(ref TextureThrottle, ref TextureOutgoingPacketQueue, item); 206 ThrottleCheck(ref TextureThrottle, ref TextureOutgoingPacketQueue, item, ThrottleOutPacketType.Texture);
219 break; 207 break;
220 case ThrottleOutPacketType.Task: 208 case ThrottleOutPacketType.Task:
221 if ((item.throttleType & ThrottleOutPacketType.LowPriority) != 0) 209 if ((item.throttleType & ThrottleOutPacketType.LowPriority) != 0)
222 ThrottleCheck(ref TaskThrottle, ref TaskLowpriorityPacketQueue, item); 210 ThrottleCheck(ref TaskThrottle, ref TaskLowpriorityPacketQueue, item, ThrottleOutPacketType.Task);
223 else 211 else
224 ThrottleCheck(ref TaskThrottle, ref TaskOutgoingPacketQueue, item); 212 ThrottleCheck(ref TaskThrottle, ref TaskOutgoingPacketQueue, item, ThrottleOutPacketType.Task);
225 break; 213 break;
226 case ThrottleOutPacketType.Land: 214 case ThrottleOutPacketType.Land:
227 ThrottleCheck(ref LandThrottle, ref LandOutgoingPacketQueue, item); 215 ThrottleCheck(ref LandThrottle, ref LandOutgoingPacketQueue, item, ThrottleOutPacketType.Land);
228 break; 216 break;
229 case ThrottleOutPacketType.Asset: 217 case ThrottleOutPacketType.Asset:
230 ThrottleCheck(ref AssetThrottle, ref AssetOutgoingPacketQueue, item); 218 ThrottleCheck(ref AssetThrottle, ref AssetOutgoingPacketQueue, item, ThrottleOutPacketType.Asset);
231 break; 219 break;
232 case ThrottleOutPacketType.Cloud: 220 case ThrottleOutPacketType.Cloud:
233 ThrottleCheck(ref CloudThrottle, ref CloudOutgoingPacketQueue, item); 221 ThrottleCheck(ref CloudThrottle, ref CloudOutgoingPacketQueue, item, ThrottleOutPacketType.Cloud);
234 break; 222 break;
235 case ThrottleOutPacketType.Wind: 223 case ThrottleOutPacketType.Wind:
236 ThrottleCheck(ref WindThrottle, ref WindOutgoingPacketQueue, item); 224 ThrottleCheck(ref WindThrottle, ref WindOutgoingPacketQueue, item, ThrottleOutPacketType.Wind);
237 break; 225 break;
238 226
239 default: 227 default:
@@ -408,6 +396,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
408 396
409 int MaxThrottleLoops = 4550; // 50*7 packets can be dequeued at once. 397 int MaxThrottleLoops = 4550; // 50*7 packets can be dequeued at once.
410 int throttleLoops = 0; 398 int throttleLoops = 0;
399 List<ThrottleOutPacketType> e;
411 400
412 // We're going to dequeue all of the saved up packets until 401 // We're going to dequeue all of the saved up packets until
413 // we've hit the throttle limit or there's no more packets to send 402 // we've hit the throttle limit or there's no more packets to send
@@ -420,8 +409,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
420 409
421 ResetCounters(); 410 ResetCounters();
422 411
423 List<ThrottleOutPacketType> Empty = new List<ThrottleOutPacketType>();
424 // m_log.Info("[THROTTLE]: Entering Throttle");
425 while (TotalThrottle.UnderLimit() && qchanged && throttleLoops <= MaxThrottleLoops) 412 while (TotalThrottle.UnderLimit() && qchanged && throttleLoops <= MaxThrottleLoops)
426 { 413 {
427 qchanged = false; // We will break out of the loop if no work was accomplished 414 qchanged = false; // We will break out of the loop if no work was accomplished
@@ -448,7 +435,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
448 LandThrottle.AddBytes(qpack.Length); 435 LandThrottle.AddBytes(qpack.Length);
449 qchanged = true; 436 qchanged = true;
450 437
451 if (LandOutgoingPacketQueue.Count == 0) 438 if (LandOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Land))
452 Empty.Add(ThrottleOutPacketType.Land); 439 Empty.Add(ThrottleOutPacketType.Land);
453 } 440 }
454 441
@@ -461,7 +448,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
461 WindThrottle.AddBytes(qpack.Length); 448 WindThrottle.AddBytes(qpack.Length);
462 qchanged = true; 449 qchanged = true;
463 450
464 if (WindOutgoingPacketQueue.Count == 0) 451 if (WindOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Wind))
465 Empty.Add(ThrottleOutPacketType.Wind); 452 Empty.Add(ThrottleOutPacketType.Wind);
466 } 453 }
467 454
@@ -474,7 +461,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
474 CloudThrottle.AddBytes(qpack.Length); 461 CloudThrottle.AddBytes(qpack.Length);
475 qchanged = true; 462 qchanged = true;
476 463
477 if (CloudOutgoingPacketQueue.Count == 0) 464 if (CloudOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Cloud))
478 Empty.Add(ThrottleOutPacketType.Cloud); 465 Empty.Add(ThrottleOutPacketType.Cloud);
479 } 466 }
480 467
@@ -496,7 +483,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
496 TaskThrottle.AddBytes(qpack.Length); 483 TaskThrottle.AddBytes(qpack.Length);
497 qchanged = true; 484 qchanged = true;
498 485
499 if (TaskOutgoingPacketQueue.Count == 0 && TaskLowpriorityPacketQueue.Count == 0) 486 if (TaskOutgoingPacketQueue.Count == 0 && TaskLowpriorityPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Task))
500 Empty.Add(ThrottleOutPacketType.Task); 487 Empty.Add(ThrottleOutPacketType.Task);
501 } 488 }
502 489
@@ -509,7 +496,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
509 TextureThrottle.AddBytes(qpack.Length); 496 TextureThrottle.AddBytes(qpack.Length);
510 qchanged = true; 497 qchanged = true;
511 498
512 if (TextureOutgoingPacketQueue.Count == 0) 499 if (TextureOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Texture))
513 Empty.Add(ThrottleOutPacketType.Texture); 500 Empty.Add(ThrottleOutPacketType.Texture);
514 } 501 }
515 502
@@ -522,16 +509,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
522 AssetThrottle.AddBytes(qpack.Length); 509 AssetThrottle.AddBytes(qpack.Length);
523 qchanged = true; 510 qchanged = true;
524 511
525 if (AssetOutgoingPacketQueue.Count == 0) 512 if (AssetOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Asset))
526 Empty.Add(ThrottleOutPacketType.Asset); 513 Empty.Add(ThrottleOutPacketType.Asset);
527 } 514 }
528 } 515 }
529 // m_log.Info("[THROTTLE]: Processed " + throttleLoops + " packets"); 516 // m_log.Info("[THROTTLE]: Processed " + throttleLoops + " packets");
530 517
531 foreach (ThrottleOutPacketType t in Empty) 518 e = new List<ThrottleOutPacketType>(Empty);
532 { 519 Empty.Clear();
520 }
521
522 foreach (ThrottleOutPacketType t in e)
523 {
524 if (GetQueueCount(t) == 0)
533 TriggerOnQueueEmpty(t); 525 TriggerOnQueueEmpty(t);
534 }
535 } 526 }
536 } 527 }
537 528
@@ -552,7 +543,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
552 ProcessThrottle(); 543 ProcessThrottle();
553 } 544 }
554 545
555 private void ThrottleCheck(ref LLPacketThrottle throttle, ref Queue<LLQueItem> q, LLQueItem item) 546 private void ThrottleCheck(ref LLPacketThrottle throttle, ref Queue<LLQueItem> q, LLQueItem item, ThrottleOutPacketType itemType)
556 { 547 {
557 // The idea.. is if the packet throttle queues are empty 548 // The idea.. is if the packet throttle queues are empty
558 // and the client is under throttle for the type. Queue 549 // and the client is under throttle for the type. Queue
@@ -568,6 +559,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
568 throttle.AddBytes(item.Length); 559 throttle.AddBytes(item.Length);
569 TotalThrottle.AddBytes(item.Length); 560 TotalThrottle.AddBytes(item.Length);
570 SendQueue.Enqueue(item); 561 SendQueue.Enqueue(item);
562 lock (this)
563 {
564 if (!Empty.Contains(itemType))
565 Empty.Add(itemType);
566 }
571 } 567 }
572 catch (Exception e) 568 catch (Exception e)
573 { 569 {