* 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()
{
lock (ScenePresences)
{
ScenePresences.Clear();
}
//SceneObjects.Clear();
Entities.Clear();
}
@ -792,6 +796,8 @@ namespace OpenSim.Region.Environment.Scenes
/// <returns></returns>
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> ScenePresencesList = GetScenePresences();
@ -812,11 +818,14 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="avatarID"></param>
/// <returns>null if the agent was not found</returns>
public ScenePresence GetScenePresence(LLUUID agentID)
{
lock (ScenePresences)
{
if (ScenePresences.ContainsKey(agentID))
{
return ScenePresences[agentID];
}
}
return null;
}
@ -916,6 +925,8 @@ namespace OpenSim.Region.Environment.Scenes
}
internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
{
lock (ScenePresences)
{
foreach (ScenePresence presence in ScenePresences.Values)
{
@ -930,6 +941,7 @@ namespace OpenSim.Region.Environment.Scenes
}
}
}
}
avatar = null;
return false;
@ -1007,12 +1019,15 @@ namespace OpenSim.Region.Environment.Scenes
}
internal void ForEachClient(Action<IClientAPI> action)
{
lock (ScenePresences)
{
foreach (ScenePresence presence in ScenePresences.Values)
{
action(presence.ControllingClient);
}
}
}
#endregion

View File

@ -2075,6 +2075,8 @@ namespace OpenSim.Region.Environment.Scenes
public virtual void AgentCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying)
{
if (regionHandle == m_regInfo.RegionHandle)
{
lock (m_scenePresences)
{
if (m_scenePresences.ContainsKey(agentID))
{
@ -2091,6 +2093,7 @@ namespace OpenSim.Region.Environment.Scenes
}
}
}
}
public virtual bool IncomingChildAgentDataUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData)
{
@ -2202,6 +2205,8 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="flags"></param>
public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, LLVector3 position,
LLVector3 lookAt, uint flags)
{
lock (m_scenePresences)
{
if (m_scenePresences.ContainsKey(remoteClient.AgentId))
{
@ -2209,6 +2214,7 @@ namespace OpenSim.Region.Environment.Scenes
position, lookAt, flags);
}
}
}
/// <summary>
/// Tries to teleport agent to landmark.
@ -2217,6 +2223,8 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="regionHandle"></param>
/// <param name="position"></param>
public void RequestTeleportLandmark(IClientAPI remoteClient, ulong regionHandle, LLVector3 position)
{
lock (m_scenePresences)
{
if (m_scenePresences.ContainsKey(remoteClient.AgentId))
{
@ -2224,6 +2232,7 @@ namespace OpenSim.Region.Environment.Scenes
position, LLVector3.Zero, 0);
}
}
}
/// <summary>
/// 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>
public void SendUrlToUser(LLUUID avatarID, string objectName, LLUUID objectID, LLUUID ownerID, bool groupOwned,
string message, string url)
{
lock (m_scenePresences)
{
if (m_scenePresences.ContainsKey(avatarID))
{
@ -2359,12 +2370,17 @@ namespace OpenSim.Region.Environment.Scenes
message, url);
}
}
}
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))
{
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="modal"></param>
public void SendAlertToUser(LLUUID agentID, string message, bool modal)
{
lock (m_scenePresences)
{
if (m_scenePresences.ContainsKey(agentID))
{
m_scenePresences[agentID].ControllingClient.SendAgentAlertMessage(message, modal);
}
}
}
/// <summary>
///
@ -2494,11 +2513,13 @@ namespace OpenSim.Region.Environment.Scenes
public void handleRequestGodlikePowers(LLUUID agentID, LLUUID sessionID, LLUUID token, bool godLike,
IClientAPI controllingClient)
{
// First check that this is the sim owner
if (Permissions.GenericEstatePermission(agentID))
lock (m_scenePresences)
{
// User needs to be logged into this sim
if (m_scenePresences.ContainsKey(agentID))
{
// First check that this is the sim owner
if (Permissions.GenericEstatePermission(agentID))
{
// Next we check for spoofing.....
LLUUID testSessionID = m_scenePresences[agentID].ControllingClient.SessionId;
@ -2511,12 +2532,13 @@ namespace OpenSim.Region.Environment.Scenes
}
}
}
}
else
{
m_scenePresences[agentID].ControllingClient.SendAgentAlertMessage("Request for god powers denied", false);
}
}
}
}
/// <summary>
/// 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.
LLUUID kickUserID = new LLUUID("44e87126e7944ded05b37c42da3d5cdb");
lock (m_scenePresences)
{
if (m_scenePresences.ContainsKey(agentID) || agentID == kickUserID)
{
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
// The thread will kill itself eventually :/
// 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)
{

View File

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