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.
parent
b824e488ba
commit
8e08dd20dc
|
@ -77,10 +77,18 @@ namespace OpenSim.Region.Communications.Hypergrid
|
||||||
}
|
}
|
||||||
|
|
||||||
// grid/hypergrid mode
|
// grid/hypergrid mode
|
||||||
|
lock (m_RequestingInventory)
|
||||||
|
{
|
||||||
if (!m_RequestingInventory.ContainsKey(userID))
|
if (!m_RequestingInventory.ContainsKey(userID))
|
||||||
{
|
{
|
||||||
m_RequestingInventory.Add(userID, callback);
|
m_RequestingInventory.Add(userID, callback);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: RequestInventoryForUser() - could not find user profile for {0}", userID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
string invServer = GetUserInventoryURI(userID);
|
string invServer = GetUserInventoryURI(userID);
|
||||||
m_log.InfoFormat(
|
m_log.InfoFormat(
|
||||||
"[HGrid INVENTORY SERVICE]: Requesting inventory from {0}/GetInventory/ for user {1} ({2})",
|
"[HGrid INVENTORY SERVICE]: Requesting inventory from {0}/GetInventory/ for user {1} ({2})",
|
||||||
|
@ -118,12 +126,6 @@ namespace OpenSim.Region.Communications.Hypergrid
|
||||||
InventoryResponse(icol);
|
InventoryResponse(icol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: RequestInventoryForUser() - could not find user profile for {0}", userID);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private delegate InventoryCollection GetInventoryDelegate(string url, UUID userID, UUID sessionID);
|
private delegate InventoryCollection GetInventoryDelegate(string url, UUID userID, UUID sessionID);
|
||||||
|
|
||||||
|
@ -447,14 +449,28 @@ namespace OpenSim.Region.Communications.Hypergrid
|
||||||
private void InventoryResponse(InventoryCollection response)
|
private void InventoryResponse(InventoryCollection response)
|
||||||
{
|
{
|
||||||
UUID userID = response.UserID;
|
UUID userID = response.UserID;
|
||||||
|
InventoryReceiptCallback callback = null;
|
||||||
|
lock (m_RequestingInventory)
|
||||||
|
{
|
||||||
if (m_RequestingInventory.ContainsKey(userID))
|
if (m_RequestingInventory.ContainsKey(userID))
|
||||||
{
|
{
|
||||||
m_log.InfoFormat("[HGrid INVENTORY SERVICE]: " +
|
m_log.InfoFormat("[HGrid INVENTORY SERVICE]: " +
|
||||||
"Received inventory response for user {0} containing {1} folders and {2} items",
|
"Received inventory response for user {0} containing {1} folders and {2} items",
|
||||||
userID, response.Folders.Count, response.Items.Count);
|
userID, response.Folders.Count, response.Items.Count);
|
||||||
|
callback = m_RequestingInventory[userID];
|
||||||
|
m_RequestingInventory.Remove(userID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[HGrid INVENTORY SERVICE]: " +
|
||||||
|
"Received inventory response for {0} for which we do not have a record of requesting!",
|
||||||
|
userID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
InventoryFolderImpl rootFolder = null;
|
InventoryFolderImpl rootFolder = null;
|
||||||
InventoryReceiptCallback callback = m_RequestingInventory[userID];
|
|
||||||
|
|
||||||
ICollection<InventoryFolderImpl> folders = new List<InventoryFolderImpl>();
|
ICollection<InventoryFolderImpl> folders = new List<InventoryFolderImpl>();
|
||||||
ICollection<InventoryItemBase> items = new List<InventoryItemBase>();
|
ICollection<InventoryItemBase> items = new List<InventoryItemBase>();
|
||||||
|
@ -490,19 +506,9 @@ namespace OpenSim.Region.Communications.Hypergrid
|
||||||
m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Did not get back an inventory containing a root folder for user {0}", userID);
|
m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Did not get back an inventory containing a root folder for user {0}", userID);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_RequestingInventory.Remove(userID);
|
|
||||||
callback(folders, items);
|
callback(folders, items);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.WarnFormat(
|
|
||||||
"[HGrid INVENTORY SERVICE]: " +
|
|
||||||
"Received inventory response for {0} for which we do not have a record of requesting!",
|
|
||||||
userID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private bool IsLocalStandaloneUser(UUID userID)
|
private bool IsLocalStandaloneUser(UUID userID)
|
||||||
{
|
{
|
||||||
|
|
|
@ -69,9 +69,16 @@ namespace OpenSim.Region.Communications.OGS1
|
||||||
/// <param name="callback"></param>
|
/// <param name="callback"></param>
|
||||||
public void RequestInventoryForUser(UUID userID, UUID session_id, InventoryReceiptCallback callback)
|
public void RequestInventoryForUser(UUID userID, UUID session_id, InventoryReceiptCallback callback)
|
||||||
{
|
{
|
||||||
if (!m_RequestingInventory.ContainsKey(userID))
|
lock (m_RequestingInventory)
|
||||||
{
|
{
|
||||||
|
if (!m_RequestingInventory.ContainsKey(userID))
|
||||||
m_RequestingInventory.Add(userID, callback);
|
m_RequestingInventory.Add(userID, callback);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("[OGS1 INVENTORY SERVICE]: RequestInventoryForUser() - could you not find user profile for {0}", userID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -94,11 +101,6 @@ namespace OpenSim.Region.Communications.OGS1
|
||||||
e.Source, e.Message);
|
e.Source, e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[OGS1 INVENTORY SERVICE]: RequestInventoryForUser() - could you not find user profile for {0}", userID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Callback used by the inventory server GetInventory request
|
/// Callback used by the inventory server GetInventory request
|
||||||
|
@ -107,14 +109,29 @@ namespace OpenSim.Region.Communications.OGS1
|
||||||
private void InventoryResponse(InventoryCollection response)
|
private void InventoryResponse(InventoryCollection response)
|
||||||
{
|
{
|
||||||
UUID userID = response.UserID;
|
UUID userID = response.UserID;
|
||||||
|
InventoryReceiptCallback callback = null;
|
||||||
|
lock (m_RequestingInventory)
|
||||||
|
{
|
||||||
if (m_RequestingInventory.ContainsKey(userID))
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_log.InfoFormat("[OGS1 INVENTORY SERVICE]: " +
|
m_log.InfoFormat("[OGS1 INVENTORY SERVICE]: " +
|
||||||
"Received inventory response for user {0} containing {1} folders and {2} items",
|
"Received inventory response for user {0} containing {1} folders and {2} items",
|
||||||
userID, response.Folders.Count, response.Items.Count);
|
userID, response.Folders.Count, response.Items.Count);
|
||||||
|
|
||||||
InventoryFolderImpl rootFolder = null;
|
InventoryFolderImpl rootFolder = null;
|
||||||
InventoryReceiptCallback callback = m_RequestingInventory[userID];
|
|
||||||
|
|
||||||
ICollection<InventoryFolderImpl> folders = new List<InventoryFolderImpl>();
|
ICollection<InventoryFolderImpl> folders = new List<InventoryFolderImpl>();
|
||||||
ICollection<InventoryItemBase> items = new List<InventoryItemBase>();
|
ICollection<InventoryItemBase> items = new List<InventoryItemBase>();
|
||||||
|
@ -152,15 +169,6 @@ namespace OpenSim.Region.Communications.OGS1
|
||||||
|
|
||||||
callback(folders, items);
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
Loading…
Reference in New Issue