aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorAdam Frisby2008-11-08 20:52:48 +0000
committerAdam Frisby2008-11-08 20:52:48 +0000
commitfb2a1a6b7cc65352644921bc7c7b7745ca7d2560 (patch)
tree40de926d545c113c8bb8af2c992b15506277c4d8
parent* "Fixed" a NRE with the new script engine Tedd committed (diff)
downloadopensim-SC-fb2a1a6b7cc65352644921bc7c7b7745ca7d2560.zip
opensim-SC-fb2a1a6b7cc65352644921bc7c7b7745ca7d2560.tar.gz
opensim-SC-fb2a1a6b7cc65352644921bc7c7b7745ca7d2560.tar.bz2
opensim-SC-fb2a1a6b7cc65352644921bc7c7b7745ca7d2560.tar.xz
* Fixed a major memory leak in packet processing - PacketQueue.Close is never called, causing the PacketQueue for dead clients to be preserved (including it's contents).
* This patch is highly experimental and may cause clients to not be able to connect, if this is the case, it will be rolled back in approximately 5 minutes.
-rw-r--r--OpenSim/Framework/BlockingQueue.cs9
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs61
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs21
3 files changed, 64 insertions, 27 deletions
diff --git a/OpenSim/Framework/BlockingQueue.cs b/OpenSim/Framework/BlockingQueue.cs
index 6fbf88f..0329e0f 100644
--- a/OpenSim/Framework/BlockingQueue.cs
+++ b/OpenSim/Framework/BlockingQueue.cs
@@ -111,5 +111,14 @@ namespace OpenSim.Framework
111 return m_queue.ToArray(); 111 return m_queue.ToArray();
112 } 112 }
113 } 113 }
114
115 public void Clear()
116 {
117 lock(m_queueSync)
118 {
119 m_pqueue.Clear();
120 m_queue.Clear();
121 }
122 }
114 } 123 }
115} 124}
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs
index cce3399..7a66925 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs
@@ -98,8 +98,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
98 98
99 // A list of the packets we haven't acked yet 99 // A list of the packets we haven't acked yet
100 // 100 //
101 private Dictionary<uint,uint> m_PendingAcks = new Dictionary<uint,uint>(); 101 private Dictionary<uint, uint> m_PendingAcks = new Dictionary<uint, uint>();
102 102
103 // Dictionary of the packets that need acks from the client. 103 // Dictionary of the packets that need acks from the client.
104 // 104 //
105 private class AckData 105 private class AckData
@@ -117,7 +117,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
117 public int TickCount; 117 public int TickCount;
118 public int Resends; 118 public int Resends;
119 } 119 }
120 120
121 private Dictionary<uint, AckData> m_NeedAck = 121 private Dictionary<uint, AckData> m_NeedAck =
122 new Dictionary<uint, AckData>(); 122 new Dictionary<uint, AckData>();
123 123
@@ -234,6 +234,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
234 m_AckTimer.Stop(); 234 m_AckTimer.Stop();
235 235
236 m_PacketQueue.Enqueue(null); 236 m_PacketQueue.Enqueue(null);
237 m_PacketQueue.Close();
237 } 238 }
238 239
239 // Send one packet. This actually doesn't send anything, it queues 240 // Send one packet. This actually doesn't send anything, it queues
@@ -362,7 +363,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
362 if ((now - data.TickCount) > m_ResendTimeout) 363 if ((now - data.TickCount) > m_ResendTimeout)
363 { 364 {
364 m_NeedAck[packet.Header.Sequence].Resends++; 365 m_NeedAck[packet.Header.Sequence].Resends++;
365 366
366 // The client needs to be told that a packet is being resent, otherwise it appears to believe 367 // The client needs to be told that a packet is being resent, otherwise it appears to believe
367 // that it should reset its sequence to that packet number. 368 // that it should reset its sequence to that packet number.
368 packet.Header.Resent = true; 369 packet.Header.Resent = true;
@@ -767,33 +768,41 @@ namespace OpenSim.Region.ClientStack.LindenUDP
767 768
768 // If we sent a killpacket 769 // If we sent a killpacket
769 if (packet is KillPacket) 770 if (packet is KillPacket)
770 Thread.CurrentThread.Abort(); 771 {
772 Abort();
771 773
772 // Actually make the byte array and send it 774 // Actually make the byte array and send it
773 byte[] sendbuffer = packet.ToBytes(); 775 byte[] sendbuffer = packet.ToBytes();
774 776
775 //m_log.DebugFormat( 777 //m_log.DebugFormat(
776 // "[CLIENT]: In {0} sending packet {1}", 778 // "[CLIENT]: In {0} sending packet {1}",
777 // m_Client.Scene.RegionInfo.ExternalEndPoint.Port, packet.Header.Sequence); 779 // m_Client.Scene.RegionInfo.ExternalEndPoint.Port, packet.Header.Sequence);
778 780
779 if (packet.Header.Zerocoded) 781 if (packet.Header.Zerocoded)
780 { 782 {
781 int packetsize = Helpers.ZeroEncode(sendbuffer, 783 int packetsize = Helpers.ZeroEncode(sendbuffer,
782 sendbuffer.Length, m_ZeroOutBuffer); 784 sendbuffer.Length, m_ZeroOutBuffer);
783 m_PacketServer.SendPacketTo(m_ZeroOutBuffer, packetsize, 785 m_PacketServer.SendPacketTo(m_ZeroOutBuffer, packetsize,
784 SocketFlags.None, m_Client.CircuitCode); 786 SocketFlags.None, m_Client.CircuitCode);
785 } 787 }
786 else 788 else
787 { 789 {
788 // Need some extra space in case we need to add proxy 790 // Need some extra space in case we need to add proxy
789 // information to the message later 791 // information to the message later
790 Buffer.BlockCopy(sendbuffer, 0, m_ZeroOutBuffer, 0, 792 Buffer.BlockCopy(sendbuffer, 0, m_ZeroOutBuffer, 0,
791 sendbuffer.Length); 793 sendbuffer.Length);
792 m_PacketServer.SendPacketTo(m_ZeroOutBuffer, 794 m_PacketServer.SendPacketTo(m_ZeroOutBuffer,
793 sendbuffer.Length, SocketFlags.None, m_Client.CircuitCode); 795 sendbuffer.Length, SocketFlags.None, m_Client.CircuitCode);
796 }
797
798 PacketPool.Instance.ReturnPacket(packet);
794 } 799 }
800 }
795 801
796 PacketPool.Instance.ReturnPacket(packet); 802 private void Abort()
803 {
804 m_PacketQueue.Close();
805 Thread.CurrentThread.Abort();
797 } 806 }
798 } 807 }
799} 808}
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs
index 9aa27ec..bb2d270 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs
@@ -131,7 +131,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
131 userSettings.ClientThrottleMultipler); 131 userSettings.ClientThrottleMultipler);
132 132
133 throttleTimer = new Timer((int) (throttletimems/throttleTimeDivisor)); 133 throttleTimer = new Timer((int) (throttletimems/throttleTimeDivisor));
134 throttleTimer.Elapsed += new ElapsedEventHandler(ThrottleTimerElapsed); 134 throttleTimer.Elapsed += ThrottleTimerElapsed;
135 throttleTimer.Start(); 135 throttleTimer.Start();
136 136
137 // TIMERS needed for this 137 // TIMERS needed for this
@@ -256,9 +256,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
256 } 256 }
257 } 257 }
258 258
259 public void WipeClean()
260 {
261 m_log.Info("[PACKETQUEUE] Wiping Packet Queues Clean");
262 lock(this)
263 {
264 ResendOutgoingPacketQueue.Clear();
265 LandOutgoingPacketQueue.Clear();
266 WindOutgoingPacketQueue.Clear();
267 CloudOutgoingPacketQueue.Clear();
268 TaskOutgoingPacketQueue.Clear();
269 TaskLowpriorityPacketQueue.Clear();
270 TextureOutgoingPacketQueue.Clear();
271 AssetOutgoingPacketQueue.Clear();
272 SendQueue.Clear();
273 }
274 }
275
259 public void Close() 276 public void Close()
260 { 277 {
278 m_log.Info("[PACKETQUEUE] Close called");
261 Flush(); 279 Flush();
280 WipeClean(); // I'm sure there's a dirty joke in here somewhere. -AFrisby
262 281
263 m_enabled = false; 282 m_enabled = false;
264 throttleTimer.Stop(); 283 throttleTimer.Stop();