aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs')
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs169
1 files changed, 129 insertions, 40 deletions
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 2afe065..d510d82 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -251,57 +251,70 @@ namespace OpenSim.Region.CoreModules.Asset
251 251
252 private void UpdateFileCache(string key, AssetBase asset) 252 private void UpdateFileCache(string key, AssetBase asset)
253 { 253 {
254 string filename = GetFileName(asset.ID); 254 // TODO: Spawn this off to some seperate thread to do the actual writing
255 255 if (asset != null)
256 try
257 { 256 {
258 // If the file is already cached just update access time. 257 string filename = GetFileName(key);
259 if (File.Exists(filename)) 258
260 { 259 try
261 lock (m_CurrentlyWriting)
262 {
263 if (!m_CurrentlyWriting.Contains(filename))
264 File.SetLastAccessTime(filename, DateTime.Now);
265 }
266 }
267 else
268 { 260 {
269 // Once we start writing, make sure we flag that we're writing 261 // If the file is already cached, don't cache it, just touch it so access time is updated
270 // that object to the cache so that we don't try to write the 262 if (File.Exists(filename))
271 // same file multiple times.
272 lock (m_CurrentlyWriting)
273 { 263 {
274#if WAIT_ON_INPROGRESS_REQUESTS 264 // We don't really want to know about sharing
275 if (m_CurrentlyWriting.ContainsKey(filename)) 265 // violations here. If the file is locked, then
266 // the other thread has updated the time for us.
267 try
276 { 268 {
277 return; 269 lock (m_CurrentlyWriting)
270 {
271 if (!m_CurrentlyWriting.Contains(filename))
272 File.SetLastAccessTime(filename, DateTime.Now);
273 }
278 } 274 }
279 else 275 catch
280 {
281 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
282 }
283
284#else
285 if (m_CurrentlyWriting.Contains(filename))
286 { 276 {
287 return;
288 } 277 }
289 else 278 } else {
279
280 // Once we start writing, make sure we flag that we're writing
281 // that object to the cache so that we don't try to write the
282 // same file multiple times.
283 lock (m_CurrentlyWriting)
290 { 284 {
291 m_CurrentlyWriting.Add(filename); 285#if WAIT_ON_INPROGRESS_REQUESTS
292 } 286 if (m_CurrentlyWriting.ContainsKey(filename))
287 {
288 return;
289 }
290 else
291 {
292 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
293 }
294
295#else
296 if (m_CurrentlyWriting.Contains(filename))
297 {
298 return;
299 }
300 else
301 {
302 m_CurrentlyWriting.Add(filename);
303 }
293#endif 304#endif
294 }
295 305
296 Util.FireAndForget( 306 }
297 delegate { WriteFileCache(filename, asset); }); 307
308 Util.FireAndForget(
309 delegate { WriteFileCache(filename, asset); });
310 }
311 }
312 catch (Exception e)
313 {
314 m_log.ErrorFormat(
315 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
316 asset.ID, e.Message, e.StackTrace);
298 } 317 }
299 }
300 catch (Exception e)
301 {
302 m_log.WarnFormat(
303 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
304 asset.ID, e.Message, e.StackTrace);
305 } 318 }
306 } 319 }
307 320
@@ -335,6 +348,17 @@ namespace OpenSim.Region.CoreModules.Asset
335 return asset; 348 return asset;
336 } 349 }
337 350
351 private bool CheckFromMemoryCache(string id)
352 {
353 AssetBase asset = null;
354
355 if (m_MemoryCache.TryGetValue(id, out asset))
356 return true;
357
358 return false;
359 }
360
361
338 /// <summary> 362 /// <summary>
339 /// Try to get an asset from the file cache. 363 /// Try to get an asset from the file cache.
340 /// </summary> 364 /// </summary>
@@ -399,6 +423,7 @@ namespace OpenSim.Region.CoreModules.Asset
399 m_log.WarnFormat( 423 m_log.WarnFormat(
400 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", 424 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
401 filename, id, e.Message, e.StackTrace); 425 filename, id, e.Message, e.StackTrace);
426
402 } 427 }
403 finally 428 finally
404 { 429 {
@@ -410,6 +435,50 @@ namespace OpenSim.Region.CoreModules.Asset
410 return asset; 435 return asset;
411 } 436 }
412 437
438 private bool CheckFromFileCache(string id)
439 {
440 bool found = false;
441
442 string filename = GetFileName(id);
443 if (File.Exists(filename))
444 {
445 // actually check if we can open it, and so update expire
446 FileStream stream = null;
447 try
448 {
449 stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
450 if (stream != null)
451 {
452 found = true;
453 stream.Close();
454 }
455
456 }
457 catch (System.Runtime.Serialization.SerializationException e)
458 {
459 found = false;
460 m_log.ErrorFormat(
461 "[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}",
462 filename, id, e.Message, e.StackTrace);
463
464 // If there was a problem deserializing the asset, the asset may
465 // either be corrupted OR was serialized under an old format
466 // {different version of AssetBase} -- we should attempt to
467 // delete it and re-cache
468 File.Delete(filename);
469 }
470 catch (Exception e)
471 {
472 found = false;
473 m_log.ErrorFormat(
474 "[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}",
475 filename, id, e.Message, e.StackTrace);
476 }
477 }
478
479 return found;
480 }
481
413 public AssetBase Get(string id) 482 public AssetBase Get(string id)
414 { 483 {
415 m_Requests++; 484 m_Requests++;
@@ -446,11 +515,26 @@ namespace OpenSim.Region.CoreModules.Asset
446 return asset; 515 return asset;
447 } 516 }
448 517
518 public bool Check(string id)
519 {
520 if (m_MemoryCacheEnabled && CheckFromMemoryCache(id))
521 return true;
522
523 if (m_FileCacheEnabled && CheckFromFileCache(id))
524 return true;
525 return false;
526 }
527
449 public AssetBase GetCached(string id) 528 public AssetBase GetCached(string id)
450 { 529 {
451 return Get(id); 530 return Get(id);
452 } 531 }
453 532
533 public AssetBase CheckCached(string id)
534 {
535 return Get(id);
536 }
537
454 public void Expire(string id) 538 public void Expire(string id)
455 { 539 {
456 if (m_LogLevel >= 2) 540 if (m_LogLevel >= 2)
@@ -966,6 +1050,11 @@ namespace OpenSim.Region.CoreModules.Asset
966 return asset.Data; 1050 return asset.Data;
967 } 1051 }
968 1052
1053 public bool CheckData(string id)
1054 {
1055 return Check(id); ;
1056 }
1057
969 public bool Get(string id, object sender, AssetRetrieved handler) 1058 public bool Get(string id, object sender, AssetRetrieved handler)
970 { 1059 {
971 AssetBase asset = Get(id); 1060 AssetBase asset = Get(id);