diff options
-rw-r--r-- | OpenSim/Framework/PacketPool.cs | 104 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 1 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs | 22 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs | 25 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLQueItem.cs | 1 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 6 | ||||
-rw-r--r-- | bin/OpenSim.ini.example | 5 |
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; | ||