Author: gonzalo
Date: 2005-04-28 00:01:16 -0400 (Thu, 28 Apr 2005)
New Revision: 43705

Modified:
   trunk/mcs/class/System.Web/System.Web.Caching/Cache.cs
   trunk/mcs/class/System.Web/System.Web.Caching/CacheExpires.cs
   trunk/mcs/class/System.Web/System.Web.Caching/ChangeLog
   trunk/mcs/class/System.Web/System.Web.Caching/ExpiresBuckets.cs
Log:
2005-04-28 Gonzalo Paniagua Javier <[EMAIL PROTECTED]>

        * ExpiresBuckets.cs:
        * Cache.cs:
        * CacheExpires.cs: fix NullReferenceException thrown sometimes when
        using sliding expiration and under high load. Patch by Eyal Alayuf from
        Mainsoft.



Modified: trunk/mcs/class/System.Web/System.Web.Caching/Cache.cs
===================================================================
--- trunk/mcs/class/System.Web/System.Web.Caching/Cache.cs      2005-04-28 
03:56:38 UTC (rev 43704)
+++ trunk/mcs/class/System.Web/System.Web.Caching/Cache.cs      2005-04-28 
04:01:16 UTC (rev 43705)
@@ -182,10 +182,9 @@
                                                                                
pub,
                                                                                
enumPriority);
 
-                       Interlocked.Increment (ref _nItems);
-
                        _lockEntries.AcquireWriterLock (-1);
                        try {
+                               _nItems++;
                                if (_arrEntries.Contains (strKey)) {
                                        if (overwrite)
                                                objOldEntry = _arrEntries 
[strKey] as CacheEntry;
@@ -195,6 +194,16 @@
                                
                                objEntry.Hit ();
                                _arrEntries [strKey] = objEntry;
+
+                               // If we have any kind of expiration add into 
the CacheExpires
+                               // Do this under the lock so no-one can 
retrieve the objEntry
+                               // before it is fully initialized.
+                               if (objEntry.HasSlidingExpiration || 
objEntry.HasAbsoluteExpiration) {
+                                       if (objEntry.HasSlidingExpiration)
+                                               objEntry.Expires = 
DateTime.UtcNow.Ticks + objEntry.SlidingExpiration;
+
+                                       _objExpires.Add (objEntry);
+                               }
                        } finally {
                                _lockEntries.ReleaseLock ();
                        }
@@ -206,14 +215,6 @@
                                objOldEntry.Close 
(CacheItemRemovedReason.Removed);
                        }
 
-                       // If we have any kind of expiration add into the 
CacheExpires class
-                       if (objEntry.HasSlidingExpiration || 
objEntry.HasAbsoluteExpiration) {
-                               if (objEntry.HasSlidingExpiration)
-                                       objEntry.Expires = 
DateTime.UtcNow.Ticks + objEntry.SlidingExpiration;
-
-                               _objExpires.Add (objEntry);
-                       }
-
                        return objEntry.Item;
                }
                
@@ -361,6 +362,7 @@
                                        return null;
 
                                _arrEntries.Remove (strKey);
+                               _nItems--;
                        }
                        finally {
                                _lockEntries.ReleaseWriterLock ();
@@ -370,9 +372,6 @@
                                _objExpires.Remove (objEntry);
 
                        objEntry.Close (enumReason);
-
-                       Interlocked.Decrement (ref _nItems);
-
                        return objEntry.Item;
                }
 
@@ -416,10 +415,7 @@
 
                        objEntry.Hit ();
                        if (objEntry.HasSlidingExpiration) {
-                               long ticksExpires = ticksNow + 
objEntry.SlidingExpiration;
-
-                               _objExpires.Update (objEntry, ticksExpires);
-                               objEntry.Expires = ticksExpires;
+                               objEntry.Expires = ticksNow + 
objEntry.SlidingExpiration;
                        }
 
                        return objEntry;

Modified: trunk/mcs/class/System.Web/System.Web.Caching/CacheExpires.cs
===================================================================
--- trunk/mcs/class/System.Web/System.Web.Caching/CacheExpires.cs       
2005-04-28 03:56:38 UTC (rev 43704)
+++ trunk/mcs/class/System.Web/System.Web.Caching/CacheExpires.cs       
2005-04-28 04:01:16 UTC (rev 43705)
@@ -92,23 +92,6 @@
                                _arrBuckets [objEntry.ExpiresBucket].Remove 
(objEntry);
                }
 
-               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) {
                        int bucket;
 

Modified: trunk/mcs/class/System.Web/System.Web.Caching/ChangeLog
===================================================================
--- trunk/mcs/class/System.Web/System.Web.Caching/ChangeLog     2005-04-28 
03:56:38 UTC (rev 43704)
+++ trunk/mcs/class/System.Web/System.Web.Caching/ChangeLog     2005-04-28 
04:01:16 UTC (rev 43705)
@@ -1,3 +1,11 @@
+2005-04-28 Gonzalo Paniagua Javier <[EMAIL PROTECTED]>
+
+       * ExpiresBuckets.cs:
+       * Cache.cs:
+       * CacheExpires.cs: fix NullReferenceException thrown sometimes when
+       using sliding expiration and under high load. Patch by Eyal Alayuf from
+       Mainsoft.
+
 2005-04-20 Gonzalo Paniagua Javier <[EMAIL PROTECTED]>
 
        * CacheDependency.cs: remove warnings.

Modified: trunk/mcs/class/System.Web/System.Web.Caching/ExpiresBuckets.cs
===================================================================
--- trunk/mcs/class/System.Web/System.Web.Caching/ExpiresBuckets.cs     
2005-04-28 03:56:38 UTC (rev 43704)
+++ trunk/mcs/class/System.Web/System.Web.Caching/ExpiresBuckets.cs     
2005-04-28 04:01:16 UTC (rev 43705)
@@ -88,8 +88,6 @@
                        int intPos = 0;
                        do {
                                _arrEntries[intPos]._intNext = intPos + 1;
-                               _arrEntries[intPos].TicksExpires = 
Cache.NoAbsoluteExpiration.Ticks;
-                               
                                intPos++;
                        } while (intPos < _intSize);
 
@@ -116,7 +114,6 @@
                                // Initialize positions for the rest of new 
elements.
                                for (int i = oldsize; i < _intSize; i++) {
                                        newlist[i]._intNext = i + 1;
-                                       newlist[i].TicksExpires = 
Cache.NoAbsoluteExpiration.Ticks;
                                }
 
                                // Last item signals the expansion of the list.
@@ -147,7 +144,6 @@
                                        }
                                }
                        
-                               _arrEntries[_intNext].TicksExpires = 
objEntry.Expires;
                                _arrEntries[_intNext].Entry = objEntry;
 
                                objEntry.ExpiresBucket = _byteID;
@@ -172,13 +168,11 @@
                /// </summary>
                /// <param name="objEntry">Cache entry to be removed.</param>
                internal void Remove(CacheEntry objEntry) {
-                       // Check if this is our bucket
-                       if (objEntry.ExpiresBucket != _byteID) return;
-                       if (objEntry.ExpiresIndex == 
CacheEntry.NoIndexInBucket) return;
-
                        _lock.AcquireWriterLock(-1);
                        try {
-                               if (_arrEntries.Length < objEntry.ExpiresIndex) 
return;
+                               if (objEntry.ExpiresIndex == 
CacheEntry.NoIndexInBucket)
+                                       return;
+
                                _intCount--;
 
                                // Push the index as a free one.
@@ -196,32 +190,6 @@
                }
 
                /// <summary>
-               /// Updates a cache entry in the expires bucket, this is called 
during a hit of an item if the 
-               /// cache item has a sliding expiration. The function is 
responsible for updating the cache
-               /// entry.
-               /// </summary>
-               /// <param name="objEntry">Cache entry to update.</param>
-               /// <param name="ticksExpires">New expiration value for the 
cache entry.</param>
-               internal void Update(CacheEntry objEntry, long ticksExpires) {
-                       // Check if this is our bucket
-                       if (objEntry.ExpiresBucket != _byteID) return;
-                       if (objEntry.ExpiresIndex == 
CacheEntry.NoIndexInBucket) return;
-
-                       _lock.AcquireWriterLock(-1);
-                       try {
-                               if (_arrEntries.Length < objEntry.ExpiresIndex) 
return;
-
-                               // Proceed to update.
-                               _arrEntries[objEntry.ExpiresIndex].TicksExpires 
= ticksExpires;
-                               
_arrEntries[objEntry.ExpiresIndex].Entry.Expires = ticksExpires;
-                       }
-                       finally {
-                               //Releases both read & write locks
-                               _lock.ReleaseWriterLock();
-                       }
-               }
-
-               /// <summary>
                /// Flushes all cache entries that has expired and removes them 
from the cache manager.
                /// </summary>
                internal void FlushExpiredItems() {
@@ -241,7 +209,7 @@
                                do {
                                        objEntry = _arrEntries [intPos];
                                        if (null != objEntry.Entry && 
-                                               ((objEntry.TicksExpires < 
ticksNow) || objEntry.Entry.ExpiresBucket != _byteID))
+                                               ((objEntry.Entry.Expires < 
ticksNow) || objEntry.Entry.ExpiresBucket != _byteID))
                                        {
                                                if (null == removeList)
                                                        removeList = new 
ArrayList ();
@@ -264,7 +232,9 @@
                                        foreach (ExpiresEntry entry in 
removeList) { 
                                                ExpiresEntry e = entry;
                                                int id = 
entry.Entry.ExpiresIndex;
-
+                                               if (id == 
CacheEntry.NoIndexInBucket)
+                                                       continue;
+
                                                //push the index for reuse
                                                _freeidx.Add (id);
 
@@ -657,4 +627,4 @@
                #endregion
        }
 }
-       
\ No newline at end of file
+

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to