diff options
author | Justin Clark-Casey (justincc) | 2012-06-12 02:16:36 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2012-06-12 02:16:36 +0100 |
commit | b099f26376a7d671eeb9113dd7611cfcb0e57de0 (patch) | |
tree | 85e4f2bfb41e2f8b811a0acf6ba7d849e24918c7 /OpenSim/Region/ClientStack | |
parent | If the simulator closes a root agent due to ack timeout, then send the client... (diff) | |
download | opensim-SC-b099f26376a7d671eeb9113dd7611cfcb0e57de0.zip opensim-SC-b099f26376a7d671eeb9113dd7611cfcb0e57de0.tar.gz opensim-SC-b099f26376a7d671eeb9113dd7611cfcb0e57de0.tar.bz2 opensim-SC-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.cs | 64 |
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 |