aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorOren Hurvitz2011-07-18 12:32:32 +0300
committerroot2011-07-21 20:52:56 +0100
commit71ef4a8fb3f582ee76ceb1ec613b32ad2e4bc058 (patch)
treec9b37d49870555721c08fcdf010cd939f5f8f98c /OpenSim
parentWhen handling SetAppearance packet, always save the appearance; not only if t... (diff)
downloadopensim-SC-71ef4a8fb3f582ee76ceb1ec613b32ad2e4bc058.zip
opensim-SC-71ef4a8fb3f582ee76ceb1ec613b32ad2e4bc058.tar.gz
opensim-SC-71ef4a8fb3f582ee76ceb1ec613b32ad2e4bc058.tar.bz2
opensim-SC-71ef4a8fb3f582ee76ceb1ec613b32ad2e4bc058.tar.xz
When an uncached asset is requested multiple times concurrently, only load it once
Signed-off-by: root <root@grid00001.t-data.com>
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs58
1 files changed, 49 insertions, 9 deletions
diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
index f1da4fa..fdab254 100644
--- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
@@ -48,6 +48,13 @@ namespace OpenSim.Services.Connectors
48 private string m_ServerURI = String.Empty; 48 private string m_ServerURI = String.Empty;
49 private IImprovedAssetCache m_Cache = null; 49 private IImprovedAssetCache m_Cache = null;
50 50
51 private delegate void AssetRetrievedEx(AssetBase asset);
52
53 // Keeps track of concurrent requests for the same asset, so that it's only loaded once.
54 // Maps: Asset ID -> Handlers which will be called when the asset has been loaded
55 private Dictionary<string, AssetRetrievedEx> m_AssetHandlers = new Dictionary<string, AssetRetrievedEx>();
56
57
51 public AssetServicesConnector() 58 public AssetServicesConnector()
52 { 59 {
53 } 60 }
@@ -178,23 +185,56 @@ namespace OpenSim.Services.Connectors
178 185
179 if (asset == null) 186 if (asset == null)
180 { 187 {
181 bool result = false; 188 lock (m_AssetHandlers)
182 189 {
183 AsynchronousRestObjectRequester. 190 AssetRetrievedEx handlerEx = new AssetRetrievedEx(delegate(AssetBase _asset) { handler(id, sender, _asset); });
184 MakeRequest<int, AssetBase>("GET", uri, 0, 191
192 AssetRetrievedEx handlers;
193 if (m_AssetHandlers.TryGetValue(id, out handlers))
194 {
195 // Someone else is already loading this asset. It will notify our handler when done.
196 handlers += handlerEx;
197 return true;
198 }
199
200 // Load the asset ourselves
201 handlers += handlerEx;
202 m_AssetHandlers.Add(id, handlers);
203 }
204
205 bool success = false;
206 try
207 {
208 AsynchronousRestObjectRequester.MakeRequest<int, AssetBase>("GET", uri, 0,
185 delegate(AssetBase a) 209 delegate(AssetBase a)
186 { 210 {
187 if (m_Cache != null) 211 if (m_Cache != null)
188 m_Cache.Cache(a); 212 m_Cache.Cache(a);
189 handler(id, sender, a);
190 result = true;
191 });
192 213
193 return result; 214 AssetRetrievedEx handlers;
215 lock (m_AssetHandlers)
216 {
217 handlers = m_AssetHandlers[id];
218 m_AssetHandlers.Remove(id);
219 }
220 handlers.Invoke(a);
221 });
222
223 success = true;
224 }
225 finally
226 {
227 if (!success)
228 {
229 lock (m_AssetHandlers)
230 {
231 m_AssetHandlers.Remove(id);
232 }
233 }
234 }
194 } 235 }
195 else 236 else
196 { 237 {
197 //Util.FireAndForget(delegate { handler(id, sender, asset); });
198 handler(id, sender, asset); 238 handler(id, sender, asset);
199 } 239 }
200 240