changes on expiringkey, add expiringcacheOS, alternative to libomv on (no slide expire option)
changes on expiringkey, add expiringcacheOS, alternative to libomv on (no slide expire option)
diff --git a/OpenSim/Framework/ExpiringKey.cs b/OpenSim/Framework/ExpiringKey.cs
index 27f64a8..ac02a67 100644
--- a/OpenSim/Framework/ExpiringKey.cs
+++ b/OpenSim/Framework/ExpiringKey.cs
@@ -25,44 +25,44 @@
*/
using System;
-using System.Timers;
using System.Threading;
using System.Collections.Generic;
-using Timer = System.Timers.Timer;
+using Timer = System.Threading.Timer ;
namespace OpenSim.Framework
{
- public class ExpiringKey<Tkey1> : IDisposable
+ public sealed class ExpiringKey<Tkey1> : IDisposable
{
- private Dictionary<Tkey1, int> m_dictionary;
+ private const int MINEXPIRE = 500;
- private ReaderWriterLockSlim m_rwLock = new ReaderWriterLockSlim();
- private readonly double m_startTS;
- private readonly int expire;
private Timer m_purgeTimer;
+ private ReaderWriterLockSlim m_rwLock;
+ private readonly Dictionary<Tkey1, int> m_dictionary;
+ private readonly double m_startTS;
+ private readonly int m_expire;
+
+ public ExpiringKey()
+ {
+ m_dictionary = new Dictionary<Tkey1, int>();
+ m_rwLock = new ReaderWriterLockSlim();
+ m_expire = MINEXPIRE;
+ m_startTS = Util.GetTimeStampMS();
+ }
public ExpiringKey(int expireTimeinMS)
{
m_dictionary = new Dictionary<Tkey1, int>();
+ m_rwLock = new ReaderWriterLockSlim();
m_startTS = Util.GetTimeStampMS();
- expire = expireTimeinMS;
- if(expire < 500)
- expire = 500;
+ m_expire = (expireTimeinMS > MINEXPIRE) ? m_expire = expireTimeinMS : MINEXPIRE;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
- private void SetTimer()
+ private void CheckTimer()
{
if (m_purgeTimer == null)
{
- m_purgeTimer = new Timer()
- {
- Interval = expire,
- AutoReset = false // time drift is not a issue.
-
- };
- m_purgeTimer.Elapsed += Purge;
- m_purgeTimer.Start();
+ m_purgeTimer = new Timer(Purge, null, m_expire, Timeout.Infinite);
}
}
@@ -71,7 +71,6 @@ namespace OpenSim.Framework
{
if (m_purgeTimer != null)
{
- m_purgeTimer.Stop();
m_purgeTimer.Dispose();
m_purgeTimer = null;
}
@@ -88,24 +87,18 @@ namespace OpenSim.Framework
GC.SuppressFinalize(this);
}
- protected void Dispose(bool disposing)
+ private void Dispose(bool disposing)
{
if (m_rwLock != null)
{
+ DisposeTimer();
m_rwLock.Dispose();
m_rwLock = null;
- DisposeTimer();
}
}
- private void Purge(object source, ElapsedEventArgs e)
+ private void Purge(object ignored)
{
- if (m_dictionary.Count == 0)
- {
- DisposeTimer();
- return;
- }
-
bool gotLock = false;
int now = (int)(Util.GetTimeStampMS() - m_startTS);
@@ -117,6 +110,13 @@ namespace OpenSim.Framework
m_rwLock.EnterWriteLock();
gotLock = true;
}
+
+ if (m_dictionary.Count == 0)
+ {
+ DisposeTimer();
+ return;
+ }
+
List<Tkey1> expired = new List<Tkey1>(m_dictionary.Count);
foreach(KeyValuePair<Tkey1,int> kvp in m_dictionary)
{
@@ -128,7 +128,7 @@ namespace OpenSim.Framework
if(m_dictionary.Count == 0)
DisposeTimer();
else
- m_purgeTimer.Start();
+ m_purgeTimer.Change(m_expire, Timeout.Infinite);
}
finally
{
@@ -140,13 +140,10 @@ namespace OpenSim.Framework
public void Add(Tkey1 key)
{
bool gotLock = false;
- int now = (int)(Util.GetTimeStampMS() - m_startTS) + expire;
+ int now = (int)(Util.GetTimeStampMS() - m_startTS) + m_expire;
try
{
- // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing
- // the acquision inside the main try. The inner finally block is needed because thread aborts cannot
- // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly).
try { }
finally
{
@@ -155,7 +152,7 @@ namespace OpenSim.Framework
}
m_dictionary[key] = now;
- SetTimer();
+ CheckTimer();
}
finally
{
@@ -167,17 +164,11 @@ namespace OpenSim.Framework
public void Add(Tkey1 key, int expireMS)
{
bool gotLock = false;
- int now;
- if (expireMS > 500)
- now = (int)(Util.GetTimeStampMS() - m_startTS) + expire;
- else
- now = (int)(Util.GetTimeStampMS() - m_startTS) + 500;
+ expireMS = (expireMS > m_expire) ? expireMS : m_expire;
+ int now = (int)(Util.GetTimeStampMS() - m_startTS) + expireMS;
try
{
- // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing
- // the acquision inside the main try. The inner finally block is needed because thread aborts cannot
- // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly).
try { }
finally
{
@@ -186,7 +177,7 @@ namespace OpenSim.Framework
}
m_dictionary[key] = now;
- SetTimer();
+ CheckTimer();
}
finally
{
@@ -202,9 +193,6 @@ namespace OpenSim.Framework
try
{
- // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing
- // the acquision inside the main try. The inner finally block is needed because thread aborts cannot
- // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly).
try {}
finally
{
@@ -224,24 +212,20 @@ namespace OpenSim.Framework
return success;
}
-
public void Clear()
{
bool gotLock = false;
try
{
- // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing
- // the acquision inside the main try. The inner finally block is needed because thread aborts cannot
- // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly).
try {}
finally
{
m_rwLock.EnterWriteLock();
gotLock = true;
- m_dictionary.Clear();
- DisposeTimer();
}
+ m_dictionary.Clear();
+ DisposeTimer();
}
finally
{
@@ -257,7 +241,22 @@ namespace OpenSim.Framework
public bool ContainsKey(Tkey1 key)
{
- return m_dictionary.ContainsKey(key);
+ bool gotLock = false;
+ try
+ {
+ try { }
+ finally
+ {
+ m_rwLock.EnterReadLock();
+ gotLock = true;
+ }
+ return m_dictionary.ContainsKey(key);
+ }
+ finally
+ {
+ if (gotLock)
+ m_rwLock.ExitReadLock();
+ }
}
public bool TryGetValue(Tkey1 key, out int value)
@@ -267,9 +266,6 @@ namespace OpenSim.Framework
try
{
- // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing
- // the acquision inside the main try. The inner finally block is needed because thread aborts cannot
- // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly).
try {}
finally
{