aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/Communications/Cache/AssetCache.cs84
1 files changed, 51 insertions, 33 deletions
diff --git a/OpenSim/Framework/Communications/Cache/AssetCache.cs b/OpenSim/Framework/Communications/Cache/AssetCache.cs
index d04708d..3bd8f5b 100644
--- a/OpenSim/Framework/Communications/Cache/AssetCache.cs
+++ b/OpenSim/Framework/Communications/Cache/AssetCache.cs
@@ -53,29 +53,30 @@ namespace OpenSim.Framework.Communications.Cache
53 /// </summary> 53 /// </summary>
54 public class AssetCache : IAssetReceiver 54 public class AssetCache : IAssetReceiver
55 { 55 {
56 private static readonly log4net.ILog m_log 56 private static readonly log4net.ILog m_log
57 = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 57 = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
58 58
59 /// <summary> 59 /// <summary>
60 /// The cache of assets. This does not include textures. 60 /// The cache of assets. This does not include textures.
61 /// </summary> 61 /// </summary>
62 private Dictionary<LLUUID, AssetInfo> Assets; 62 private Dictionary<LLUUID, AssetInfo> Assets;
63 63
64 /// <summary> 64 /// <summary>
65 /// The cache of textures. 65 /// The cache of textures.
66 /// </summary> 66 /// </summary>
67 private Dictionary<LLUUID, TextureImage> Textures; 67 private Dictionary<LLUUID, TextureImage> Textures;
68 68
69 /// <summary> 69 ///
70 /// Assets requests which are waiting for asset server data. This includes texture requests 70 /// Assets requests which are waiting for asset server data. This includes texture requests
71 /// </summary> 71 /// </summary>
72 private Dictionary<LLUUID, AssetRequest> RequestedAssets; 72 private Dictionary<LLUUID, AssetRequest> RequestedAssets;
73 73
74 /// <summary> 74 /// <summary>
75 /// Asset requests with data which are ready to be sent back to requesters. This includes textures. 75 /// Asset requests with data which are ready to be sent back to requesters. This includes textures.
76 /// </summary> 76 /// </summary>
77 private List<AssetRequest> AssetRequests; 77 private List<AssetRequest> AssetRequests;
78 78
79
79 /// <summary> 80 /// <summary>
80 /// Until the asset request is fulfilled, each asset request is associated with a list of requesters 81 /// Until the asset request is fulfilled, each asset request is associated with a list of requesters
81 /// </summary> 82 /// </summary>
@@ -150,7 +151,7 @@ namespace OpenSim.Framework.Communications.Cache
150 Assets = new Dictionary<LLUUID, AssetInfo>(); 151 Assets = new Dictionary<LLUUID, AssetInfo>();
151 Textures = new Dictionary<LLUUID, TextureImage>(); 152 Textures = new Dictionary<LLUUID, TextureImage>();
152 AssetRequests = new List<AssetRequest>(); 153 AssetRequests = new List<AssetRequest>();
153 154
154 RequestedAssets = new Dictionary<LLUUID, AssetRequest>(); 155 RequestedAssets = new Dictionary<LLUUID, AssetRequest>();
155 RequestLists = new Dictionary<LLUUID, AssetRequestsList>(); 156 RequestLists = new Dictionary<LLUUID, AssetRequestsList>();
156 } 157 }
@@ -242,10 +243,10 @@ namespace OpenSim.Framework.Communications.Cache
242 /// If the asset was not found this is still called with the asset UUID but with a null asset data reference</param> 243 /// If the asset was not found this is still called with the asset UUID but with a null asset data reference</param>
243 public void GetAsset(LLUUID assetId, AssetRequestCallback callback, bool isTexture) 244 public void GetAsset(LLUUID assetId, AssetRequestCallback callback, bool isTexture)
244 { 245 {
245 #if DEBUG 246#if DEBUG
246 //m_log.DebugFormat("[ASSET CACHE]: Requesting {0} {1}", isTexture ? "texture" : "asset", assetId); 247 //m_log.DebugFormat("[ASSET CACHE]: Requesting {0} {1}", isTexture ? "texture" : "asset", assetId);
247 #endif 248#endif
248 249
249 AssetBase asset; 250 AssetBase asset;
250 251
251 if (TryGetCachedAsset(assetId, out asset)) 252 if (TryGetCachedAsset(assetId, out asset))
@@ -253,11 +254,11 @@ namespace OpenSim.Framework.Communications.Cache
253 callback(assetId, asset); 254 callback(assetId, asset);
254 } 255 }
255 else 256 else
256 { 257 {
257 #if DEBUG 258#if DEBUG
258 //m_log.DebugFormat("[ASSET CACHE]: Adding request for {0} {1}", isTexture ? "texture" : "asset", assetId); 259 //m_log.DebugFormat("[ASSET CACHE]: Adding request for {0} {1}", isTexture ? "texture" : "asset", assetId);
259 #endif 260#endif
260 261
261 NewAssetRequest req = new NewAssetRequest(assetId, callback); 262 NewAssetRequest req = new NewAssetRequest(assetId, callback);
262 263
263 // Make sure we always have a request list to which to add the asset 264 // Make sure we always have a request list to which to add the asset
@@ -277,7 +278,7 @@ namespace OpenSim.Framework.Communications.Cache
277 requestList.Requests.Add(req); 278 requestList.Requests.Add(req);
278 279
279 m_assetServer.RequestAsset(assetId, isTexture); 280 m_assetServer.RequestAsset(assetId, isTexture);
280 } 281 }
281 } 282 }
282 283
283 /// <summary> 284 /// <summary>
@@ -322,7 +323,7 @@ namespace OpenSim.Framework.Communications.Cache
322 } 323 }
323 } while (--maxPolls > 0); 324 } while (--maxPolls > 0);
324 325
325 m_log.WarnFormat("[ASSET CACHE]: {0} {1} was not received before the retrieval timeout was reached", 326 m_log.WarnFormat("[ASSET CACHE]: {0} {1} was not received before the retrieval timeout was reached",
326 isTexture ? "texture" : "asset", assetID.ToString()); 327 isTexture ? "texture" : "asset", assetID.ToString());
327 328
328 return null; 329 return null;
@@ -390,17 +391,17 @@ namespace OpenSim.Framework.Communications.Cache
390 } 391 }
391 } 392 }
392 } 393 }
393 #if DEBUG 394#if DEBUG
394 //m_log.DebugFormat("[ASSET CACHE]: Adding {0} {1} [{2}]: {3}.", temporary, type, asset.FullID, result); 395 //m_log.DebugFormat("[ASSET CACHE]: Adding {0} {1} [{2}]: {3}.", temporary, type, asset.FullID, result);
395 #endif 396#endif
396 } 397 }
397 398
398 // See IAssetReceiver 399 // See IAssetReceiver
399 public void AssetReceived(AssetBase asset, bool IsTexture) 400 public void AssetReceived(AssetBase asset, bool IsTexture)
400 { 401 {
401 #if DEBUG 402#if DEBUG
402 //m_log.DebugFormat("[ASSET CACHE]: Received {0} [{1}]", IsTexture ? "texture" : "asset", asset.FullID); 403 //m_log.DebugFormat("[ASSET CACHE]: Received {0} [{1}]", IsTexture ? "texture" : "asset", asset.FullID);
403 #endif 404#endif
404 405
405 if (asset.FullID != LLUUID.Zero) // if it is set to zero then the asset wasn't found by the server 406 if (asset.FullID != LLUUID.Zero) // if it is set to zero then the asset wasn't found by the server
406 { 407 {
@@ -414,9 +415,9 @@ namespace OpenSim.Framework.Communications.Cache
414 TextureImage image = new TextureImage(asset); 415 TextureImage image = new TextureImage(asset);
415 if (Textures.ContainsKey(image.FullID)) 416 if (Textures.ContainsKey(image.FullID))
416 { 417 {
417 #if DEBUG 418#if DEBUG
418 //m_log.DebugFormat("[ASSET CACHE]: There's already an texture {0} in memory. Skipping.", asset.FullID); 419 //m_log.DebugFormat("[ASSET CACHE]: There's already an texture {0} in memory. Skipping.", asset.FullID);
419 #endif 420#endif
420 } 421 }
421 else 422 else
422 { 423 {
@@ -433,9 +434,9 @@ namespace OpenSim.Framework.Communications.Cache
433 AssetInfo assetInf = new AssetInfo(asset); 434 AssetInfo assetInf = new AssetInfo(asset);
434 if (Assets.ContainsKey(assetInf.FullID)) 435 if (Assets.ContainsKey(assetInf.FullID))
435 { 436 {
436 #if DEBUG 437#if DEBUG
437 //m_log.DebugFormat("[ASSET CACHE]: There's already an asset {0} in memory. Skipping.", asset.FullID); 438 //m_log.DebugFormat("[ASSET CACHE]: There's already an asset {0} in memory. Skipping.", asset.FullID);
438 #endif 439#endif
439 } 440 }
440 else 441 else
441 { 442 {
@@ -448,9 +449,9 @@ namespace OpenSim.Framework.Communications.Cache
448 449
449 if (RequestedAssets.ContainsKey(assetInf.FullID)) 450 if (RequestedAssets.ContainsKey(assetInf.FullID))
450 { 451 {
451 #if DEBUG 452#if DEBUG
452 //m_log.DebugFormat("[ASSET CACHE]: Moving {0} from RequestedAssets to AssetRequests", asset.FullID); 453 //m_log.DebugFormat("[ASSET CACHE]: Moving {0} from RequestedAssets to AssetRequests", asset.FullID);
453 #endif 454#endif
454 455
455 AssetRequest req = RequestedAssets[assetInf.FullID]; 456 AssetRequest req = RequestedAssets[assetInf.FullID];
456 req.AssetInf = assetInf; 457 req.AssetInf = assetInf;
@@ -464,17 +465,34 @@ namespace OpenSim.Framework.Communications.Cache
464 465
465 // Notify requesters for this asset 466 // Notify requesters for this asset
466 if (RequestLists.ContainsKey(asset.FullID)) 467 if (RequestLists.ContainsKey(asset.FullID))
467 { 468 {
469 AssetRequestsList reqList = null;
468 lock (RequestLists) 470 lock (RequestLists)
469 { 471 {
470 AssetRequestsList reqList = RequestLists[asset.FullID]; 472 reqList = RequestLists[asset.FullID];
471 foreach (NewAssetRequest req in reqList.Requests) 473
474 }
475 if (reqList != null)
476 {
477 //making a copy of the list is not ideal
478 //but the old method of locking around this whole block of code was causing a multi-thread lock
479 //between this and the TextureDownloadModule
480 //while the localAsset thread running this and trying to send a texture to the callback in the
481 //texturedownloadmodule , and hitting a lock in there. While the texturedownload thread (which was holding
482 // the lock in the texturedownload module) was trying to
483 //request a new asset and hitting a lock in here on the RequestLists.
484 List<NewAssetRequest> theseRequests = new List<NewAssetRequest>(reqList.Requests);
485 reqList.Requests.Clear();
486
487 lock (RequestLists)
472 { 488 {
473 req.Callback(asset.FullID, asset); 489 RequestLists.Remove(asset.FullID);
474 } 490 }
475 491
476 RequestLists.Remove(asset.FullID); 492 foreach (NewAssetRequest req in theseRequests)
477 reqList.Requests.Clear(); 493 {
494 req.Callback(asset.FullID, asset);
495 }
478 } 496 }
479 } 497 }
480 } 498 }
@@ -484,7 +502,7 @@ namespace OpenSim.Framework.Communications.Cache
484 public void AssetNotFound(LLUUID assetID) 502 public void AssetNotFound(LLUUID assetID)
485 { 503 {
486 m_log.WarnFormat("[ASSET CACHE]: AssetNotFound for {0}", assetID); 504 m_log.WarnFormat("[ASSET CACHE]: AssetNotFound for {0}", assetID);
487 505
488 // Notify requesters for this asset 506 // Notify requesters for this asset
489 lock (RequestLists) 507 lock (RequestLists)
490 { 508 {
@@ -495,10 +513,10 @@ namespace OpenSim.Framework.Communications.Cache
495 { 513 {
496 req.Callback(assetID, null); 514 req.Callback(assetID, null);
497 } 515 }
498 516
499 RequestLists.Remove(assetID); 517 RequestLists.Remove(assetID);
500 } 518 }
501 } 519 }
502 } 520 }
503 521
504 /// <summary> 522 /// <summary>