When an uncached asset is requested multiple times concurrently, only load it once
Signed-off-by: root <root@grid00001.t-data.com>bulletsim
parent
56830bfe07
commit
71ef4a8fb3
|
@ -48,6 +48,13 @@ namespace OpenSim.Services.Connectors
|
|||
private string m_ServerURI = String.Empty;
|
||||
private IImprovedAssetCache m_Cache = null;
|
||||
|
||||
private delegate void AssetRetrievedEx(AssetBase asset);
|
||||
|
||||
// Keeps track of concurrent requests for the same asset, so that it's only loaded once.
|
||||
// Maps: Asset ID -> Handlers which will be called when the asset has been loaded
|
||||
private Dictionary<string, AssetRetrievedEx> m_AssetHandlers = new Dictionary<string, AssetRetrievedEx>();
|
||||
|
||||
|
||||
public AssetServicesConnector()
|
||||
{
|
||||
}
|
||||
|
@ -178,23 +185,56 @@ namespace OpenSim.Services.Connectors
|
|||
|
||||
if (asset == null)
|
||||
{
|
||||
bool result = false;
|
||||
lock (m_AssetHandlers)
|
||||
{
|
||||
AssetRetrievedEx handlerEx = new AssetRetrievedEx(delegate(AssetBase _asset) { handler(id, sender, _asset); });
|
||||
|
||||
AsynchronousRestObjectRequester.
|
||||
MakeRequest<int, AssetBase>("GET", uri, 0,
|
||||
AssetRetrievedEx handlers;
|
||||
if (m_AssetHandlers.TryGetValue(id, out handlers))
|
||||
{
|
||||
// Someone else is already loading this asset. It will notify our handler when done.
|
||||
handlers += handlerEx;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Load the asset ourselves
|
||||
handlers += handlerEx;
|
||||
m_AssetHandlers.Add(id, handlers);
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
try
|
||||
{
|
||||
AsynchronousRestObjectRequester.MakeRequest<int, AssetBase>("GET", uri, 0,
|
||||
delegate(AssetBase a)
|
||||
{
|
||||
if (m_Cache != null)
|
||||
m_Cache.Cache(a);
|
||||
handler(id, sender, a);
|
||||
result = true;
|
||||
|
||||
AssetRetrievedEx handlers;
|
||||
lock (m_AssetHandlers)
|
||||
{
|
||||
handlers = m_AssetHandlers[id];
|
||||
m_AssetHandlers.Remove(id);
|
||||
}
|
||||
handlers.Invoke(a);
|
||||
});
|
||||
|
||||
return result;
|
||||
success = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
lock (m_AssetHandlers)
|
||||
{
|
||||
m_AssetHandlers.Remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Util.FireAndForget(delegate { handler(id, sender, asset); });
|
||||
handler(id, sender, asset);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue