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.0.7.4.1
parent
5f4f9f0230
commit
c215b1ad16
|
@ -539,8 +539,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false, null);
|
SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleUnacked(LLUDPClient udpClient)
|
public void HandleUnacked(LLClientView client)
|
||||||
{
|
{
|
||||||
|
LLUDPClient udpClient = client.UDPClient;
|
||||||
|
|
||||||
if (!udpClient.IsConnected)
|
if (!udpClient.IsConnected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -553,12 +555,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (udpClient.IsPaused)
|
if (udpClient.IsPaused)
|
||||||
timeoutTicks = m_pausedAckTimeout;
|
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);
|
m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID);
|
||||||
StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
|
StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
|
||||||
|
|
||||||
RemoveClient(udpClient);
|
RemoveClient(udpClient);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1113,8 +1116,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
IClientAPI client;
|
IClientAPI client;
|
||||||
if (m_scene.TryGetClient(udpClient.AgentID, out 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.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
|
else
|
||||||
{
|
{
|
||||||
|
@ -1254,12 +1262,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
if (client is LLClientView)
|
if (client is LLClientView)
|
||||||
{
|
{
|
||||||
LLUDPClient udpClient = ((LLClientView)client).UDPClient;
|
LLClientView llClient = (LLClientView)client;
|
||||||
|
LLUDPClient udpClient = llClient.UDPClient;
|
||||||
|
|
||||||
if (udpClient.IsConnected)
|
if (udpClient.IsConnected)
|
||||||
{
|
{
|
||||||
if (m_resendUnacked)
|
if (m_resendUnacked)
|
||||||
HandleUnacked(udpClient);
|
HandleUnacked(llClient);
|
||||||
|
|
||||||
if (m_sendAcks)
|
if (m_sendAcks)
|
||||||
SendAcks(udpClient);
|
SendAcks(udpClient);
|
||||||
|
@ -1308,7 +1317,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
if (client is LLClientView)
|
if (client is LLClientView)
|
||||||
{
|
{
|
||||||
LLUDPClient udpClient = ((LLClientView)client).UDPClient;
|
LLClientView llClient = (LLClientView)client;
|
||||||
|
LLUDPClient udpClient = llClient.UDPClient;
|
||||||
|
|
||||||
if (udpClient.IsConnected)
|
if (udpClient.IsConnected)
|
||||||
{
|
{
|
||||||
|
@ -1317,7 +1327,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
nticksUnack++;
|
nticksUnack++;
|
||||||
watch2.Start();
|
watch2.Start();
|
||||||
|
|
||||||
HandleUnacked(udpClient);
|
HandleUnacked(llClient);
|
||||||
|
|
||||||
watch2.Stop();
|
watch2.Stop();
|
||||||
avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack);
|
avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack);
|
||||||
|
|
|
@ -197,7 +197,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
public void TestLogoutClientDueToAck()
|
public void TestLogoutClientDueToAck()
|
||||||
{
|
{
|
||||||
TestHelpers.InMethod();
|
TestHelpers.InMethod();
|
||||||
TestHelpers.EnableLogging();
|
// TestHelpers.EnableLogging();
|
||||||
|
|
||||||
IniConfigSource ics = new IniConfigSource();
|
IniConfigSource ics = new IniConfigSource();
|
||||||
IConfig config = ics.AddConfig("ClientStack.LindenUDP");
|
IConfig config = ics.AddConfig("ClientStack.LindenUDP");
|
||||||
|
@ -210,7 +210,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID);
|
ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID);
|
||||||
Assert.That(spAfterAckTimeout, Is.Null);
|
Assert.That(spAfterAckTimeout, Is.Null);
|
||||||
|
|
||||||
TestHelpers.DisableLogging();
|
// TestHelpers.DisableLogging();
|
||||||
}
|
}
|
||||||
|
|
||||||
// /// <summary>
|
// /// <summary>
|
||||||
|
|
|
@ -480,6 +480,9 @@ namespace pCampBot
|
||||||
|
|
||||||
public void Objects_NewPrim(object sender, PrimEventArgs args)
|
public void Objects_NewPrim(object sender, PrimEventArgs args)
|
||||||
{
|
{
|
||||||
|
// if (Name.EndsWith("4"))
|
||||||
|
// throw new Exception("Aaargh");
|
||||||
|
|
||||||
Primitive prim = args.Prim;
|
Primitive prim = args.Prim;
|
||||||
|
|
||||||
if (prim != null)
|
if (prim != null)
|
||||||
|
|
Loading…
Reference in New Issue