From 22e8d0022f4a4041a40dd9298f9612609a3fd1a0 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 22 Jun 2023 13:50:19 +0100 Subject: [PATCH] AgentCircuitManager: go back to use of normal dictionaries and lock() --- OpenSim/Framework/AgentCircuitManager.cs | 174 +++++++++++++---------- 1 file changed, 99 insertions(+), 75 deletions(-) diff --git a/OpenSim/Framework/AgentCircuitManager.cs b/OpenSim/Framework/AgentCircuitManager.cs index 060ce9542f..b445759e75 100644 --- a/OpenSim/Framework/AgentCircuitManager.cs +++ b/OpenSim/Framework/AgentCircuitManager.cs @@ -26,7 +26,7 @@ */ using System.Collections.Generic; -using System.Collections.Concurrent; +using System.Runtime.InteropServices; using OpenMetaverse; namespace OpenSim.Framework @@ -39,48 +39,43 @@ namespace OpenSim.Framework /// /// Agent circuits indexed by circuit code. /// - /// - /// We lock this for operations both on this dictionary and on m_agentCircuitsByUUID - /// - private readonly ConcurrentDictionary m_agentCircuits = new(); + private readonly Dictionary m_agentCircuits = new(); /// /// Agent circuits indexed by agent UUID. /// - private readonly ConcurrentDictionary m_agentCircuitsByUUID = new(); + private readonly Dictionary m_agentCircuitsByUUID = new(); + + private readonly object m_lock = new(); public virtual AuthenticateResponse AuthenticateSession(UUID sessionID, UUID agentID, uint circuitcode) { - AuthenticateResponse user = new(); - if (!m_agentCircuits.TryGetValue(circuitcode, out AgentCircuitData validcircuit) || validcircuit is null) + lock (m_lock) { - //don't have this circuit code in our list - user.Authorised = false; - return user; - } - - if (sessionID.Equals(validcircuit.SessionID) && agentID.Equals(validcircuit.AgentID)) - { - user.Authorised = true; - user.LoginInfo = new Login + if (m_agentCircuits.TryGetValue(circuitcode, out AgentCircuitData validcircuit) || validcircuit is null) { - Agent = agentID, - Session = sessionID, - SecureSession = validcircuit.SecureSessionID, - First = validcircuit.firstname, - Last = validcircuit.lastname, - InventoryFolder = validcircuit.InventoryFolder, - BaseFolder = validcircuit.BaseFolder, - StartPos = validcircuit.startpos, - StartFar = validcircuit.startfar - }; + if (sessionID.Equals(validcircuit.SessionID) && agentID.Equals(validcircuit.AgentID)) + { + return new AuthenticateResponse() + { + Authorised = true, + LoginInfo = new Login + { + Agent = agentID, + Session = sessionID, + SecureSession = validcircuit.SecureSessionID, + First = validcircuit.firstname, + Last = validcircuit.lastname, + InventoryFolder = validcircuit.InventoryFolder, + BaseFolder = validcircuit.BaseFolder, + StartPos = validcircuit.startpos, + StartFar = validcircuit.startfar + } + }; + } + } } - else - { - // Invalid - user.Authorised = false; - } - return user; + return new AuthenticateResponse(); } /// @@ -91,55 +86,74 @@ namespace OpenSim.Framework public virtual void AddNewCircuit(AgentCircuitData agentData) { agentData.child = true; - RemoveCircuit(agentData.AgentID); // no duplications - m_agentCircuits[agentData.circuitcode] = agentData; - m_agentCircuitsByUUID[agentData.AgentID] = agentData; + lock (m_lock) + { + ref AgentCircuitData acd = ref CollectionsMarshal.GetValueRefOrAddDefault(m_agentCircuits, agentData.circuitcode, out bool existed); + if (existed && acd is not null && acd.AgentID.NotEqual(agentData.AgentID)) + m_agentCircuitsByUUID.Remove(acd.AgentID); + acd = agentData; + m_agentCircuitsByUUID[agentData.AgentID] = agentData; + } } public virtual void AddNewCircuit(uint circuitCode, AgentCircuitData agentData) { agentData.circuitcode = circuitCode; - RemoveCircuit(agentData.AgentID); // no duplications - m_agentCircuits[circuitCode] = agentData; - m_agentCircuitsByUUID[agentData.AgentID] = agentData; + lock (m_lock) + { + ref AgentCircuitData acd = ref CollectionsMarshal.GetValueRefOrAddDefault(m_agentCircuits, agentData.circuitcode, out bool existed); + if (existed && acd is not null && acd.AgentID.NotEqual(agentData.AgentID)) + m_agentCircuitsByUUID.Remove(acd.AgentID); + acd = agentData; + m_agentCircuitsByUUID[agentData.AgentID] = agentData; + } } public virtual void RemoveCircuit(uint circuitCode) { - if (m_agentCircuits.TryRemove(circuitCode, out AgentCircuitData ac)) + lock (m_lock) { - m_agentCircuitsByUUID.TryRemove(ac.AgentID, out AgentCircuitData _); + if (m_agentCircuits.Remove(circuitCode, out AgentCircuitData ac)) + m_agentCircuitsByUUID.Remove(ac.AgentID); } } public virtual void RemoveCircuit(UUID agentID) { - if (m_agentCircuitsByUUID.TryRemove(agentID, out AgentCircuitData ac)) + lock (m_lock) { - m_agentCircuits.TryRemove(ac.circuitcode, out AgentCircuitData _); + if (m_agentCircuitsByUUID.Remove(agentID, out AgentCircuitData ac)) + m_agentCircuits.Remove(ac.circuitcode); } } public virtual void RemoveCircuit(AgentCircuitData ac) { - m_agentCircuitsByUUID.TryRemove(ac.AgentID, out AgentCircuitData byuuid); - m_agentCircuits.TryRemove(ac.circuitcode, out AgentCircuitData _); - if (byuuid is not null && byuuid.circuitcode != ac.circuitcode) //?? - m_agentCircuits.TryRemove(byuuid.circuitcode, out AgentCircuitData _); + lock (m_lock) + { + if (m_agentCircuitsByUUID.Remove(ac.AgentID, out AgentCircuitData byuuid)) + { + if (byuuid.circuitcode != ac.circuitcode) + m_agentCircuits.Remove(byuuid.circuitcode); + } + m_agentCircuits.Remove(ac.circuitcode); + } } public AgentCircuitData GetAgentCircuitData(uint circuitCode) { - if(m_agentCircuits.TryGetValue(circuitCode, out AgentCircuitData agentCircuit)) - return agentCircuit; - return null; + lock (m_lock) + { + return m_agentCircuits.TryGetValue(circuitCode, out AgentCircuitData agentCircuit) ? agentCircuit : null; + } } public AgentCircuitData GetAgentCircuitData(UUID agentID) { - if(m_agentCircuitsByUUID.TryGetValue(agentID, out AgentCircuitData agentCircuit)) - return agentCircuit; - return null; + lock (m_lock) + { + return m_agentCircuitsByUUID.TryGetValue(agentID, out AgentCircuitData agentCircuit) ? agentCircuit : null; + } } /// @@ -148,22 +162,25 @@ namespace OpenSim.Framework /// public Dictionary GetAgentCircuits() { - lock (m_agentCircuits) + lock (m_lock) return new Dictionary(m_agentCircuitsByUUID); } public void UpdateAgentData(AgentCircuitData agentData) { - if (m_agentCircuits.TryGetValue(agentData.circuitcode, out AgentCircuitData ac)) + lock (m_lock) { - ac.firstname = agentData.firstname; - ac.lastname = agentData.lastname; - ac.startpos = agentData.startpos; - ac.startfar = agentData.startfar; + if (m_agentCircuits.TryGetValue(agentData.circuitcode, out AgentCircuitData ac)) + { + ac.firstname = agentData.firstname; + ac.lastname = agentData.lastname; + ac.startpos = agentData.startpos; + ac.startfar = agentData.startfar; - // Updated for when we don't know them before calling Scene.NewUserConnection - ac.SecureSessionID = agentData.SecureSessionID; - ac.SessionID = agentData.SessionID; + // Updated for when we don't know them before calling Scene.NewUserConnection + ac.SecureSessionID = agentData.SecureSessionID; + ac.SessionID = agentData.SessionID; + } } } @@ -174,29 +191,36 @@ namespace OpenSim.Framework /// public bool TryChangeCircuitCode(uint circuitcode, uint newcircuitcode) { - if(m_agentCircuits.ContainsKey(newcircuitcode)) - return false; - if (m_agentCircuits.TryRemove(circuitcode, out AgentCircuitData agentData)) + lock (m_lock) { - agentData.circuitcode = newcircuitcode; - m_agentCircuits[newcircuitcode] = agentData; - m_agentCircuitsByUUID[agentData.AgentID] = agentData; - return true; + if (m_agentCircuits.ContainsKey(newcircuitcode)) + return false; + if (m_agentCircuits.Remove(circuitcode, out AgentCircuitData agentData)) + { + agentData.circuitcode = newcircuitcode; + m_agentCircuits[newcircuitcode] = agentData; + m_agentCircuitsByUUID[agentData.AgentID] = agentData; + return true; + } + return false; } - return false; } public void UpdateAgentChildStatus(uint circuitcode, bool childstatus) { - if (m_agentCircuits.TryGetValue(circuitcode, out AgentCircuitData ac)) - ac.child = childstatus; + lock (m_lock) + { + if (m_agentCircuits.TryGetValue(circuitcode, out AgentCircuitData ac)) + ac.child = childstatus; + } } public bool GetAgentChildStatus(uint circuitcode) { - if (m_agentCircuits.TryGetValue(circuitcode, out AgentCircuitData ac)) - return ac.child; - return false; + lock (m_lock) + { + return m_agentCircuits.TryGetValue(circuitcode, out AgentCircuitData ac) && ac.child; + } } } } \ No newline at end of file