diff options
author | Adam Frisby | 2008-11-08 20:52:48 +0000 |
---|---|---|
committer | Adam Frisby | 2008-11-08 20:52:48 +0000 |
commit | fb2a1a6b7cc65352644921bc7c7b7745ca7d2560 (patch) | |
tree | 40de926d545c113c8bb8af2c992b15506277c4d8 | |
parent | * "Fixed" a NRE with the new script engine Tedd committed (diff) | |
download | opensim-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.cs | 9 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs | 61 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs | 21 |
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(); |