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