* 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.0.6.1-post-fixes
parent
cbda728183
commit
fb2a1a6b7c
|
@ -111,5 +111,14 @@ namespace OpenSim.Framework
|
||||||
return m_queue.ToArray();
|
return m_queue.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
lock(m_queueSync)
|
||||||
|
{
|
||||||
|
m_pqueue.Clear();
|
||||||
|
m_queue.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
// A list of the packets we haven't acked yet
|
// A list of the packets we haven't acked yet
|
||||||
//
|
//
|
||||||
private Dictionary<uint,uint> m_PendingAcks = new Dictionary<uint,uint>();
|
private Dictionary<uint, uint> m_PendingAcks = new Dictionary<uint, uint>();
|
||||||
|
|
||||||
// Dictionary of the packets that need acks from the client.
|
// Dictionary of the packets that need acks from the client.
|
||||||
//
|
//
|
||||||
|
@ -234,6 +234,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_AckTimer.Stop();
|
m_AckTimer.Stop();
|
||||||
|
|
||||||
m_PacketQueue.Enqueue(null);
|
m_PacketQueue.Enqueue(null);
|
||||||
|
m_PacketQueue.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send one packet. This actually doesn't send anything, it queues
|
// Send one packet. This actually doesn't send anything, it queues
|
||||||
|
@ -767,33 +768,41 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
// If we sent a killpacket
|
// If we sent a killpacket
|
||||||
if (packet is KillPacket)
|
if (packet is KillPacket)
|
||||||
Thread.CurrentThread.Abort();
|
|
||||||
|
|
||||||
// Actually make the byte array and send it
|
|
||||||
byte[] sendbuffer = packet.ToBytes();
|
|
||||||
|
|
||||||
//m_log.DebugFormat(
|
|
||||||
// "[CLIENT]: In {0} sending packet {1}",
|
|
||||||
// m_Client.Scene.RegionInfo.ExternalEndPoint.Port, packet.Header.Sequence);
|
|
||||||
|
|
||||||
if (packet.Header.Zerocoded)
|
|
||||||
{
|
{
|
||||||
int packetsize = Helpers.ZeroEncode(sendbuffer,
|
Abort();
|
||||||
sendbuffer.Length, m_ZeroOutBuffer);
|
|
||||||
m_PacketServer.SendPacketTo(m_ZeroOutBuffer, packetsize,
|
|
||||||
SocketFlags.None, m_Client.CircuitCode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Need some extra space in case we need to add proxy
|
|
||||||
// information to the message later
|
|
||||||
Buffer.BlockCopy(sendbuffer, 0, m_ZeroOutBuffer, 0,
|
|
||||||
sendbuffer.Length);
|
|
||||||
m_PacketServer.SendPacketTo(m_ZeroOutBuffer,
|
|
||||||
sendbuffer.Length, SocketFlags.None, m_Client.CircuitCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
PacketPool.Instance.ReturnPacket(packet);
|
// Actually make the byte array and send it
|
||||||
|
byte[] sendbuffer = packet.ToBytes();
|
||||||
|
|
||||||
|
//m_log.DebugFormat(
|
||||||
|
// "[CLIENT]: In {0} sending packet {1}",
|
||||||
|
// m_Client.Scene.RegionInfo.ExternalEndPoint.Port, packet.Header.Sequence);
|
||||||
|
|
||||||
|
if (packet.Header.Zerocoded)
|
||||||
|
{
|
||||||
|
int packetsize = Helpers.ZeroEncode(sendbuffer,
|
||||||
|
sendbuffer.Length, m_ZeroOutBuffer);
|
||||||
|
m_PacketServer.SendPacketTo(m_ZeroOutBuffer, packetsize,
|
||||||
|
SocketFlags.None, m_Client.CircuitCode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Need some extra space in case we need to add proxy
|
||||||
|
// information to the message later
|
||||||
|
Buffer.BlockCopy(sendbuffer, 0, m_ZeroOutBuffer, 0,
|
||||||
|
sendbuffer.Length);
|
||||||
|
m_PacketServer.SendPacketTo(m_ZeroOutBuffer,
|
||||||
|
sendbuffer.Length, SocketFlags.None, m_Client.CircuitCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketPool.Instance.ReturnPacket(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Abort()
|
||||||
|
{
|
||||||
|
m_PacketQueue.Close();
|
||||||
|
Thread.CurrentThread.Abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,7 +131,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
userSettings.ClientThrottleMultipler);
|
userSettings.ClientThrottleMultipler);
|
||||||
|
|
||||||
throttleTimer = new Timer((int) (throttletimems/throttleTimeDivisor));
|
throttleTimer = new Timer((int) (throttletimems/throttleTimeDivisor));
|
||||||
throttleTimer.Elapsed += new ElapsedEventHandler(ThrottleTimerElapsed);
|
throttleTimer.Elapsed += ThrottleTimerElapsed;
|
||||||
throttleTimer.Start();
|
throttleTimer.Start();
|
||||||
|
|
||||||
// TIMERS needed for this
|
// TIMERS needed for this
|
||||||
|
@ -256,9 +256,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void WipeClean()
|
||||||
|
{
|
||||||
|
m_log.Info("[PACKETQUEUE] Wiping Packet Queues Clean");
|
||||||
|
lock(this)
|
||||||
|
{
|
||||||
|
ResendOutgoingPacketQueue.Clear();
|
||||||
|
LandOutgoingPacketQueue.Clear();
|
||||||
|
WindOutgoingPacketQueue.Clear();
|
||||||
|
CloudOutgoingPacketQueue.Clear();
|
||||||
|
TaskOutgoingPacketQueue.Clear();
|
||||||
|
TaskLowpriorityPacketQueue.Clear();
|
||||||
|
TextureOutgoingPacketQueue.Clear();
|
||||||
|
AssetOutgoingPacketQueue.Clear();
|
||||||
|
SendQueue.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
|
m_log.Info("[PACKETQUEUE] Close called");
|
||||||
Flush();
|
Flush();
|
||||||
|
WipeClean(); // I'm sure there's a dirty joke in here somewhere. -AFrisby
|
||||||
|
|
||||||
m_enabled = false;
|
m_enabled = false;
|
||||||
throttleTimer.Stop();
|
throttleTimer.Stop();
|
||||||
|
|
Loading…
Reference in New Issue