Merge branch 'master' into careminster

Conflicts:
	OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
	OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
avinationmerge
Melanie 2012-06-12 03:09:52 +01:00
commit dfafb5ca14
10 changed files with 97 additions and 98 deletions

View File

@ -749,14 +749,21 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
string Name { get; } string Name { get; }
/// <value> /// <summary>
/// Determines whether the client thread is doing anything or not. /// True if the client is active (sending and receiving new UDP messages). False if the client is being closed.
/// </value> /// </summary>
bool IsActive { get; set; } bool IsActive { get; set; }
/// <value> /// <summary>
/// Determines whether the client is or has been removed from a given scene /// Set if the client is closing due to a logout request
/// </value> /// </summary>
/// <remarks>
/// Do not use this flag if you want to know if the client is closing, since it will not be set in other
/// circumstances (e.g. if a child agent is closed or the agent is kicked off the simulator). Use IsActive
/// instead with a IClientAPI.SceneAgent.IsChildAgent check if necessary.
///
/// Only set for root agents.
/// </remarks>
bool IsLoggingOut { get; set; } bool IsLoggingOut { get; set; }
bool SendLogoutPacketWhenClosing { set; } bool SendLogoutPacketWhenClosing { set; }

View File

@ -26,6 +26,7 @@
*/ */
using System; using System;
using OpenMetaverse;
namespace OpenSim.Framework namespace OpenSim.Framework
{ {
@ -71,5 +72,11 @@ namespace OpenSim.Framework
/// This includes scene object data and the appearance data of other avatars. /// This includes scene object data and the appearance data of other avatars.
/// </remarks> /// </remarks>
void SendInitialDataToMe(); void SendInitialDataToMe();
/// <summary>
/// Direction in which the scene presence is looking.
/// </summary>
/// <remarks>Will be Vector3.Zero for a child agent.</remarks>
Vector3 Lookat { get; }
} }
} }

View File

@ -515,6 +515,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// </summary> /// </summary>
public void Close(bool sendStop) public void Close(bool sendStop)
{ {
IsActive = false;
m_log.DebugFormat( m_log.DebugFormat(
"[CLIENT]: Close has been called for {0} attached to scene {1}", "[CLIENT]: Close has been called for {0} attached to scene {1}",
Name, m_scene.RegionInfo.RegionName); Name, m_scene.RegionInfo.RegionName);

View File

@ -555,12 +555,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (udpClient.IsPaused) if (udpClient.IsPaused)
timeoutTicks = m_pausedAckTimeout; timeoutTicks = m_pausedAckTimeout;
if (!client.IsLoggingOut && if (client.IsActive &&
(Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks) (Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks)
{ {
m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID); // We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even
StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); // though it's set later on by LLClientView.Close()
RemoveClient(client); client.IsActive = false;
// 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 => DeactivateClientDueToTimeout(client));
return; return;
} }
@ -1110,9 +1115,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return client; return client;
} }
private void RemoveClient(IClientAPI client) /// <summary>
/// Deactivates the client if we don't receive any packets within a certain amount of time (default 60 seconds).
/// </summary>
/// <remarks>
/// If a connection is active then we will always receive packets even if nothing else is happening, due to
/// regular client pings.
/// </remarks>
/// <param name='client'></param>
private void DeactivateClientDueToTimeout(IClientAPI client)
{ {
client.IsLoggingOut = true; // We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even
// though it's set later on by LLClientView.Close()
client.IsActive = false;
m_log.WarnFormat(
"[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}",
client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName);
StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
if (!client.SceneAgent.IsChildAgent)
client.Kick("Simulator logged you out due to connection timeout");
Util.FireAndForget(o => client.Close()); Util.FireAndForget(o => client.Close());
} }
@ -1429,8 +1454,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected void LogoutHandler(IClientAPI client) protected void LogoutHandler(IClientAPI client)
{ {
client.SendLogoutPacket(); client.SendLogoutPacket();
if (!client.IsLoggingOut) if (!client.IsLoggingOut)
RemoveClient(client); {
client.IsLoggingOut = true;
client.Close();
}
} }
} }
} }

View File

@ -328,18 +328,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
void OnConnectionClosed(IClientAPI obj) void OnConnectionClosed(IClientAPI obj)
{ {
if (obj.IsLoggingOut) if (obj.SceneAgent.IsChildAgent)
{
object sp = null;
if (obj.Scene.TryGetScenePresence(obj.AgentId, out sp))
{
if (((ScenePresence)sp).IsChildAgent)
return; return;
}
// Let's find out if this is a foreign user or a local user // Let's find out if this is a foreign user or a local user
IUserManagement uMan = Scene.RequestModuleInterface<IUserManagement>(); IUserManagement uMan = Scene.RequestModuleInterface<IUserManagement>();
// UserAccount account = Scene.UserAccountService.GetUserAccount(Scene.RegionInfo.ScopeID, obj.AgentId); // UserAccount account = Scene.UserAccountService.GetUserAccount(Scene.RegionInfo.ScopeID, obj.AgentId);
if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) if (uMan != null && uMan.IsLocalGridUser(obj.AgentId))
{ {
// local grid user // local grid user
@ -356,6 +351,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
//m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Sent logout call to UserAgentService @ {0}", url); //m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Sent logout call to UserAgentService @ {0}", url);
} }
else else
{
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: HomeURI not found for agent {0} logout", obj.AgentId); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: HomeURI not found for agent {0} logout", obj.AgentId);
} }
} }

View File

@ -79,29 +79,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
public void OnConnectionClose(IClientAPI client) public void OnConnectionClose(IClientAPI client)
{ {
if (client.IsLoggingOut) if (client.SceneAgent.IsChildAgent)
{
object sp = null;
Vector3 position = new Vector3(128, 128, 0);
Vector3 lookat = new Vector3(0, 1, 0);
if (client.Scene.TryGetScenePresence(client.AgentId, out sp))
{
if (sp is ScenePresence)
{
if (((ScenePresence)sp).IsChildAgent)
return; return;
position = ((ScenePresence)sp).AbsolutePosition;
lookat = ((ScenePresence)sp).Lookat;
}
}
// m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); // m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName);
m_GridUserService.LoggedOut(client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID, position, lookat); m_GridUserService.LoggedOut(
client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID,
client.SceneAgent.AbsolutePosition, client.SceneAgent.Lookat);
} }
}
} }
} }

View File

@ -64,7 +64,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
scene.EventManager.OnNewClient -= OnNewClient; scene.EventManager.OnNewClient -= OnNewClient;
m_PresenceService.LogoutRegionAgents(scene.RegionInfo.RegionID); m_PresenceService.LogoutRegionAgents(scene.RegionInfo.RegionID);
} }
public void OnMakeRootAgent(ScenePresence sp) public void OnMakeRootAgent(ScenePresence sp)
@ -80,18 +79,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
public void OnConnectionClose(IClientAPI client) public void OnConnectionClose(IClientAPI client)
{ {
if (client.IsLoggingOut) if (!client.SceneAgent.IsChildAgent)
{ {
object sp = null;
if (client.Scene.TryGetScenePresence(client.AgentId, out sp))
{
if (sp is ScenePresence)
{
if (((ScenePresence)sp).IsChildAgent)
return;
}
}
// m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); // m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName);
m_PresenceService.LogoutAgent(client.SessionId); m_PresenceService.LogoutAgent(client.SessionId);
} }

View File

@ -137,7 +137,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
if (fh.Client.IsLoggingOut) if (!fh.Client.IsActive)
continue; continue;
// m_log.DebugFormat( // m_log.DebugFormat(

View File

@ -3617,10 +3617,9 @@ namespace OpenSim.Region.Framework.Scenes
// Or the same user is trying to be root twice here, won't work. // Or the same user is trying to be root twice here, won't work.
// Kill it. // Kill it.
m_log.DebugFormat( m_log.DebugFormat(
"[SCENE]: Zombie scene presence detected for {0} in {1}", "[SCENE]: Zombie scene presence detected for {0} {1} in {2}",
agent.AgentID, sp.Name, sp.UUID, RegionInfo.RegionName);
RegionInfo.RegionName
);
sp.ControllingClient.Close(); sp.ControllingClient.Close();
sp = null; sp = null;
} }

View File

@ -79,27 +79,13 @@ namespace OpenSim.Services.Connectors.SimianGrid
public void OnConnectionClose(IClientAPI client) public void OnConnectionClose(IClientAPI client)
{ {
if (client.IsLoggingOut) if (client.SceneAgent.IsChildAgent)
{
object sp = null;
Vector3 position = new Vector3(128, 128, 0);
Vector3 lookat = new Vector3(0, 1, 0);
if (client.Scene.TryGetScenePresence(client.AgentId, out sp))
{
if (sp is ScenePresence)
{
if (((ScenePresence)sp).IsChildAgent)
return; return;
position = ((ScenePresence)sp).AbsolutePosition; // m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName);
lookat = ((ScenePresence)sp).Lookat; m_GridUserService.LoggedOut(
} client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID,
} client.SceneAgent.AbsolutePosition, client.SceneAgent.Lookat);
// m_log.DebugFormat("[SIMIAN ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName);
m_GridUserService.LoggedOut(client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID, position, lookat);
}
} }
void OnEnteringNewParcel(ScenePresence sp, int localLandID, UUID regionID) void OnEnteringNewParcel(ScenePresence sp, int localLandID, UUID regionID)