Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrik Torstensson <totte@mono-cvs.ximian.com>2004-05-27 16:15:13 +0400
committerPatrik Torstensson <totte@mono-cvs.ximian.com>2004-05-27 16:15:13 +0400
commita596fe49993ed0af78a86232bd09ed52861ec21e (patch)
tree23ab307448807f0d21bbef76ccdce398dbb5d231 /mcs/class/System.Web/System.Web.Caching/CacheExpires.cs
parent78cde011042142a1c921df9ca58c84089aa57bb4 (diff)
2004-05-27 Patrik Torstensson <totte@hiddenpeaks.com>
* CacheEntry.cs,CacheExpires.cs,ExpiresBucket.cs, Cache.cs : Fixed deadlock issues, fixed items not correctly being flushed, fixed update of item when expiration has been updated more than 1 min (placed in wrong bucket), fixed deadlock during cache callback when item is removed due to expiriation. Rewrite of locking handling in Cache class, leading to better performance and less bugs. This rewrite is due to a number of bugs found in the output caching during load (leading to memory leaks and deadlocks) svn path=/trunk/mcs/; revision=28254
Diffstat (limited to 'mcs/class/System.Web/System.Web.Caching/CacheExpires.cs')
-rw-r--r--mcs/class/System.Web/System.Web.Caching/CacheExpires.cs139
1 files changed, 56 insertions, 83 deletions
diff --git a/mcs/class/System.Web/System.Web.Caching/CacheExpires.cs b/mcs/class/System.Web/System.Web.Caching/CacheExpires.cs
index 639be6efa99..bdc4748a5a8 100644
--- a/mcs/class/System.Web/System.Web.Caching/CacheExpires.cs
+++ b/mcs/class/System.Web/System.Web.Caching/CacheExpires.cs
@@ -2,22 +2,22 @@
// System.Web.Caching
//
// Author:
-// Patrik Torstensson (Patrik.Torstensson@labs2.com)
-// Changes:
-// Daniel Cazzulino [DHC] (dcazzulino@users.sf.net)
+// Patrik Torstensson
+// Daniel Cazzulino (dcazzulino@users.sf.net)
//
-// (C) Copyright Patrik Torstensson, 2001
-//
-namespace System.Web.Caching
-{
+
+using System;
+using System.Collections;
+using System.Threading;
+
+namespace System.Web.Caching {
/// <summary>
/// Class responsible for handling time based flushing of entries in the cache. The class creates
/// and manages 60 buckets each holding every item that expires that minute. The bucket calculated
/// for an entry is one minute more than the timeout just to make sure that the item end up in the
/// bucket where it should be flushed.
/// </summary>
- internal class CacheExpires : System.IDisposable
- {
+ internal class CacheExpires : IDisposable {
static int _intFlush;
/// <summary>
/// 1 bucket == 1 minute == 10M ticks (1 second) * 60
@@ -29,101 +29,79 @@ namespace System.Web.Caching
static long _ticksPerCycle = _ticksPerBucket * 60;
private ExpiresBucket[] _arrBuckets;
- private System.Threading.Timer _objTimer;
+ private Timer _objTimer;
private Cache _objManager;
- /// <summary>
- /// Constructor
- /// </summary>
- /// <param name="objManager">The cache manager, used when flushing items in a bucket.</param>
- internal CacheExpires(Cache objManager)
- {
+ private object _lockObj = new object ();
+
+ internal CacheExpires (Cache objManager) {
_objManager = objManager;
Initialize();
}
- /// <summary>
- /// Initializes the class.
- /// </summary>
- private void Initialize()
- {
+ private void Initialize () {
// Create one bucket per minute
- _arrBuckets = new ExpiresBucket[60];
+ _arrBuckets = new ExpiresBucket [60];
byte bytePos = 0;
- do
- {
- _arrBuckets[bytePos] = new ExpiresBucket(bytePos, _objManager);
+ do {
+ _arrBuckets [bytePos] = new ExpiresBucket (bytePos, _objManager);
bytePos++;
} while (bytePos < 60);
// GC Bucket controller
_intFlush = System.DateTime.Now.Minute - 1;
- _objTimer = new System.Threading.Timer(new System.Threading.TimerCallback(GarbageCleanup), null, 10000, 60000);
+ _objTimer = new System.Threading.Timer (new System.Threading.TimerCallback (GarbageCleanup), null, 10000, 60000);
}
/// <summary>
/// Adds a Cache entry to the correct flush bucket.
/// </summary>
/// <param name="objEntry">Cache entry to add.</param>
- internal void Add (CacheEntry objEntry)
- {
- lock(this)
- {
- // If the entry doesn't have a expires time we assume that the entry is due to expire now.
- if (objEntry.Expires == 0)
- {
- objEntry.Expires = System.DateTime.Now.Ticks;
- }
-
- _arrBuckets[GetHashBucket(objEntry.Expires)].Add(objEntry);
- }
+ internal void Add (CacheEntry objEntry) {
+ long now = DateTime.Now.Ticks;
+ if (objEntry.Expires < now)
+ objEntry.Expires = now;
+
+ _arrBuckets [GetHashBucket (objEntry.Expires)].Add (objEntry);
}
- internal void Remove(CacheEntry objEntry)
- {
- lock(this)
- {
- // If the entry doesn't have a expires time we assume that the entry is due to expire now.
- if (objEntry.Expires == 0)
- {
- objEntry.Expires = System.DateTime.Now.Ticks;
- }
-
- _arrBuckets[GetHashBucket(objEntry.Expires)].Remove(objEntry);
- }
+ internal void Remove (CacheEntry objEntry) {
+ if (objEntry.ExpiresBucket != CacheEntry.NoBucketHash)
+ _arrBuckets [objEntry.ExpiresBucket].Remove (objEntry);
}
- internal void Update(CacheEntry objEntry, long ticksExpires)
- {
- lock(this)
- {
- // If the entry doesn't have a expires time we assume that the entry is due to expire now.
- if (objEntry.Expires == 0)
- {
- objEntry.Expires = System.DateTime.Now.Ticks;
- }
-
- _arrBuckets[GetHashBucket(objEntry.Expires)].Update(objEntry, ticksExpires);
- }
+ internal void Update (CacheEntry objEntry, long ticksExpires) {
+ // If the entry doesn't have a expires time we assume that the entry is due to expire now.
+ int oldBucket = objEntry.ExpiresBucket;
+ int newBucket = GetHashBucket (ticksExpires);
+
+ if (oldBucket == CacheEntry.NoBucketHash)
+ return;
+
+ // Check if we need to move the item
+ if (oldBucket != newBucket) {
+ _arrBuckets [oldBucket].Remove (objEntry);
+ objEntry.Expires = ticksExpires;
+ _arrBuckets [newBucket].Add (objEntry);
+ } else
+ _arrBuckets [oldBucket].Update (objEntry, ticksExpires);
}
- internal void GarbageCleanup(object State)
- {
- ExpiresBucket objBucket;
+ internal void GarbageCleanup (object State) {
+ ExpiresBucket objBucket;
+ int bucket;
- lock(this)
- {
- // Do cleanup of the bucket
- objBucket = _arrBuckets[(++_intFlush) % 60];
- }
+ // We lock here if FlushExpiredItems take time
+ lock (_lockObj) {
+ bucket = (++_intFlush) % 60;
+ }
// Flush expired items in the current bucket (defined by _intFlush)
- objBucket.FlushExpiredItems();
+ _arrBuckets [bucket].FlushExpiredItems ();
}
- private int GetHashBucket(long ticks)
- {
+ private int GetHashBucket (long ticks) {
// Get bucket to add expire item into, add one minute to the bucket just to make sure that we get it in the bucket gc
return (int) (((((ticks + 60000) % _ticksPerCycle) / _ticksPerBucket) + 1) % 60);
}
@@ -131,16 +109,11 @@ namespace System.Web.Caching
/// <summary>
/// Called by the cache for cleanup.
/// </summary>
- public void Dispose()
- {
- lock(this)
- {
- // Cleanup the internal timer
- if (_objTimer != null)
- {
- _objTimer.Dispose();
- _objTimer = null;
- }
+ public void Dispose () {
+ // Cleanup the internal timer
+ if (_objTimer != null) {
+ _objTimer.Dispose();
+ _objTimer = null;
}
}
}