aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2012-06-12 02:16:36 +0100
committerJustin Clark-Casey (justincc)2012-06-12 02:16:36 +0100
commitb099f26376a7d671eeb9113dd7611cfcb0e57de0 (patch)
tree85e4f2bfb41e2f8b811a0acf6ba7d849e24918c7 /OpenSim/Region/ClientStack
parentIf the simulator closes a root agent due to ack timeout, then send the client... (diff)
downloadopensim-SC_OLD-b099f26376a7d671eeb9113dd7611cfcb0e57de0.zip
opensim-SC_OLD-b099f26376a7d671eeb9113dd7611cfcb0e57de0.tar.gz
opensim-SC_OLD-b099f26376a7d671eeb9113dd7611cfcb0e57de0.tar.bz2
opensim-SC_OLD-b099f26376a7d671eeb9113dd7611cfcb0e57de0.tar.xz
Set IClientAPI.IsActive = false early on client removal due to ack timeout rather than using IsLoggingOut flag.
IsActive is more appropriate since unack timeout is not due to voluntary logout. This is in line with operations such as manual kick that do not set the IsLoggingOut flag. It's also slightly better race-wise since it reduces the chance of this operation clashing with another reason for client deactivation (e.g. manual kick).
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs64
1 files changed, 35 insertions, 29 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 2036f61..37d2943 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -555,15 +555,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
555 if (udpClient.IsPaused) 555 if (udpClient.IsPaused)
556 timeoutTicks = m_pausedAckTimeout; 556 timeoutTicks = m_pausedAckTimeout;
557 557
558 if (!client.IsLoggingOut && 558 if (client.IsActive &&
559 (Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks) 559 (Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks)
560 { 560 {
561 m_log.WarnFormat( 561 // We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even
562 "[LLUDPSERVER]: Ack timeout for {0} {1}, disconnecting", 562 // though it's set later on by LLClientView.Close()
563 client.Name, client.AgentId); 563 client.IsActive = false;
564 564
565 StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); 565 // Fire this out on a different thread so that we don't hold up outgoing packet processing for
566 LogoutClientDueToTimeout(client); 566 // everybody else if this is being called due to an ack timeout.
567 // This is the same as processing as the async process of a logout request.
568 Util.FireAndForget(o => DeactivateClientDueToTimeout(client));
567 569
568 return; 570 return;
569 } 571 }
@@ -792,7 +794,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
792 Interlocked.Increment(ref udpClient.PacketsReceived); 794 Interlocked.Increment(ref udpClient.PacketsReceived);
793 795
794 int now = Environment.TickCount & Int32.MaxValue; 796 int now = Environment.TickCount & Int32.MaxValue;
795 udpClient.TickLastPacketReceived = now; 797// udpClient.TickLastPacketReceived = now;
796 798
797 #region ACK Receiving 799 #region ACK Receiving
798 800
@@ -1113,30 +1115,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1113 return client; 1115 return client;
1114 } 1116 }
1115 1117
1116 private void RemoveClient(IClientAPI client) 1118 /// <summary>
1119 /// Deactivates the client if we don't receive any packets within a certain amount of time (default 60 seconds).
1120 /// </summary>
1121 /// <remarks>
1122 /// If a connection is active then we will always receive packets even if nothing else is happening, due to
1123 /// regular client pings.
1124 /// </remarks>
1125 /// <param name='client'></param>
1126 private void DeactivateClientDueToTimeout(IClientAPI client)
1117 { 1127 {
1118 // We must set IsLoggingOut synchronously so that we can stop the packet loop reinvoking this method. 1128 // We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even
1119 client.IsLoggingOut = true; 1129 // though it's set later on by LLClientView.Close()
1130 client.IsActive = false;
1120 1131
1121 // Fire this out on a different thread so that we don't hold up outgoing packet processing for 1132 m_log.WarnFormat(
1122 // everybody else if this is being called due to an ack timeout. 1133 "[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}",
1123 // This is the same as processing as the async process of a logout request. 1134 client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName);
1124 Util.FireAndForget(o => client.Close());
1125 }
1126 1135
1127 private void LogoutClientDueToTimeout(IClientAPI client) 1136 StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
1128 { 1137
1129 // We must set IsLoggingOut synchronously so that we can stop the packet loop reinvoking this method. 1138 if (!client.SceneAgent.IsChildAgent)
1130 client.IsLoggingOut = true; 1139 client.Kick("Simulator logged you out due to connection timeout");
1131 1140
1132 // Fire this out on a different thread so that we don't hold up outgoing packet processing for 1141 client.Close();
1133 // everybody else if this is being called due to an ack timeout.
1134 // This is the same as processing as the async process of a logout request.
1135 Util.FireAndForget(
1136 o =>
1137 { if (!client.SceneAgent.IsChildAgent)
1138 client.Kick("Simulator logged you out due to connection timeout");
1139 client.Close(); });
1140 } 1142 }
1141 1143
1142 private void IncomingPacketHandler() 1144 private void IncomingPacketHandler()
@@ -1450,8 +1452,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1450 protected void LogoutHandler(IClientAPI client) 1452 protected void LogoutHandler(IClientAPI client)
1451 { 1453 {
1452 client.SendLogoutPacket(); 1454 client.SendLogoutPacket();
1455
1453 if (!client.IsLoggingOut) 1456 if (!client.IsLoggingOut)
1454 RemoveClient(client); 1457 {
1458 client.IsLoggingOut = true;
1459 client.Close();
1460 }
1455 } 1461 }
1456 } 1462 }
1457} \ No newline at end of file 1463} \ No newline at end of file