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.cs80
1 files changed, 53 insertions, 27 deletions
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index da39202..22c301b 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -357,8 +357,6 @@ namespace Flotsam.RegionModules.AssetCache
357 357
358 asset = (AssetBase)bformatter.Deserialize(stream); 358 asset = (AssetBase)bformatter.Deserialize(stream);
359 359
360 UpdateMemoryCache(id, asset);
361
362 m_DiskHits++; 360 m_DiskHits++;
363 } 361 }
364 catch (System.Runtime.Serialization.SerializationException e) 362 catch (System.Runtime.Serialization.SerializationException e)
@@ -419,9 +417,15 @@ namespace Flotsam.RegionModules.AssetCache
419 417
420 if (m_MemoryCacheEnabled) 418 if (m_MemoryCacheEnabled)
421 asset = GetFromMemoryCache(id); 419 asset = GetFromMemoryCache(id);
420
422 if (asset == null && m_FileCacheEnabled) 421 if (asset == null && m_FileCacheEnabled)
422 {
423 asset = GetFromFileCache(id); 423 asset = GetFromFileCache(id);
424 424
425 if (m_MemoryCacheEnabled && asset != null)
426 UpdateMemoryCache(id, asset);
427 }
428
425 if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0)) 429 if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0))
426 { 430 {
427 m_HitRateFile = (double)m_DiskHits / m_Requests * 100.0; 431 m_HitRateFile = (double)m_DiskHits / m_Requests * 100.0;
@@ -589,33 +593,59 @@ namespace Flotsam.RegionModules.AssetCache
589 593
590 try 594 try
591 { 595 {
592 if (!Directory.Exists(directory)) 596 try
593 { 597 {
594 Directory.CreateDirectory(directory); 598 if (!Directory.Exists(directory))
599 {
600 Directory.CreateDirectory(directory);
601 }
602
603 stream = File.Open(tempname, FileMode.Create);
604 BinaryFormatter bformatter = new BinaryFormatter();
605 bformatter.Serialize(stream, asset);
595 } 606 }
607 catch (IOException e)
608 {
609 m_log.ErrorFormat(
610 "[FLOTSAM ASSET CACHE]: Failed to write asset {0} to temporary location {1} (final {2}) on cache in {3}. Exception {4} {5}.",
611 asset.ID, tempname, filename, directory, e.Message, e.StackTrace);
596 612
597 stream = File.Open(tempname, FileMode.Create); 613 return;
598 BinaryFormatter bformatter = new BinaryFormatter(); 614 }
599 bformatter.Serialize(stream, asset); 615 finally
600 stream.Close(); 616 {
601 617 if (stream != null)
602 // Now that it's written, rename it so that it can be found. 618 stream.Close();
603 File.Move(tempname, filename); 619 }
604 620
605 if (m_LogLevel >= 2) 621 try
606 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Cache Stored :: {0}", asset.ID); 622 {
607 } 623 // Now that it's written, rename it so that it can be found.
608 catch (Exception e) 624 //
609 { 625 // File.Copy(tempname, filename, true);
610 m_log.ErrorFormat( 626 // File.Delete(tempname);
611 "[FLOTSAM ASSET CACHE]: Failed to write asset {0} to cache. Directory {1}, tempname {2}, filename {3}. Exception {4} {5}.", 627 //
612 asset.ID, directory, tempname, filename, e.Message, e.StackTrace); 628 // For a brief period, this was done as a separate copy and then temporary file delete operation to
629 // avoid an IOException caused by move if some competing thread had already written the file.
630 // However, this causes exceptions on Windows when other threads attempt to read a file
631 // which is still being copied. So instead, go back to moving the file and swallow any IOException.
632 //
633 // This situation occurs fairly rarely anyway. We assume in this that moves are atomic on the
634 // filesystem.
635 File.Move(tempname, filename);
636
637 if (m_LogLevel >= 2)
638 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Cache Stored :: {0}", asset.ID);
639 }
640 catch (IOException)
641 {
642 // If we see an IOException here it's likely that some other competing thread has written the
643 // cache file first, so ignore. Other IOException errors (e.g. filesystem full) should be
644 // signally by the earlier temporary file writing code.
645 }
613 } 646 }
614 finally 647 finally
615 { 648 {
616 if (stream != null)
617 stream.Close();
618
619 // Even if the write fails with an exception, we need to make sure 649 // Even if the write fails with an exception, we need to make sure
620 // that we release the lock on that file, otherwise it'll never get 650 // that we release the lock on that file, otherwise it'll never get
621 // cached 651 // cached
@@ -629,13 +659,9 @@ namespace Flotsam.RegionModules.AssetCache
629 waitEvent.Set(); 659 waitEvent.Set();
630 } 660 }
631#else 661#else
632 if (m_CurrentlyWriting.Contains(filename)) 662 m_CurrentlyWriting.Remove(filename);
633 {
634 m_CurrentlyWriting.Remove(filename);
635 }
636#endif 663#endif
637 } 664 }
638
639 } 665 }
640 } 666 }
641 667