* Increasing ScenePresences locking to prevent race conditions such as those seen in one of the crashes of mantis 1163

* It's not impossible that this could lead to deadlock where sessions simply appear to freeze, even though the region console still responds.
* If this is the case, please file a mantis
0.6.0-stable
Justin Clarke Casey 2008-05-07 22:59:30 +00:00
parent 95fbf63b3b
commit be02107ea8
3 changed files with 129 additions and 87 deletions

View File

@ -115,8 +115,12 @@ namespace OpenSim.Region.Environment.Scenes
} }
public void Close() public void Close()
{
lock (ScenePresences)
{ {
ScenePresences.Clear(); ScenePresences.Clear();
}
//SceneObjects.Clear(); //SceneObjects.Clear();
Entities.Clear(); Entities.Clear();
} }
@ -792,6 +796,8 @@ namespace OpenSim.Region.Environment.Scenes
/// <returns></returns> /// <returns></returns>
public List<ScenePresence> GetScenePresences(FilterAvatarList filter) public List<ScenePresence> GetScenePresences(FilterAvatarList filter)
{ {
// No locking of scene presences here since we're passing back a list...
List<ScenePresence> result = new List<ScenePresence>(); List<ScenePresence> result = new List<ScenePresence>();
List<ScenePresence> ScenePresencesList = GetScenePresences(); List<ScenePresence> ScenePresencesList = GetScenePresences();
@ -812,11 +818,14 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="avatarID"></param> /// <param name="avatarID"></param>
/// <returns>null if the agent was not found</returns> /// <returns>null if the agent was not found</returns>
public ScenePresence GetScenePresence(LLUUID agentID) public ScenePresence GetScenePresence(LLUUID agentID)
{
lock (ScenePresences)
{ {
if (ScenePresences.ContainsKey(agentID)) if (ScenePresences.ContainsKey(agentID))
{ {
return ScenePresences[agentID]; return ScenePresences[agentID];
} }
}
return null; return null;
} }
@ -916,6 +925,8 @@ namespace OpenSim.Region.Environment.Scenes
} }
internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
{
lock (ScenePresences)
{ {
foreach (ScenePresence presence in ScenePresences.Values) foreach (ScenePresence presence in ScenePresences.Values)
{ {
@ -930,6 +941,7 @@ namespace OpenSim.Region.Environment.Scenes
} }
} }
} }
}
avatar = null; avatar = null;
return false; return false;
@ -1007,12 +1019,15 @@ namespace OpenSim.Region.Environment.Scenes
} }
internal void ForEachClient(Action<IClientAPI> action) internal void ForEachClient(Action<IClientAPI> action)
{
lock (ScenePresences)
{ {
foreach (ScenePresence presence in ScenePresences.Values) foreach (ScenePresence presence in ScenePresences.Values)
{ {
action(presence.ControllingClient); action(presence.ControllingClient);
} }
} }
}
#endregion #endregion

View File

@ -2075,6 +2075,8 @@ namespace OpenSim.Region.Environment.Scenes
public virtual void AgentCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying) public virtual void AgentCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying)
{ {
if (regionHandle == m_regInfo.RegionHandle) if (regionHandle == m_regInfo.RegionHandle)
{
lock (m_scenePresences)
{ {
if (m_scenePresences.ContainsKey(agentID)) if (m_scenePresences.ContainsKey(agentID))
{ {
@ -2091,6 +2093,7 @@ namespace OpenSim.Region.Environment.Scenes
} }
} }
} }
}
public virtual bool IncomingChildAgentDataUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData) public virtual bool IncomingChildAgentDataUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData)
{ {
@ -2202,6 +2205,8 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="flags"></param> /// <param name="flags"></param>
public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, LLVector3 position, public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, LLVector3 position,
LLVector3 lookAt, uint flags) LLVector3 lookAt, uint flags)
{
lock (m_scenePresences)
{ {
if (m_scenePresences.ContainsKey(remoteClient.AgentId)) if (m_scenePresences.ContainsKey(remoteClient.AgentId))
{ {
@ -2209,6 +2214,7 @@ namespace OpenSim.Region.Environment.Scenes
position, lookAt, flags); position, lookAt, flags);
} }
} }
}
/// <summary> /// <summary>
/// Tries to teleport agent to landmark. /// Tries to teleport agent to landmark.
@ -2217,6 +2223,8 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="regionHandle"></param> /// <param name="regionHandle"></param>
/// <param name="position"></param> /// <param name="position"></param>
public void RequestTeleportLandmark(IClientAPI remoteClient, ulong regionHandle, LLVector3 position) public void RequestTeleportLandmark(IClientAPI remoteClient, ulong regionHandle, LLVector3 position)
{
lock (m_scenePresences)
{ {
if (m_scenePresences.ContainsKey(remoteClient.AgentId)) if (m_scenePresences.ContainsKey(remoteClient.AgentId))
{ {
@ -2224,6 +2232,7 @@ namespace OpenSim.Region.Environment.Scenes
position, LLVector3.Zero, 0); position, LLVector3.Zero, 0);
} }
} }
}
/// <summary> /// <summary>
/// Agent is crossing the border into a neighbouring region. Tell the neighbour about it! /// Agent is crossing the border into a neighbouring region. Tell the neighbour about it!
@ -2352,6 +2361,8 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="url"></param> /// <param name="url"></param>
public void SendUrlToUser(LLUUID avatarID, string objectName, LLUUID objectID, LLUUID ownerID, bool groupOwned, public void SendUrlToUser(LLUUID avatarID, string objectName, LLUUID objectID, LLUUID ownerID, bool groupOwned,
string message, string url) string message, string url)
{
lock (m_scenePresences)
{ {
if (m_scenePresences.ContainsKey(avatarID)) if (m_scenePresences.ContainsKey(avatarID))
{ {
@ -2359,12 +2370,17 @@ namespace OpenSim.Region.Environment.Scenes
message, url); message, url);
} }
} }
}
public void SendDialogToUser(LLUUID avatarID, string objectName, LLUUID objectID, LLUUID ownerID, string message, LLUUID TextureID, int ch, string[] buttonlabels) public void SendDialogToUser(LLUUID avatarID, string objectName, LLUUID objectID, LLUUID ownerID, string message, LLUUID TextureID, int ch, string[] buttonlabels)
{
lock (m_scenePresences)
{ {
if (m_scenePresences.ContainsKey(avatarID)) if (m_scenePresences.ContainsKey(avatarID))
{ {
m_scenePresences[avatarID].ControllingClient.SendDialog(objectName, objectID, ownerID, message, TextureID, ch, buttonlabels); m_scenePresences[avatarID].ControllingClient.SendDialog(
objectName, objectID, ownerID, message, TextureID, ch, buttonlabels);
}
} }
} }
@ -2477,12 +2493,15 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="message"></param> /// <param name="message"></param>
/// <param name="modal"></param> /// <param name="modal"></param>
public void SendAlertToUser(LLUUID agentID, string message, bool modal) public void SendAlertToUser(LLUUID agentID, string message, bool modal)
{
lock (m_scenePresences)
{ {
if (m_scenePresences.ContainsKey(agentID)) if (m_scenePresences.ContainsKey(agentID))
{ {
m_scenePresences[agentID].ControllingClient.SendAgentAlertMessage(message, modal); m_scenePresences[agentID].ControllingClient.SendAgentAlertMessage(message, modal);
} }
} }
}
/// <summary> /// <summary>
/// ///
@ -2494,11 +2513,13 @@ namespace OpenSim.Region.Environment.Scenes
public void handleRequestGodlikePowers(LLUUID agentID, LLUUID sessionID, LLUUID token, bool godLike, public void handleRequestGodlikePowers(LLUUID agentID, LLUUID sessionID, LLUUID token, bool godLike,
IClientAPI controllingClient) IClientAPI controllingClient)
{ {
// First check that this is the sim owner lock (m_scenePresences)
if (Permissions.GenericEstatePermission(agentID))
{ {
// User needs to be logged into this sim // User needs to be logged into this sim
if (m_scenePresences.ContainsKey(agentID)) if (m_scenePresences.ContainsKey(agentID))
{
// First check that this is the sim owner
if (Permissions.GenericEstatePermission(agentID))
{ {
// Next we check for spoofing..... // Next we check for spoofing.....
LLUUID testSessionID = m_scenePresences[agentID].ControllingClient.SessionId; LLUUID testSessionID = m_scenePresences[agentID].ControllingClient.SessionId;
@ -2511,12 +2532,13 @@ namespace OpenSim.Region.Environment.Scenes
} }
} }
} }
}
else else
{ {
m_scenePresences[agentID].ControllingClient.SendAgentAlertMessage("Request for god powers denied", false); m_scenePresences[agentID].ControllingClient.SendAgentAlertMessage("Request for god powers denied", false);
} }
} }
}
}
/// <summary> /// <summary>
/// Sends a Big Blue Box message on the upper right of the screen to the client /// Sends a Big Blue Box message on the upper right of the screen to the client
@ -2571,6 +2593,8 @@ namespace OpenSim.Region.Environment.Scenes
{ {
// For some reason the client sends this seemingly hard coded UUID for kicking everyone. Dun-know. // For some reason the client sends this seemingly hard coded UUID for kicking everyone. Dun-know.
LLUUID kickUserID = new LLUUID("44e87126e7944ded05b37c42da3d5cdb"); LLUUID kickUserID = new LLUUID("44e87126e7944ded05b37c42da3d5cdb");
lock (m_scenePresences)
{
if (m_scenePresences.ContainsKey(agentID) || agentID == kickUserID) if (m_scenePresences.ContainsKey(agentID) || agentID == kickUserID)
{ {
if (Permissions.GenericEstatePermission(godID)) if (Permissions.GenericEstatePermission(godID))
@ -2586,6 +2610,7 @@ namespace OpenSim.Region.Environment.Scenes
} }
); );
// This is a bit crude. It seems the client will be null before it actually stops the thread // This is a bit crude. It seems the client will be null before it actually stops the thread
// The thread will kill itself eventually :/ // The thread will kill itself eventually :/
// Is there another way to make sure *all* clients get this 'inter region' message? // Is there another way to make sure *all* clients get this 'inter region' message?
@ -2623,6 +2648,7 @@ namespace OpenSim.Region.Environment.Scenes
} }
} }
} }
}
public void HandleObjectPermissionsUpdate(IClientAPI controller, LLUUID agentID, LLUUID sessionID, byte field, uint localId, uint mask, byte set) public void HandleObjectPermissionsUpdate(IClientAPI controller, LLUUID agentID, LLUUID sessionID, byte field, uint localId, uint mask, byte set)
{ {

View File

@ -1506,6 +1506,7 @@ namespace OpenSim.Region.Environment.Scenes
foreach (ScenePresence avatar in avatars) foreach (ScenePresence avatar in avatars)
{ {
SendFullUpdateToOtherClient(avatar); SendFullUpdateToOtherClient(avatar);
if (avatar.LocalId != LocalId) if (avatar.LocalId != LocalId)
{ {
if (!avatar.m_isChildAgent || m_scene.m_seeIntoRegionFromNeighbor) if (!avatar.m_isChildAgent || m_scene.m_seeIntoRegionFromNeighbor)