Do proper locking of m_localScenes list in SceneManager

bulletsim
Justin Clark-Casey (justincc) 2011-08-06 01:15:49 +01:00
parent dad1d6df18
commit 76f46b2545
2 changed files with 143 additions and 97 deletions

View File

@ -47,12 +47,12 @@ namespace OpenSim.Region.Framework.Scenes
public event RestartSim OnRestartSim; public event RestartSim OnRestartSim;
private readonly List<Scene> m_localScenes; private readonly List<Scene> m_localScenes = new List<Scene>();
private Scene m_currentScene = null; private Scene m_currentScene = null;
public List<Scene> Scenes public List<Scene> Scenes
{ {
get { return m_localScenes; } get { return new List<Scene>(m_localScenes); }
} }
public Scene CurrentScene public Scene CurrentScene
@ -66,13 +66,12 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (m_currentScene == null) if (m_currentScene == null)
{ {
if (m_localScenes.Count > 0) lock (m_localScenes)
{ {
return m_localScenes[0]; if (m_localScenes.Count > 0)
} return m_localScenes[0];
else else
{ return null;
return null;
} }
} }
else else
@ -82,26 +81,25 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public SceneManager()
{
m_localScenes = new List<Scene>();
}
public void Close() public void Close()
{ {
// collect known shared modules in sharedModules // collect known shared modules in sharedModules
Dictionary<string, IRegionModule> sharedModules = new Dictionary<string, IRegionModule>(); Dictionary<string, IRegionModule> sharedModules = new Dictionary<string, IRegionModule>();
for (int i = 0; i < m_localScenes.Count; i++)
lock (m_localScenes)
{ {
// extract known shared modules from scene for (int i = 0; i < m_localScenes.Count; i++)
foreach (string k in m_localScenes[i].Modules.Keys)
{ {
if (m_localScenes[i].Modules[k].IsSharedModule && // extract known shared modules from scene
!sharedModules.ContainsKey(k)) foreach (string k in m_localScenes[i].Modules.Keys)
sharedModules[k] = m_localScenes[i].Modules[k]; {
if (m_localScenes[i].Modules[k].IsSharedModule &&
!sharedModules.ContainsKey(k))
sharedModules[k] = m_localScenes[i].Modules[k];
}
// close scene/region
m_localScenes[i].Close();
} }
// close scene/region
m_localScenes[i].Close();
} }
// all regions/scenes are now closed, we can now safely // all regions/scenes are now closed, we can now safely
@ -114,13 +112,16 @@ namespace OpenSim.Region.Framework.Scenes
public void Close(Scene cscene) public void Close(Scene cscene)
{ {
if (m_localScenes.Contains(cscene)) lock (m_localScenes)
{ {
for (int i = 0; i < m_localScenes.Count; i++) if (m_localScenes.Contains(cscene))
{ {
if (m_localScenes[i].Equals(cscene)) for (int i = 0; i < m_localScenes.Count; i++)
{ {
m_localScenes[i].Close(); if (m_localScenes[i].Equals(cscene))
{
m_localScenes[i].Close();
}
} }
} }
} }
@ -129,27 +130,33 @@ namespace OpenSim.Region.Framework.Scenes
public void Add(Scene scene) public void Add(Scene scene)
{ {
scene.OnRestart += HandleRestart; scene.OnRestart += HandleRestart;
m_localScenes.Add(scene);
lock (m_localScenes)
m_localScenes.Add(scene);
} }
public void HandleRestart(RegionInfo rdata) public void HandleRestart(RegionInfo rdata)
{ {
m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main"); m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main");
int RegionSceneElement = -1; int RegionSceneElement = -1;
for (int i = 0; i < m_localScenes.Count; i++)
lock (m_localScenes)
{ {
if (rdata.RegionName == m_localScenes[i].RegionInfo.RegionName) for (int i = 0; i < m_localScenes.Count; i++)
{ {
RegionSceneElement = i; if (rdata.RegionName == m_localScenes[i].RegionInfo.RegionName)
{
RegionSceneElement = i;
}
} }
}
// Now we make sure the region is no longer known about by the SceneManager // Now we make sure the region is no longer known about by the SceneManager
// Prevents duplicates. // Prevents duplicates.
if (RegionSceneElement >= 0) if (RegionSceneElement >= 0)
{ {
m_localScenes.RemoveAt(RegionSceneElement); m_localScenes.RemoveAt(RegionSceneElement);
}
} }
// Send signal to main that we're restarting this sim. // Send signal to main that we're restarting this sim.
@ -160,28 +167,32 @@ namespace OpenSim.Region.Framework.Scenes
{ {
RegionInfo Result = null; RegionInfo Result = null;
for (int i = 0; i < m_localScenes.Count; i++) lock (m_localScenes)
{
if (m_localScenes[i].RegionInfo.RegionHandle == regionHandle)
{
// Inform other regions to tell their avatar about me
Result = m_localScenes[i].RegionInfo;
}
}
if (Result != null)
{ {
for (int i = 0; i < m_localScenes.Count; i++) for (int i = 0; i < m_localScenes.Count; i++)
{ {
if (m_localScenes[i].RegionInfo.RegionHandle != regionHandle) if (m_localScenes[i].RegionInfo.RegionHandle == regionHandle)
{ {
// Inform other regions to tell their avatar about me // Inform other regions to tell their avatar about me
//m_localScenes[i].OtherRegionUp(Result); Result = m_localScenes[i].RegionInfo;
} }
} }
}
else if (Result != null)
{ {
m_log.Error("[REGION]: Unable to notify Other regions of this Region coming up"); for (int i = 0; i < m_localScenes.Count; i++)
{
if (m_localScenes[i].RegionInfo.RegionHandle != regionHandle)
{
// Inform other regions to tell their avatar about me
//m_localScenes[i].OtherRegionUp(Result);
}
}
}
else
{
m_log.Error("[REGION]: Unable to notify Other regions of this Region coming up");
}
} }
} }
@ -285,7 +296,8 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (m_currentScene == null) if (m_currentScene == null)
{ {
m_localScenes.ForEach(func); lock (m_localScenes)
m_localScenes.ForEach(func);
} }
else else
{ {
@ -314,12 +326,15 @@ namespace OpenSim.Region.Framework.Scenes
} }
else else
{ {
foreach (Scene scene in m_localScenes) lock (m_localScenes)
{ {
if (String.Compare(scene.RegionInfo.RegionName, regionName, true) == 0) foreach (Scene scene in m_localScenes)
{ {
m_currentScene = scene; if (String.Compare(scene.RegionInfo.RegionName, regionName, true) == 0)
return true; {
m_currentScene = scene;
return true;
}
} }
} }
@ -331,12 +346,15 @@ namespace OpenSim.Region.Framework.Scenes
{ {
m_log.Debug("Searching for Region: '" + regionID + "'"); m_log.Debug("Searching for Region: '" + regionID + "'");
foreach (Scene scene in m_localScenes) lock (m_localScenes)
{ {
if (scene.RegionInfo.RegionID == regionID) foreach (Scene scene in m_localScenes)
{ {
m_currentScene = scene; if (scene.RegionInfo.RegionID == regionID)
return true; {
m_currentScene = scene;
return true;
}
} }
} }
@ -345,26 +363,33 @@ namespace OpenSim.Region.Framework.Scenes
public bool TryGetScene(string regionName, out Scene scene) public bool TryGetScene(string regionName, out Scene scene)
{ {
foreach (Scene mscene in m_localScenes) lock (m_localScenes)
{ {
if (String.Compare(mscene.RegionInfo.RegionName, regionName, true) == 0) foreach (Scene mscene in m_localScenes)
{ {
scene = mscene; if (String.Compare(mscene.RegionInfo.RegionName, regionName, true) == 0)
return true; {
scene = mscene;
return true;
}
} }
} }
scene = null; scene = null;
return false; return false;
} }
public bool TryGetScene(UUID regionID, out Scene scene) public bool TryGetScene(UUID regionID, out Scene scene)
{ {
foreach (Scene mscene in m_localScenes) lock (m_localScenes)
{ {
if (mscene.RegionInfo.RegionID == regionID) foreach (Scene mscene in m_localScenes)
{ {
scene = mscene; if (mscene.RegionInfo.RegionID == regionID)
return true; {
scene = mscene;
return true;
}
} }
} }
@ -374,13 +399,16 @@ namespace OpenSim.Region.Framework.Scenes
public bool TryGetScene(uint locX, uint locY, out Scene scene) public bool TryGetScene(uint locX, uint locY, out Scene scene)
{ {
foreach (Scene mscene in m_localScenes) lock (m_localScenes)
{ {
if (mscene.RegionInfo.RegionLocX == locX && foreach (Scene mscene in m_localScenes)
mscene.RegionInfo.RegionLocY == locY)
{ {
scene = mscene; if (mscene.RegionInfo.RegionLocX == locX &&
return true; mscene.RegionInfo.RegionLocY == locY)
{
scene = mscene;
return true;
}
} }
} }
@ -390,13 +418,16 @@ namespace OpenSim.Region.Framework.Scenes
public bool TryGetScene(IPEndPoint ipEndPoint, out Scene scene) public bool TryGetScene(IPEndPoint ipEndPoint, out Scene scene)
{ {
foreach (Scene mscene in m_localScenes) lock (m_localScenes)
{ {
if ((mscene.RegionInfo.InternalEndPoint.Equals(ipEndPoint.Address)) && foreach (Scene mscene in m_localScenes)
(mscene.RegionInfo.InternalEndPoint.Port == ipEndPoint.Port))
{ {
scene = mscene; if ((mscene.RegionInfo.InternalEndPoint.Equals(ipEndPoint.Address)) &&
return true; (mscene.RegionInfo.InternalEndPoint.Port == ipEndPoint.Port))
{
scene = mscene;
return true;
}
} }
} }
@ -465,11 +496,14 @@ namespace OpenSim.Region.Framework.Scenes
public RegionInfo GetRegionInfo(UUID regionID) public RegionInfo GetRegionInfo(UUID regionID)
{ {
foreach (Scene scene in m_localScenes) lock (m_localScenes)
{ {
if (scene.RegionInfo.RegionID == regionID) foreach (Scene scene in m_localScenes)
{ {
return scene.RegionInfo; if (scene.RegionInfo.RegionID == regionID)
{
return scene.RegionInfo;
}
} }
} }
@ -488,11 +522,14 @@ namespace OpenSim.Region.Framework.Scenes
public bool TryGetScenePresence(UUID avatarId, out ScenePresence avatar) public bool TryGetScenePresence(UUID avatarId, out ScenePresence avatar)
{ {
foreach (Scene scene in m_localScenes) lock (m_localScenes)
{ {
if (scene.TryGetScenePresence(avatarId, out avatar)) foreach (Scene scene in m_localScenes)
{ {
return true; if (scene.TryGetScenePresence(avatarId, out avatar))
{
return true;
}
} }
} }
@ -503,12 +540,16 @@ namespace OpenSim.Region.Framework.Scenes
public bool TryGetAvatarsScene(UUID avatarId, out Scene scene) public bool TryGetAvatarsScene(UUID avatarId, out Scene scene)
{ {
ScenePresence avatar = null; ScenePresence avatar = null;
foreach (Scene mScene in m_localScenes)
lock (m_localScenes)
{ {
if (mScene.TryGetScenePresence(avatarId, out avatar)) foreach (Scene mScene in m_localScenes)
{ {
scene = mScene; if (mScene.TryGetScenePresence(avatarId, out avatar))
return true; {
scene = mScene;
return true;
}
} }
} }
@ -518,17 +559,22 @@ namespace OpenSim.Region.Framework.Scenes
public void CloseScene(Scene scene) public void CloseScene(Scene scene)
{ {
m_localScenes.Remove(scene); lock (m_localScenes)
m_localScenes.Remove(scene);
scene.Close(); scene.Close();
} }
public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
{ {
foreach (Scene scene in m_localScenes) lock (m_localScenes)
{ {
if (scene.TryGetAvatarByName(avatarName, out avatar)) foreach (Scene scene in m_localScenes)
{ {
return true; if (scene.TryGetAvatarByName(avatarName, out avatar))
{
return true;
}
} }
} }
@ -538,7 +584,8 @@ namespace OpenSim.Region.Framework.Scenes
public void ForEachScene(Action<Scene> action) public void ForEachScene(Action<Scene> action)
{ {
m_localScenes.ForEach(action); lock (m_localScenes)
m_localScenes.ForEach(action);
} }
} }
} }

View File

@ -95,7 +95,6 @@ namespace OpenSim.Services.HypergridService
m_InGatekeeper = serverConfig.GetBoolean("InGatekeeper", false); m_InGatekeeper = serverConfig.GetBoolean("InGatekeeper", false);
m_log.DebugFormat("[HG IM SERVICE]: Starting... InRobust? {0}", m_InGatekeeper); m_log.DebugFormat("[HG IM SERVICE]: Starting... InRobust? {0}", m_InGatekeeper);
if (gridService == string.Empty || presenceService == string.Empty) if (gridService == string.Empty || presenceService == string.Empty)
throw new Exception(String.Format("Incomplete specifications, InstantMessage Service cannot function.")); throw new Exception(String.Format("Incomplete specifications, InstantMessage Service cannot function."));
@ -120,7 +119,7 @@ namespace OpenSim.Services.HypergridService
public bool IncomingInstantMessage(GridInstantMessage im) public bool IncomingInstantMessage(GridInstantMessage im)
{ {
m_log.DebugFormat("[HG IM SERVICE]: Received message from {0} to {1}", im.fromAgentID, im.toAgentID); // m_log.DebugFormat("[HG IM SERVICE]: Received message from {0} to {1}", im.fromAgentID, im.toAgentID);
UUID toAgentID = new UUID(im.toAgentID); UUID toAgentID = new UUID(im.toAgentID);
bool success = false; bool success = false;
@ -142,7 +141,7 @@ namespace OpenSim.Services.HypergridService
public bool OutgoingInstantMessage(GridInstantMessage im, string url, bool foreigner) public bool OutgoingInstantMessage(GridInstantMessage im, string url, bool foreigner)
{ {
m_log.DebugFormat("[HG IM SERVICE]: Sending message from {0} to {1}@{2}", im.fromAgentID, im.toAgentID, url); // m_log.DebugFormat("[HG IM SERVICE]: Sending message from {0} to {1}@{2}", im.fromAgentID, im.toAgentID, url);
if (url != string.Empty) if (url != string.Empty)
return TrySendInstantMessage(im, url, true, foreigner); return TrySendInstantMessage(im, url, true, foreigner);
else else
@ -333,7 +332,7 @@ namespace OpenSim.Services.HypergridService
if (m_RestURL != string.Empty && (im.offline != 0) if (m_RestURL != string.Empty && (im.offline != 0)
&& (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages))) && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages)))
{ {
m_log.DebugFormat("[HG IM SERVICE]: Message saved"); // m_log.DebugFormat("[HG IM SERVICE]: Message saved");
return SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>( return SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>(
"POST", m_RestURL + "/SaveMessage/", im); "POST", m_RestURL + "/SaveMessage/", im);