diff options
author | Justin Clark-Casey (justincc) | 2012-06-08 03:53:03 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2012-06-08 03:53:03 +0100 |
commit | c215b1ad169cb8c3add70622f610e980ee9cfa31 (patch) | |
tree | a13e258b6635aa2c63a8e2b0604142bf939a3612 /OpenSim/Region/ClientStack/Linden/UDP | |
parent | Add regression test for client logout due to ack timeout. (diff) | |
download | opensim-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.
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 26 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs | 4 |
2 files changed, 20 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> |