From 8e08dd20dc9fe785874943c7986f82af60ed1879 Mon Sep 17 00:00:00 2001 From: diva Date: Sat, 18 Apr 2009 16:37:05 +0000 Subject: Thank you dslake for diagnosing and fixing a race condition in OGS1SecureInventoryServer (mantis #3483). The provided patch was slightly modified to narrow the locking scope to smaller portions of the functions. Applied the same locking to HGInventoryService, which suffered from the same race condition. --- .../OGS1/OGS1SecureInventoryService.cs | 122 +++++++++++---------- 1 file changed, 65 insertions(+), 57 deletions(-) (limited to 'OpenSim/Region/Communications/OGS1/OGS1SecureInventoryService.cs') diff --git a/OpenSim/Region/Communications/OGS1/OGS1SecureInventoryService.cs b/OpenSim/Region/Communications/OGS1/OGS1SecureInventoryService.cs index 03fb0d5..e24f820 100644 --- a/OpenSim/Region/Communications/OGS1/OGS1SecureInventoryService.cs +++ b/OpenSim/Region/Communications/OGS1/OGS1SecureInventoryService.cs @@ -69,34 +69,36 @@ namespace OpenSim.Region.Communications.OGS1 /// public void RequestInventoryForUser(UUID userID, UUID session_id, InventoryReceiptCallback callback) { - if (!m_RequestingInventory.ContainsKey(userID)) + lock (m_RequestingInventory) { - m_RequestingInventory.Add(userID, callback); - - try + if (!m_RequestingInventory.ContainsKey(userID)) + m_RequestingInventory.Add(userID, callback); + else { - m_log.InfoFormat( - "[OGS1 INVENTORY SERVICE]: Requesting inventory from {0}/GetInventory/ for user {1}", - _inventoryServerUrl, userID); + m_log.ErrorFormat("[OGS1 INVENTORY SERVICE]: RequestInventoryForUser() - could you not find user profile for {0}", userID); + return; + } + } - RestSessionObjectPosterResponse requester - = new RestSessionObjectPosterResponse(); - requester.ResponseCallback = InventoryResponse; + try + { + m_log.InfoFormat( + "[OGS1 INVENTORY SERVICE]: Requesting inventory from {0}/GetInventory/ for user {1}", + _inventoryServerUrl, userID); - requester.BeginPostObject(_inventoryServerUrl + "/GetInventory/", userID.Guid, session_id.ToString(), userID.ToString()); - } - catch (WebException e) - { - if (StatsManager.SimExtraStats != null) - StatsManager.SimExtraStats.AddInventoryServiceRetrievalFailure(); + RestSessionObjectPosterResponse requester + = new RestSessionObjectPosterResponse(); + requester.ResponseCallback = InventoryResponse; - m_log.ErrorFormat("[OGS1 INVENTORY SERVICE]: Request inventory operation failed, {0} {1}", - e.Source, e.Message); - } + requester.BeginPostObject(_inventoryServerUrl + "/GetInventory/", userID.Guid, session_id.ToString(), userID.ToString()); } - else + catch (WebException e) { - m_log.ErrorFormat("[OGS1 INVENTORY SERVICE]: RequestInventoryForUser() - could you not find user profile for {0}", userID); + if (StatsManager.SimExtraStats != null) + StatsManager.SimExtraStats.AddInventoryServiceRetrievalFailure(); + + m_log.ErrorFormat("[OGS1 INVENTORY SERVICE]: Request inventory operation failed, {0} {1}", + e.Source, e.Message); } } @@ -107,60 +109,66 @@ namespace OpenSim.Region.Communications.OGS1 private void InventoryResponse(InventoryCollection response) { UUID userID = response.UserID; - if (m_RequestingInventory.ContainsKey(userID)) + InventoryReceiptCallback callback = null; + lock (m_RequestingInventory) { - m_log.InfoFormat("[OGS1 INVENTORY SERVICE]: " + - "Received inventory response for user {0} containing {1} folders and {2} items", - userID, response.Folders.Count, response.Items.Count); + if (m_RequestingInventory.ContainsKey(userID)) + { + callback = m_RequestingInventory[userID]; + m_RequestingInventory.Remove(userID); + } + else + { + m_log.WarnFormat( + "[OGS1 INVENTORY SERVICE]: " + + "Received inventory response for {0} for which we do not have a record of requesting!", + userID); + return; + } + } - InventoryFolderImpl rootFolder = null; - InventoryReceiptCallback callback = m_RequestingInventory[userID]; + m_log.InfoFormat("[OGS1 INVENTORY SERVICE]: " + + "Received inventory response for user {0} containing {1} folders and {2} items", + userID, response.Folders.Count, response.Items.Count); - ICollection folders = new List(); - ICollection items = new List(); + InventoryFolderImpl rootFolder = null; - foreach (InventoryFolderBase folder in response.Folders) + ICollection folders = new List(); + ICollection items = new List(); + + foreach (InventoryFolderBase folder in response.Folders) + { + if (folder.ParentID == UUID.Zero) { - if (folder.ParentID == UUID.Zero) - { - rootFolder = new InventoryFolderImpl(folder); - folders.Add(rootFolder); + rootFolder = new InventoryFolderImpl(folder); + folders.Add(rootFolder); - break; - } + break; } + } - if (rootFolder != null) + if (rootFolder != null) + { + foreach (InventoryFolderBase folder in response.Folders) { - foreach (InventoryFolderBase folder in response.Folders) + if (folder.ID != rootFolder.ID) { - if (folder.ID != rootFolder.ID) - { - folders.Add(new InventoryFolderImpl(folder)); - } - } - - foreach (InventoryItemBase item in response.Items) - { - items.Add(item); + folders.Add(new InventoryFolderImpl(folder)); } } - else + + foreach (InventoryItemBase item in response.Items) { - m_log.ErrorFormat("[OGS1 INVENTORY SERVICE]: Did not get back an inventory containing a root folder for user {0}", userID); + items.Add(item); } - - callback(folders, items); - - m_RequestingInventory.Remove(userID); } else { - m_log.WarnFormat( - "[OGS1 INVENTORY SERVICE]: " + - "Received inventory response for {0} for which we do not have a record of requesting!", - userID); + m_log.ErrorFormat("[OGS1 INVENTORY SERVICE]: Did not get back an inventory containing a root folder for user {0}", userID); } + + callback(folders, items); + } /// -- cgit v1.1