aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2012-06-08 03:53:03 +0100
committerJustin Clark-Casey (justincc)2012-06-08 03:53:03 +0100
commitc215b1ad169cb8c3add70622f610e980ee9cfa31 (patch)
treea13e258b6635aa2c63a8e2b0604142bf939a3612
parentAdd regression test for client logout due to ack timeout. (diff)
downloadopensim-SC-c215b1ad169cb8c3add70622f610e980ee9cfa31.zip
opensim-SC-c215b1ad169cb8c3add70622f610e980ee9cfa31.tar.gz
opensim-SC-c215b1ad169cb8c3add70622f610e980ee9cfa31.tar.bz2
opensim-SC-c215b1ad169cb8c3add70622f610e980ee9cfa31.tar.xz
If logging a client out due to ack timeout, do this asynchronously rather than synchronously on the outgoing packet loop.
This is the same async behaviour as normal logouts. This is necessary because the event queue will sleep the thread for 5 seconds on an ack timeout logout as the client isn't around to pick up the final event queue messages.
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs26
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs4
-rw-r--r--OpenSim/Tools/pCampBot/Bot.cs3
3 files changed, 23 insertions, 10 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 58a3b1c..e1fccb5 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
539 SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false, null); 539 SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false, null);
540 } 540 }
541 541
542 public void HandleUnacked(LLUDPClient udpClient) 542 public void HandleUnacked(LLClientView client)
543 { 543 {
544 LLUDPClient udpClient = client.UDPClient;
545
544 if (!udpClient.IsConnected) 546 if (!udpClient.IsConnected)
545 return; 547 return;
546 548
@@ -553,12 +555,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
553 if (udpClient.IsPaused) 555 if (udpClient.IsPaused)
554 timeoutTicks = m_pausedAckTimeout; 556 timeoutTicks = m_pausedAckTimeout;
555 557
556 if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks) 558 if (!client.IsLoggingOut &&
559 (Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks)
557 { 560 {
558 m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID); 561 m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID);
559 StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); 562 StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
560
561 RemoveClient(udpClient); 563 RemoveClient(udpClient);
564
562 return; 565 return;
563 } 566 }
564 567
@@ -1113,8 +1116,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1113 IClientAPI client; 1116 IClientAPI client;
1114 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 1117 if (m_scene.TryGetClient(udpClient.AgentID, out client))
1115 { 1118 {
1119 // We must set IsLoggingOut synchronously so that we can stop the packet loop reinvoking this method.
1116 client.IsLoggingOut = true; 1120 client.IsLoggingOut = true;
1117 client.Close(); 1121
1122 // Fire this out on a different thread so that we don't hold up outgoing packet processing for
1123 // everybody else if this is being called due to an ack timeout.
1124 // This is the same as processing as the async process of a logout request.
1125 Util.FireAndForget(o => client.Close());
1118 } 1126 }
1119 else 1127 else
1120 { 1128 {
@@ -1254,12 +1262,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1254 { 1262 {
1255 if (client is LLClientView) 1263 if (client is LLClientView)
1256 { 1264 {
1257 LLUDPClient udpClient = ((LLClientView)client).UDPClient; 1265 LLClientView llClient = (LLClientView)client;
1266 LLUDPClient udpClient = llClient.UDPClient;
1258 1267
1259 if (udpClient.IsConnected) 1268 if (udpClient.IsConnected)
1260 { 1269 {
1261 if (m_resendUnacked) 1270 if (m_resendUnacked)
1262 HandleUnacked(udpClient); 1271 HandleUnacked(llClient);
1263 1272
1264 if (m_sendAcks) 1273 if (m_sendAcks)
1265 SendAcks(udpClient); 1274 SendAcks(udpClient);
@@ -1308,7 +1317,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1308 { 1317 {
1309 if (client is LLClientView) 1318 if (client is LLClientView)
1310 { 1319 {
1311 LLUDPClient udpClient = ((LLClientView)client).UDPClient; 1320 LLClientView llClient = (LLClientView)client;
1321 LLUDPClient udpClient = llClient.UDPClient;
1312 1322
1313 if (udpClient.IsConnected) 1323 if (udpClient.IsConnected)
1314 { 1324 {
@@ -1317,7 +1327,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1317 nticksUnack++; 1327 nticksUnack++;
1318 watch2.Start(); 1328 watch2.Start();
1319 1329
1320 HandleUnacked(udpClient); 1330 HandleUnacked(llClient);
1321 1331
1322 watch2.Stop(); 1332 watch2.Stop();
1323 avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack); 1333 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 45d0e2a..109a8e1 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
197 public void TestLogoutClientDueToAck() 197 public void TestLogoutClientDueToAck()
198 { 198 {
199 TestHelpers.InMethod(); 199 TestHelpers.InMethod();
200 TestHelpers.EnableLogging(); 200// TestHelpers.EnableLogging();
201 201
202 IniConfigSource ics = new IniConfigSource(); 202 IniConfigSource ics = new IniConfigSource();
203 IConfig config = ics.AddConfig("ClientStack.LindenUDP"); 203 IConfig config = ics.AddConfig("ClientStack.LindenUDP");
@@ -210,7 +210,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
210 ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID); 210 ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID);
211 Assert.That(spAfterAckTimeout, Is.Null); 211 Assert.That(spAfterAckTimeout, Is.Null);
212 212
213 TestHelpers.DisableLogging(); 213// TestHelpers.DisableLogging();
214 } 214 }
215 215
216// /// <summary> 216// /// <summary>
diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs
index b6cd287..daaa3c0 100644
--- a/OpenSim/Tools/pCampBot/Bot.cs
+++ b/OpenSim/Tools/pCampBot/Bot.cs
@@ -480,6 +480,9 @@ namespace pCampBot
480 480
481 public void Objects_NewPrim(object sender, PrimEventArgs args) 481 public void Objects_NewPrim(object sender, PrimEventArgs args)
482 { 482 {
483// if (Name.EndsWith("4"))
484// throw new Exception("Aaargh");
485
483 Primitive prim = args.Prim; 486 Primitive prim = args.Prim;
484 487
485 if (prim != null) 488 if (prim != null)