* Fixed a bug where clients were being added to ClientManager twice
* Changed the ClientManager interface to reduce potential errors with duplicate or mismatched keys * Added IClientAPI.RemoteEndPoint, which can (hopefully) eventually replace IClientAPI.CircuitCode * Changed the order of operations during client shutdownprioritization
parent
23a334b9f5
commit
395a8680c3
|
@ -97,19 +97,17 @@ namespace OpenSim.Framework
|
||||||
/// Add a client reference to the collection if it does not already
|
/// Add a client reference to the collection if it does not already
|
||||||
/// exist
|
/// exist
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key">UUID of the client</param>
|
|
||||||
/// <param name="key2">Remote endpoint of the client</param>
|
|
||||||
/// <param name="value">Reference to the client object</param>
|
/// <param name="value">Reference to the client object</param>
|
||||||
/// <returns>True if the client reference was successfully added,
|
/// <returns>True if the client reference was successfully added,
|
||||||
/// otherwise false if the given key already existed in the collection</returns>
|
/// otherwise false if the given key already existed in the collection</returns>
|
||||||
public bool Add(UUID key, IPEndPoint key2, IClientAPI value)
|
public bool Add(IClientAPI value)
|
||||||
{
|
{
|
||||||
lock (m_writeLock)
|
lock (m_writeLock)
|
||||||
{
|
{
|
||||||
if (!m_dict.ContainsKey(key) && !m_dict2.ContainsKey(key2))
|
if (!m_dict.ContainsKey(value.AgentId) && !m_dict2.ContainsKey(value.RemoteEndPoint))
|
||||||
{
|
{
|
||||||
m_dict = m_dict.Add(key, value);
|
m_dict = m_dict.Add(value.AgentId, value);
|
||||||
m_dict2 = m_dict2.Add(key2, value);
|
m_dict2 = m_dict2.Add(value.RemoteEndPoint, value);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -123,14 +121,16 @@ namespace OpenSim.Framework
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Remove a client from the collection
|
/// Remove a client from the collection
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key">UUID of the client</param>
|
/// <param name="value">Reference to the client object</param>
|
||||||
/// <param name="key2">Remote endpoint of the client</param>
|
public void Remove(IClientAPI value)
|
||||||
public void Remove(UUID key, IPEndPoint key2)
|
|
||||||
{
|
{
|
||||||
lock (m_writeLock)
|
lock (m_writeLock)
|
||||||
{
|
{
|
||||||
m_dict = m_dict.Delete(key);
|
if (m_dict.ContainsKey(value.AgentId))
|
||||||
m_dict2 = m_dict2.Delete(key2);
|
m_dict = m_dict.Delete(value.AgentId);
|
||||||
|
|
||||||
|
if (m_dict2.ContainsKey(value.RemoteEndPoint))
|
||||||
|
m_dict2 = m_dict2.Delete(value.RemoteEndPoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -561,6 +561,8 @@ namespace OpenSim.Framework
|
||||||
// [Obsolete("LLClientView Specific - Circuits are unique to LLClientView")]
|
// [Obsolete("LLClientView Specific - Circuits are unique to LLClientView")]
|
||||||
uint CircuitCode { get; }
|
uint CircuitCode { get; }
|
||||||
|
|
||||||
|
IPEndPoint RemoteEndPoint { get; }
|
||||||
|
|
||||||
event GenericMessage OnGenericMessage;
|
event GenericMessage OnGenericMessage;
|
||||||
|
|
||||||
// [Obsolete("LLClientView Specific - Replace with more bare-bones arguments.")]
|
// [Obsolete("LLClientView Specific - Replace with more bare-bones arguments.")]
|
||||||
|
|
|
@ -411,38 +411,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
"[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);
|
||||||
|
|
||||||
// Remove ourselves from the scene
|
|
||||||
m_scene.ClientManager.Remove(m_agentId, m_udpClient.RemoteEndPoint);
|
|
||||||
|
|
||||||
if (m_imageManager != null)
|
|
||||||
{
|
|
||||||
m_imageManager.Close();
|
|
||||||
m_imageManager = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_udpServer != null)
|
|
||||||
{
|
|
||||||
m_udpServer.Flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OnConnectionClosed != null)
|
|
||||||
OnConnectionClosed(this);
|
|
||||||
|
|
||||||
CloseCleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CloseCleanup()
|
|
||||||
{
|
|
||||||
m_scene.RemoveClient(AgentId);
|
|
||||||
|
|
||||||
//m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false));
|
|
||||||
//m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
|
|
||||||
|
|
||||||
// Send the STOP packet
|
// Send the STOP packet
|
||||||
DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
|
DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
|
||||||
OutPacket(disable, ThrottleOutPacketType.Unknown);
|
OutPacket(disable, ThrottleOutPacketType.Unknown);
|
||||||
|
|
||||||
Thread.Sleep(2000);
|
IsActive = false;
|
||||||
|
|
||||||
|
// Shutdown the image manager
|
||||||
|
if (m_imageManager != null)
|
||||||
|
m_imageManager.Close();
|
||||||
|
|
||||||
|
// Fire the callback for this connection closing
|
||||||
|
if (OnConnectionClosed != null)
|
||||||
|
OnConnectionClosed(this);
|
||||||
|
|
||||||
|
// Flush all of the packets out of the UDP server for this client
|
||||||
|
if (m_udpServer != null)
|
||||||
|
m_udpServer.Flush(m_udpClient);
|
||||||
|
|
||||||
|
// Remove ourselves from the scene
|
||||||
|
m_scene.RemoveClient(AgentId);
|
||||||
|
m_scene.ClientManager.Remove(this);
|
||||||
|
|
||||||
|
//m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false));
|
||||||
|
//GC.Collect();
|
||||||
|
//m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
|
||||||
|
|
||||||
|
// FIXME: Is this still necessary?
|
||||||
|
//Thread.Sleep(2000);
|
||||||
|
|
||||||
// Shut down timers. Thread Context of this method is murky. Lock all timers
|
// Shut down timers. Thread Context of this method is murky. Lock all timers
|
||||||
if (m_avatarTerseUpdateTimer.Enabled)
|
if (m_avatarTerseUpdateTimer.Enabled)
|
||||||
|
@ -459,8 +455,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// We need to do this over grid communications
|
// We need to do this over grid communications
|
||||||
//m_scene.CloseAllAgents(CircuitCode);
|
//m_scene.CloseAllAgents(CircuitCode);
|
||||||
|
|
||||||
IsActive = false;
|
|
||||||
|
|
||||||
m_avatarTerseUpdateTimer.Dispose();
|
m_avatarTerseUpdateTimer.Dispose();
|
||||||
m_primTerseUpdateTimer.Dispose();
|
m_primTerseUpdateTimer.Dispose();
|
||||||
m_primFullUpdateTimer.Dispose();
|
m_primFullUpdateTimer.Dispose();
|
||||||
|
|
|
@ -167,39 +167,39 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
J2KImage imagereq;
|
J2KImage imagereq;
|
||||||
int numCollected = 0;
|
int numCollected = 0;
|
||||||
|
|
||||||
//lock (m_syncRoot)
|
m_lastloopprocessed = DateTime.Now.Ticks;
|
||||||
//{
|
|
||||||
m_lastloopprocessed = DateTime.Now.Ticks;
|
|
||||||
|
|
||||||
// This can happen during Close()
|
// This can happen during Close()
|
||||||
if (m_client == null)
|
if (m_client == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
while ((imagereq = GetHighestPriorityImage()) != null)
|
while ((imagereq = GetHighestPriorityImage()) != null)
|
||||||
|
{
|
||||||
|
if (imagereq.IsDecoded == true)
|
||||||
{
|
{
|
||||||
if (imagereq.IsDecoded == true)
|
++numCollected;
|
||||||
|
|
||||||
|
if (imagereq.SendPackets(m_client, maxpack))
|
||||||
{
|
{
|
||||||
++numCollected;
|
// Send complete. Destroy any knowledge of this transfer
|
||||||
|
RemoveImageFromQueue(imagereq);
|
||||||
if (imagereq.SendPackets(m_client, maxpack))
|
|
||||||
{
|
|
||||||
// Send complete. Destroy any knowledge of this transfer
|
|
||||||
RemoveImageFromQueue(imagereq);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numCollected == count)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
//}
|
|
||||||
|
if (numCollected == count)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return m_priorityQueue.Count > 0;
|
return m_priorityQueue.Count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Faux destructor
|
/// <summary>
|
||||||
|
/// Faux destructor
|
||||||
|
/// </summary>
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
m_shuttingdown = true;
|
m_shuttingdown = true;
|
||||||
|
m_priorityQueue = null;
|
||||||
m_j2kDecodeModule = null;
|
m_j2kDecodeModule = null;
|
||||||
m_assetCache = null;
|
m_assetCache = null;
|
||||||
m_client = null;
|
m_client = null;
|
||||||
|
|
|
@ -390,7 +390,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Flush()
|
public void Flush(LLUDPClient udpClient)
|
||||||
{
|
{
|
||||||
// FIXME: Implement?
|
// FIXME: Implement?
|
||||||
}
|
}
|
||||||
|
@ -645,15 +645,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
client.OnLogout += LogoutHandler;
|
client.OnLogout += LogoutHandler;
|
||||||
client.OnConnectionClosed += ConnectionClosedHandler;
|
client.OnConnectionClosed += ConnectionClosedHandler;
|
||||||
|
|
||||||
m_scene.ClientManager.Add(agentID, remoteEndPoint, client);
|
|
||||||
|
|
||||||
// Start the IClientAPI
|
// Start the IClientAPI
|
||||||
m_scene.ClientManager.Add(agentID, remoteEndPoint, client);
|
m_scene.ClientManager.Add(client);
|
||||||
client.Start();
|
client.Start();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_log.Debug("[LLUDPSERVER]: Ignoring a repeated UseCircuitCode from " + udpClient.AgentID);
|
m_log.WarnFormat("[LLUDPSERVER]: Ignoring a repeated UseCircuitCode from {0} at {1} for circuit {2}",
|
||||||
|
udpClient.AgentID, remoteEndPoint, circuitCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue