* Turned all instances of ForEach loops in ClientManager into Local Arrays.
* Added Locking while the Copy is taking place. * Added an error message to describe what's actually happening.afrisby
parent
f9540e3f11
commit
adf7afb606
|
@ -40,9 +40,25 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public void ForEachClient(ForEachClientDelegate whatToDo)
|
public void ForEachClient(ForEachClientDelegate whatToDo)
|
||||||
{
|
{
|
||||||
foreach (IClientAPI client in m_clients.Values)
|
|
||||||
|
// Wasteful, I know
|
||||||
|
IClientAPI[] LocalClients = new IClientAPI[0];
|
||||||
|
lock (m_clients)
|
||||||
{
|
{
|
||||||
whatToDo(client);
|
LocalClients = new IClientAPI[m_clients.Count];
|
||||||
|
m_clients.Values.CopyTo(LocalClients, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < LocalClients.Length; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
whatToDo(LocalClients[i]);
|
||||||
|
}
|
||||||
|
catch (System.Exception e)
|
||||||
|
{
|
||||||
|
OpenSim.Framework.Console.MainLog.Instance.Warn("CLIENT", "Unable to do ForEachClient for one of the clients" + "\n Reason: " + e.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,29 +100,48 @@ namespace OpenSim.Framework
|
||||||
public void CloseAllCircuits(LLUUID agentId)
|
public void CloseAllCircuits(LLUUID agentId)
|
||||||
{
|
{
|
||||||
uint[] circuits = GetAllCircuits(agentId);
|
uint[] circuits = GetAllCircuits(agentId);
|
||||||
foreach (uint circuit in circuits)
|
// We're using a for loop here so changes to the circuits don't cause it to completely fail.
|
||||||
|
|
||||||
|
for (int i = 0; i < circuits.Length; i++)
|
||||||
{
|
{
|
||||||
IClientAPI client;
|
IClientAPI client;
|
||||||
if (m_clients.TryGetValue(circuit, out client))
|
try
|
||||||
{
|
{
|
||||||
Remove(circuit);
|
|
||||||
|
if (m_clients.TryGetValue(circuits[i], out client))
|
||||||
|
{
|
||||||
|
Remove(client.CircuitCode);
|
||||||
client.Close();
|
client.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (System.Exception e)
|
||||||
|
{
|
||||||
|
OpenSim.Framework.Console.MainLog.Instance.Error("CLIENT", "Unable to shutdown circuit for: " + agentId.ToString() + "\n Reason: " + e.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private uint[] GetAllCircuits(LLUUID agentId)
|
private uint[] GetAllCircuits(LLUUID agentId)
|
||||||
{
|
{
|
||||||
List<uint> circuits = new List<uint>();
|
List<uint> circuits = new List<uint>();
|
||||||
|
// Wasteful, I know
|
||||||
foreach (KeyValuePair<uint, IClientAPI> pair in m_clients)
|
IClientAPI[] LocalClients = new IClientAPI[0];
|
||||||
|
lock (m_clients)
|
||||||
{
|
{
|
||||||
if (pair.Value.AgentId == agentId)
|
LocalClients = new IClientAPI[m_clients.Count];
|
||||||
{
|
m_clients.Values.CopyTo(LocalClients, 0);
|
||||||
circuits.Add(pair.Key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < LocalClients.Length; i++ )
|
||||||
|
{
|
||||||
|
if (LocalClients[i].AgentId == agentId)
|
||||||
|
{
|
||||||
|
circuits.Add(LocalClients[i].CircuitCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
return circuits.ToArray();
|
return circuits.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,14 +151,24 @@ namespace OpenSim.Framework
|
||||||
ViewerEffectPacket packet = new ViewerEffectPacket();
|
ViewerEffectPacket packet = new ViewerEffectPacket();
|
||||||
packet.Effect = effectBlock;
|
packet.Effect = effectBlock;
|
||||||
|
|
||||||
foreach (IClientAPI client in m_clients.Values)
|
// Wasteful, I know
|
||||||
|
IClientAPI[] LocalClients = new IClientAPI[0];
|
||||||
|
lock (m_clients)
|
||||||
{
|
{
|
||||||
if (client.AgentId != sender.AgentId)
|
LocalClients = new IClientAPI[m_clients.Count];
|
||||||
{
|
m_clients.Values.CopyTo(LocalClients, 0);
|
||||||
packet.AgentData.AgentID = client.AgentId;
|
|
||||||
packet.AgentData.SessionID = client.SessionId;
|
|
||||||
client.OutPacket(packet,ThrottleOutPacketType.Task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < LocalClients.Length; i++)
|
||||||
|
{
|
||||||
|
if (LocalClients[i].AgentId != sender.AgentId)
|
||||||
|
{
|
||||||
|
packet.AgentData.AgentID = LocalClients[i].AgentId;
|
||||||
|
packet.AgentData.SessionID = LocalClients[i].SessionId;
|
||||||
|
LocalClients[i].OutPacket(packet, ThrottleOutPacketType.Task);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -209,8 +209,8 @@ namespace OpenSim.Region.ClientStack
|
||||||
m_scene.RemoveClient(AgentId);
|
m_scene.RemoveClient(AgentId);
|
||||||
|
|
||||||
// Send the STOP packet
|
// Send the STOP packet
|
||||||
libsecondlife.Packets.DisableSimulatorPacket disable = new libsecondlife.Packets.DisableSimulatorPacket();
|
//libsecondlife.Packets.DisableSimulatorPacket disable = new libsecondlife.Packets.DisableSimulatorPacket();
|
||||||
OutPacket(disable, ThrottleOutPacketType.Task);
|
//OutPacket(disable, ThrottleOutPacketType.Task);
|
||||||
|
|
||||||
// FLUSH Packets
|
// FLUSH Packets
|
||||||
m_packetQueue.Close();
|
m_packetQueue.Close();
|
||||||
|
|
|
@ -459,6 +459,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
// This is the method that shuts down the scene.
|
// This is the method that shuts down the scene.
|
||||||
public override void Close()
|
public override void Close()
|
||||||
{
|
{
|
||||||
|
MainLog.Instance.Warn("SCENE", "Closing down the single simulator: " + RegionInfo.RegionName);
|
||||||
// Kick all ROOT agents with the message, 'The simulator is going down'
|
// Kick all ROOT agents with the message, 'The simulator is going down'
|
||||||
ForEachScenePresence(delegate(ScenePresence avatar)
|
ForEachScenePresence(delegate(ScenePresence avatar)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue