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 08d4fc0..f1fee63 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -248,57 +248,70 @@ namespace OpenSim.Region.CoreModules.Asset
248 248
249 private void UpdateFileCache(string key, AssetBase asset) 249 private void UpdateFileCache(string key, AssetBase asset)
250 { 250 {
251 string filename = GetFileName(asset.ID); 251 // TODO: Spawn this off to some seperate thread to do the actual writing
252 252 if (asset != null)
253 try
254 { 253 {
255 // If the file is already cached just update access time. 254 string filename = GetFileName(key);
256 if (File.Exists(filename)) 255
257 { 256 try
258 lock (m_CurrentlyWriting)
259 {
260 if (!m_CurrentlyWriting.Contains(filename))
261 File.SetLastAccessTime(filename, DateTime.Now);
262 }
263 }
264 else
265 { 257 {
266 // Once we start writing, make sure we flag that we're writing 258 // If the file is already cached, don't cache it, just touch it so access time is updated
267 // that object to the cache so that we don't try to write the 259 if (File.Exists(filename))
268 // same file multiple times.
269 lock (m_CurrentlyWriting)
270 { 260 {
271#if WAIT_ON_INPROGRESS_REQUESTS 261 // We don't really want to know about sharing
272 if (m_CurrentlyWriting.ContainsKey(filename)) 262 // violations here. If the file is locked, then
263 // the other thread has updated the time for us.
264 try
273 { 265 {
274 return; 266 lock (m_CurrentlyWriting)
267 {
268 if (!m_CurrentlyWriting.Contains(filename))
269 File.SetLastAccessTime(filename, DateTime.Now);
270 }
275 } 271 }
276 else 272 catch
277 {
278 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
279 }
280
281#else
282 if (m_CurrentlyWriting.Contains(filename))
283 { 273 {
284 return;
285 } 274 }
286 else 275 } else {
276
277 // Once we start writing, make sure we flag that we're writing
278 // that object to the cache so that we don't try to write the
279 // same file multiple times.
280 lock (m_CurrentlyWriting)
287 { 281 {
288 m_CurrentlyWriting.Add(filename); 282#if WAIT_ON_INPROGRESS_REQUESTS
289 } 283 if (m_CurrentlyWriting.ContainsKey(filename))
284 {
285 return;
286 }
287 else
288 {
289 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
290 }
291
292#else
293 if (m_CurrentlyWriting.Contains(filename))
294 {
295 return;
296 }
297 else
298 {
299 m_CurrentlyWriting.Add(filename);
300 }
290#endif 301#endif
291 }
292 302
293 Util.FireAndForget( 303 }
294 delegate { WriteFileCache(filename, asset); }); 304
305 Util.FireAndForget(
306 delegate { WriteFileCache(filename, asset); });
307 }
308 }
309 catch (Exception e)
310 {
311 m_log.ErrorFormat(
312 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
313 asset.ID, e.Message, e.StackTrace);
295 } 314 }
296 }
297 catch (Exception e)
298 {
299 m_log.WarnFormat(
300 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
301 asset.ID, e.Message, e.StackTrace);
302 } 315 }
303 } 316 }
304 317
@@ -332,6 +345,17 @@ namespace OpenSim.Region.CoreModules.Asset
332 return asset; 345 return asset;
333 } 346 }
334 347
348 private bool CheckFromMemoryCache(string id)
349 {
350 AssetBase asset = null;
351
352 if (m_MemoryCache.TryGetValue(id, out asset))
353 return true;
354
355 return false;
356 }
357
358
335 /// <summary> 359 /// <summary>
336 /// Try to get an asset from the file cache. 360 /// Try to get an asset from the file cache.
337 /// </summary> 361 /// </summary>
@@ -396,6 +420,7 @@ namespace OpenSim.Region.CoreModules.Asset
396 m_log.WarnFormat( 420 m_log.WarnFormat(
397 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", 421 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
398 filename, id, e.Message, e.StackTrace); 422 filename, id, e.Message, e.StackTrace);
423
399 } 424 }
400 finally 425 finally
401 { 426 {
@@ -407,6 +432,50 @@ namespace OpenSim.Region.CoreModules.Asset
407 return asset; 432 return asset;
408 } 433 }
409 434
435 private bool CheckFromFileCache(string id)
436 {
437 bool found = false;
438
439 string filename = GetFileName(id);
440 if (File.Exists(filename))
441 {
442 // actually check if we can open it, and so update expire
443 FileStream stream = null;
444 try
445 {
446 stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
447 if (stream != null)
448 {
449 found = true;
450 stream.Close();
451 }
452
453 }
454 catch (System.Runtime.Serialization.SerializationException e)
455 {
456 found = false;
457 m_log.ErrorFormat(
458 "[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}",
459 filename, id, e.Message, e.StackTrace);
460
461 // If there was a problem deserializing the asset, the asset may
462 // either be corrupted OR was serialized under an old format
463 // {different version of AssetBase} -- we should attempt to
464 // delete it and re-cache
465 File.Delete(filename);
466 }
467 catch (Exception e)
468 {
469 found = false;
470 m_log.ErrorFormat(
471 "[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}",
472 filename, id, e.Message, e.StackTrace);
473 }
474 }
475
476 return found;
477 }
478
410 public AssetBase Get(string id) 479 public AssetBase Get(string id)
411 { 480 {
412 m_Requests++; 481 m_Requests++;
@@ -434,11 +503,26 @@ namespace OpenSim.Region.CoreModules.Asset
434 return asset; 503 return asset;
435 } 504 }
436 505
506 public bool Check(string id)
507 {
508 if (m_MemoryCacheEnabled && CheckFromMemoryCache(id))
509 return true;
510
511 if (m_FileCacheEnabled && CheckFromFileCache(id))
512 return true;
513 return false;
514 }
515
437 public AssetBase GetCached(string id) 516 public AssetBase GetCached(string id)
438 { 517 {
439 return Get(id); 518 return Get(id);
440 } 519 }
441 520
521 public AssetBase CheckCached(string id)
522 {
523 return Get(id);
524 }
525
442 public void Expire(string id) 526 public void Expire(string id)
443 { 527 {
444 if (m_LogLevel >= 2) 528 if (m_LogLevel >= 2)
@@ -983,6 +1067,11 @@ namespace OpenSim.Region.CoreModules.Asset
983 return asset.Data; 1067 return asset.Data;
984 } 1068 }
985 1069
1070 public bool CheckData(string id)
1071 {
1072 return Check(id); ;
1073 }
1074
986 public bool Get(string id, object sender, AssetRetrieved handler) 1075 public bool Get(string id, object sender, AssetRetrieved handler)
987 { 1076 {
988 AssetBase asset = Get(id); 1077 AssetBase asset = Get(id);