aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Communications/Cache
diff options
context:
space:
mode:
authorMW2008-02-27 14:40:30 +0000
committerMW2008-02-27 14:40:30 +0000
commita9ae5ab8405af5ce80ee060a387683b3044ca7b6 (patch)
treec58549555166f960602025792a3eeca02ea5de78 /OpenSim/Framework/Communications/Cache
parentUserService.ClearAgent call is no longer made when a childagent connection is... (diff)
downloadopensim-SC_OLD-a9ae5ab8405af5ce80ee060a387683b3044ca7b6.zip
opensim-SC_OLD-a9ae5ab8405af5ce80ee060a387683b3044ca7b6.tar.gz
opensim-SC_OLD-a9ae5ab8405af5ce80ee060a387683b3044ca7b6.tar.bz2
opensim-SC_OLD-a9ae5ab8405af5ce80ee060a387683b3044ca7b6.tar.xz
Hopefully fixed the bug that was causing a lot of the freezing. Which was happening due to locks in the AssetCache and Texturedownload module. Where the thread from the Asset thread would be take a lock on a list in the asset cache and then try to call the Callback into the texturedownload module and hit a lock in there which was held by a ClientView thread- which at the same time would be trying to request another texture from the cache and be hitting the lock in there held by the IClientAPI. The result each thread waiting for the other one to release a lock. And as one of those was the ClientView process packet thread. No more packets from that client could be processed. For now I've made a copy of the list in AssetCache so that it can release the lock. I'm doing more work on assets (moving the client asset downloading to a module ), so will hopefully change this into a better method once I've cleaned over things up a bit.
Diffstat (limited to 'OpenSim/Framework/Communications/Cache')
-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>