aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-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;