aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorMelanie Thielker2009-05-02 13:16:41 +0000
committerMelanie Thielker2009-05-02 13:16:41 +0000
commit62bcf0e69405ee1443f66eecd1f3fbd684f0c2a5 (patch)
tree24a887f787545c95fcc721cf41ac8c9b17d1ef85
parentAlso add these packet to the list of packets to be recycled. No enabled (diff)
downloadopensim-SC-62bcf0e69405ee1443f66eecd1f3fbd684f0c2a5.zip
opensim-SC-62bcf0e69405ee1443f66eecd1f3fbd684f0c2a5.tar.gz
opensim-SC-62bcf0e69405ee1443f66eecd1f3fbd684f0c2a5.tar.bz2
opensim-SC-62bcf0e69405ee1443f66eecd1f3fbd684f0c2a5.tar.xz
Numerous packet improvements.
Don't allow packets to be resent before they have actually been sent for the first time. Switch from serializing a packet to get it's length to the LibOMV provided Length property. Fix resend timing. Fix the use of dangling references to Acked packets. Fix the packet handler to play nice with the packet pool. Fix the packet pool. Add data block recycling to the packet pool. Packet pool is now ENABLED by default. Add config option to disable packet and data block reuse. Add ObjectUpdate and ImprovedTerseObjectUpdate to the packets being recycled.
-rw-r--r--OpenSim/Framework/PacketPool.cs104
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs1
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs22
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs25
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLQueItem.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs6
-rw-r--r--bin/OpenSim.ini.example5
7 files changed, 111 insertions, 53 deletions
diff --git a/OpenSim/Framework/PacketPool.cs b/OpenSim/Framework/PacketPool.cs
index f17d654..37924d7 100644
--- a/OpenSim/Framework/PacketPool.cs
+++ b/OpenSim/Framework/PacketPool.cs
@@ -41,7 +41,8 @@ namespace OpenSim.Framework
41 41
42 private static readonly PacketPool instance = new PacketPool(); 42 private static readonly PacketPool instance = new PacketPool();
43 43
44 private bool packetPoolEnabled = false; 44 private bool packetPoolEnabled = true;
45 private bool dataBlockPoolEnabled = true;
45 46
46 private readonly Dictionary<PacketType, Stack<Packet>> pool = new Dictionary<PacketType, Stack<Packet>>(); 47 private readonly Dictionary<PacketType, Stack<Packet>> pool = new Dictionary<PacketType, Stack<Packet>>();
47 48
@@ -57,6 +58,18 @@ namespace OpenSim.Framework
57 get { return instance; } 58 get { return instance; }
58 } 59 }
59 60
61 public bool RecyclePackets
62 {
63 set { packetPoolEnabled = value; }
64 get { return packetPoolEnabled; }
65 }
66
67 public bool RecycleDataBlocks
68 {
69 set { dataBlockPoolEnabled = value; }
70 get { return dataBlockPoolEnabled; }
71 }
72
60 public Packet GetPacket(PacketType type) 73 public Packet GetPacket(PacketType type)
61 { 74 {
62 Packet packet; 75 Packet packet;
@@ -140,55 +153,58 @@ namespace OpenSim.Framework
140 /// <param name="packet"></param> 153 /// <param name="packet"></param>
141 public void ReturnPacket(Packet packet) 154 public void ReturnPacket(Packet packet)
142 { 155 {
143 switch (packet.Type) 156 if (dataBlockPoolEnabled)
144 { 157 {
145 case PacketType.ObjectUpdate: 158 switch (packet.Type)
146 ObjectUpdatePacket oup = (ObjectUpdatePacket)packet; 159 {
147 160 case PacketType.ObjectUpdate:
148 foreach (ObjectUpdatePacket.ObjectDataBlock oupod in 161 ObjectUpdatePacket oup = (ObjectUpdatePacket)packet;
149 oup.ObjectData) 162
150 ReturnDataBlock<ObjectUpdatePacket.ObjectDataBlock>(oupod); 163 foreach (ObjectUpdatePacket.ObjectDataBlock oupod in
151 oup.ObjectData = null; 164 oup.ObjectData)
152 break; 165 ReturnDataBlock<ObjectUpdatePacket.ObjectDataBlock>(oupod);
153 166 oup.ObjectData = null;
154 case PacketType.ImprovedTerseObjectUpdate: 167 break;
155 ImprovedTerseObjectUpdatePacket itoup = 168
156 (ImprovedTerseObjectUpdatePacket)packet; 169 case PacketType.ImprovedTerseObjectUpdate:
157 170 ImprovedTerseObjectUpdatePacket itoup =
158 foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock 171 (ImprovedTerseObjectUpdatePacket)packet;
159 itoupod in itoup.ObjectData) 172
160 ReturnDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(itoupod); 173 foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock
161 itoup.ObjectData = null; 174 itoupod in itoup.ObjectData)
162 break; 175 ReturnDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(itoupod);
176 itoup.ObjectData = null;
177 break;
178 }
163 } 179 }
164 180
165 if (!packetPoolEnabled) 181 if (packetPoolEnabled)
166 return;
167
168 switch (packet.Type)
169 { 182 {
170 // List pooling packets here 183 switch (packet.Type)
171 case PacketType.PacketAck: 184 {
172 case PacketType.ObjectUpdate: 185 // List pooling packets here
173 case PacketType.ImprovedTerseObjectUpdate: 186 case PacketType.PacketAck:
174 lock (pool) 187 case PacketType.ObjectUpdate:
175 { 188 case PacketType.ImprovedTerseObjectUpdate:
176 PacketType type = packet.Type; 189 lock (pool)
177
178 if (!pool.ContainsKey(type))
179 {
180 pool[type] = new Stack<Packet>();
181 }
182 if ((pool[type]).Count < 50)
183 { 190 {
184 (pool[type]).Push(packet); 191 PacketType type = packet.Type;
192
193 if (!pool.ContainsKey(type))
194 {
195 pool[type] = new Stack<Packet>();
196 }
197 if ((pool[type]).Count < 50)
198 {
199 (pool[type]).Push(packet);
200 }
185 } 201 }
186 } 202 break;
187 break; 203
188 204 // Other packets wont pool
189 // Other packets wont pool 205 default:
190 default: 206 return;
191 return; 207 }
192 } 208 }
193 } 209 }
194 210
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 4acc6be..4bc568c 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -936,6 +936,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
936 936
937 LLQueItem item = new LLQueItem(); 937 LLQueItem item = new LLQueItem();
938 item.Packet = packet; 938 item.Packet = packet;
939 item.Sequence = packet.Header.Sequence;
939 940
940 m_PacketHandler.ProcessOutPacket(item); 941 m_PacketHandler.ProcessOutPacket(item);
941 942
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs
index 2191ca7..6229237 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs
@@ -253,7 +253,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
253 item.TickCount = Environment.TickCount; 253 item.TickCount = Environment.TickCount;
254 item.Identifier = id; 254 item.Identifier = id;
255 item.Resends = 0; 255 item.Resends = 0;
256 item.Length = packet.ToBytes().Length; 256 item.Length = packet.Length;
257 item.Sequence = packet.Header.Sequence;
257 258
258 m_PacketQueue.Enqueue(item); 259 m_PacketQueue.Enqueue(item);
259 m_PacketsSent++; 260 m_PacketsSent++;
@@ -310,7 +311,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
310 311
311 // Packets this old get resent 312 // Packets this old get resent
312 // 313 //
313 if ((now - data.TickCount) > m_ResendTimeout) 314 if ((now - data.TickCount) > m_ResendTimeout && data.Sequence != 0)
314 { 315 {
315 if (resent < 20) 316 if (resent < 20)
316 { 317 {
@@ -325,6 +326,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
325 { 326 {
326 m_NeedAck.Remove(packet.Header.Sequence); 327 m_NeedAck.Remove(packet.Header.Sequence);
327 TriggerOnPacketDrop(packet, data.Identifier); 328 TriggerOnPacketDrop(packet, data.Identifier);
329 m_PacketQueue.Cancel(packet.Header.Sequence);
328 PacketPool.Instance.ReturnPacket(packet); 330 PacketPool.Instance.ReturnPacket(packet);
329 continue; 331 continue;
330 } 332 }
@@ -586,11 +588,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
586 return; 588 return;
587 589
588 m_NeedAck.Remove(id); 590 m_NeedAck.Remove(id);
589 // We can't return this packet, it will just have to be GC'd 591 m_PacketQueue.Cancel(data.Sequence);
590 // Reason for that is that the packet may still be in the 592 PacketPool.Instance.ReturnPacket(data.Packet);
591 // send queue, and if it gets reused things get messy!
592 //
593 // PacketPool.Instance.ReturnPacket(data.Packet);
594 m_UnackedBytes -= data.Length; 593 m_UnackedBytes -= data.Length;
595 } 594 }
596 } 595 }
@@ -680,7 +679,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
680 item.TickCount = Environment.TickCount; 679 item.TickCount = Environment.TickCount;
681 item.Identifier = 0; 680 item.Identifier = 0;
682 item.Resends = 0; 681 item.Resends = 0;
683 item.Length = packet.ToBytes().Length; 682 item.Length = packet.Length;
683 item.Sequence = packet.Header.Sequence;
684 m_NeedAck.Add(key, item); 684 m_NeedAck.Add(key, item);
685 } 685 }
686 686
@@ -719,6 +719,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
719 if (data.Identifier != null && data.Identifier == id) 719 if (data.Identifier != null && data.Identifier == id)
720 { 720 {
721 m_NeedAck.Remove(data.Packet.Header.Sequence); 721 m_NeedAck.Remove(data.Packet.Header.Sequence);
722 m_PacketQueue.Cancel(data.Sequence);
722 PacketPool.Instance.ReturnPacket(data.Packet); 723 PacketPool.Instance.ReturnPacket(data.Packet);
723 return; 724 return;
724 } 725 }
@@ -745,6 +746,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
745 if (packet.Header.Sequence == 0) 746 if (packet.Header.Sequence == 0)
746 { 747 {
747 packet.Header.Sequence = NextPacketSequenceNumber(); 748 packet.Header.Sequence = NextPacketSequenceNumber();
749 item.Sequence = packet.Header.Sequence;
750 item.TickCount = Environment.TickCount;
748 751
749 lock (m_NeedAck) 752 lock (m_NeedAck)
750 { 753 {
@@ -793,7 +796,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
793 // Dont't return in that case 796 // Dont't return in that case
794 // 797 //
795 if (!packet.Header.Reliable) 798 if (!packet.Header.Reliable)
799 {
800 m_PacketQueue.Cancel(item.Sequence);
796 PacketPool.Instance.ReturnPacket(packet); 801 PacketPool.Instance.ReturnPacket(packet);
802 }
797 } 803 }
798 804
799 private void Abort() 805 private void Abort()
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs
index ef1f34a..46d5610 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs
@@ -83,6 +83,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
83 internal LLPacketThrottle TextureThrottle; 83 internal LLPacketThrottle TextureThrottle;
84 internal LLPacketThrottle TotalThrottle; 84 internal LLPacketThrottle TotalThrottle;
85 85
86 private List<uint> contents = new List<uint>();
87
86 /// <summary> 88 /// <summary>
87 /// The number of packets in the OutgoingPacketQueue 89 /// The number of packets in the OutgoingPacketQueue
88 /// 90 ///
@@ -186,6 +188,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
186 return; 188 return;
187 } 189 }
188 190
191 if (item.Sequence != 0)
192 contents.Add(item.Sequence);
193
189 lock (this) 194 lock (this)
190 { 195 {
191 switch (item.throttleType & ThrottleOutPacketType.TypeMask) 196 switch (item.throttleType & ThrottleOutPacketType.TypeMask)
@@ -226,7 +231,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
226 231
227 public LLQueItem Dequeue() 232 public LLQueItem Dequeue()
228 { 233 {
229 return SendQueue.Dequeue(); 234 while (true)
235 {
236 LLQueItem item = SendQueue.Dequeue();
237 if (item == null)
238 return null;
239 if (item.Incoming)
240 return item;
241 if (item.Sequence == 0)
242 return item;
243 if (contents.Remove(item.Sequence))
244 return item;
245 }
246 }
247
248 public void Cancel(uint sequence)
249 {
250 while(contents.Remove(sequence))
251 ;
230 } 252 }
231 253
232 public void Flush() 254 public void Flush()
@@ -286,6 +308,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
286 TextureOutgoingPacketQueue.Clear(); 308 TextureOutgoingPacketQueue.Clear();
287 AssetOutgoingPacketQueue.Clear(); 309 AssetOutgoingPacketQueue.Clear();
288 SendQueue.Clear(); 310 SendQueue.Clear();
311 contents.Clear();
289 } 312 }
290 } 313 }
291 314
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLQueItem.cs b/OpenSim/Region/ClientStack/LindenUDP/LLQueItem.cs
index a5dcf55..3a08e9b 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLQueItem.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLQueItem.cs
@@ -44,5 +44,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
44 public Object Identifier; 44 public Object Identifier;
45 public int Resends; 45 public int Resends;
46 public int Length; 46 public int Length;
47 public uint Sequence;
47 } 48 }
48} 49}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 638187b..7872a6e 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -381,6 +381,12 @@ namespace OpenSim.Region.Framework.Scenes
381 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "DotNetEngine"); 381 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "DotNetEngine");
382 382
383 m_maxPrimsPerFrame = startupConfig.GetInt("MaxPrimsPerFrame", 200); 383 m_maxPrimsPerFrame = startupConfig.GetInt("MaxPrimsPerFrame", 200);
384 IConfig packetConfig = m_config.Configs["PacketPool"];
385 if (packetConfig != null)
386 {
387 PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true);
388 PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true);
389 }
384 } 390 }
385 catch 391 catch
386 { 392 {
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 7f7bcf4..2ae7fb7 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -1269,3 +1269,8 @@
1269 ; System.Net.WebException: The request was aborted: The request was canceled. 1269 ; System.Net.WebException: The request was aborted: The request was canceled.
1270 ; 1270 ;
1271 ; XmlRpcDisableKeepAlive = false 1271 ; XmlRpcDisableKeepAlive = false
1272
1273[PacketPool]
1274 ; Enables the experimental packet pool. Yes, we've been here before.
1275 ;RecyclePackets = true;
1276 ;RecycleDataBlocks = true;