diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 58a3b1c6c8..e1fccb58a6 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -539,8 +539,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false, null); } - public void HandleUnacked(LLUDPClient udpClient) + public void HandleUnacked(LLClientView client) { + LLUDPClient udpClient = client.UDPClient; + if (!udpClient.IsConnected) return; @@ -553,12 +555,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (udpClient.IsPaused) timeoutTicks = m_pausedAckTimeout; - if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks) + if (!client.IsLoggingOut && + (Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks) { m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID); StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); - RemoveClient(udpClient); + return; } @@ -1113,8 +1116,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP IClientAPI client; if (m_scene.TryGetClient(udpClient.AgentID, out client)) { + // We must set IsLoggingOut synchronously so that we can stop the packet loop reinvoking this method. client.IsLoggingOut = true; - client.Close(); + + // Fire this out on a different thread so that we don't hold up outgoing packet processing for + // everybody else if this is being called due to an ack timeout. + // This is the same as processing as the async process of a logout request. + Util.FireAndForget(o => client.Close()); } else { @@ -1254,12 +1262,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (client is LLClientView) { - LLUDPClient udpClient = ((LLClientView)client).UDPClient; + LLClientView llClient = (LLClientView)client; + LLUDPClient udpClient = llClient.UDPClient; if (udpClient.IsConnected) { if (m_resendUnacked) - HandleUnacked(udpClient); + HandleUnacked(llClient); if (m_sendAcks) SendAcks(udpClient); @@ -1308,7 +1317,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (client is LLClientView) { - LLUDPClient udpClient = ((LLClientView)client).UDPClient; + LLClientView llClient = (LLClientView)client; + LLUDPClient udpClient = llClient.UDPClient; if (udpClient.IsConnected) { @@ -1317,7 +1327,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP nticksUnack++; watch2.Start(); - HandleUnacked(udpClient); + HandleUnacked(llClient); watch2.Stop(); avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack); diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs index 45d0e2ab32..109a8e1914 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs @@ -197,7 +197,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests public void TestLogoutClientDueToAck() { TestHelpers.InMethod(); - TestHelpers.EnableLogging(); +// TestHelpers.EnableLogging(); IniConfigSource ics = new IniConfigSource(); IConfig config = ics.AddConfig("ClientStack.LindenUDP"); @@ -210,7 +210,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID); Assert.That(spAfterAckTimeout, Is.Null); - TestHelpers.DisableLogging(); +// TestHelpers.DisableLogging(); } // /// diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index b6cd287202..daaa3c0070 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs @@ -480,6 +480,9 @@ namespace pCampBot public void Objects_NewPrim(object sender, PrimEventArgs args) { +// if (Name.EndsWith("4")) +// throw new Exception("Aaargh"); + Primitive prim = args.Prim; if (prim != null)