Przeglądaj źródła

HPCC-16030 Security Manager cache to implement read/write locks

Signed-off-by: Russ Whitehead <william.whitehead@lexisnexis.com>
Russ Whitehead 9 lat temu
rodzic
commit
25730e679f

+ 16 - 7
system/security/shared/caching.cpp

@@ -171,11 +171,7 @@ void CResPermissionsCache::add( IArrayOf<ISecResource>& resources )
 //called from within a WriteLockBlock
 void CResPermissionsCache::removeStaleEntries(time_t tstamp)
 {
-    int timeout = m_pParentCache->getCacheTimeout();
-    if(timeout == 0 && m_pParentCache->isTransactionalEnabled())
-        timeout = 10; //Transactional timeout is set to 10 seconds for long transactions that might take over 10 seconds.
-    tstamp -= timeout;
-    if (m_tLastCleanup < tstamp)
+    if (needsCleanup(tstamp, m_pParentCache->getCacheTimeout()))
     {
         MapTimeStamp::iterator i;
         MapTimeStamp::iterator itL    = m_timestampMap.lower_bound(tstamp);
@@ -234,13 +230,26 @@ int CPermissionsCache::lookup( ISecUser& sec_user, IArrayOf<ISecResource>& resou
 
     const char* userId = sec_user.getName();
 
-    //First, clear stale cache entries for this CResPermissionsCache entry
+    //First check if matching cache entry is stale
+    bool needsCleanup = false;
     {
-        WriteLockBlock writeLock(m_resPermCacheRWLock);
+        ReadLockBlock readLock(m_resPermCacheRWLock);
         MapResPermissionsCache::const_iterator i = m_resPermissionsMap.find( userId );
         if (i != m_resPermissionsMap.end())
         {
             CResPermissionsCache* pResPermissionsCache = (*i).second;
+            needsCleanup = pResPermissionsCache->needsCleanup(tstamp, getCacheTimeout());
+        }
+    }
+
+    //clear stale cache entries for this CResPermissionsCache entry
+    if (needsCleanup)
+    {
+        WriteLockBlock writeLock(m_resPermCacheRWLock);
+        MapResPermissionsCache::const_iterator i = m_resPermissionsMap.find( userId );
+        if (i != m_resPermissionsMap.end())//Entry could have been deleted by another thread
+        {
+            CResPermissionsCache* pResPermissionsCache = (*i).second;
             pResPermissionsCache->removeStaleEntries(tstamp);
         }
     }

+ 27 - 2
system/security/shared/caching.hpp

@@ -73,6 +73,10 @@ public:
     //removes entries older than tstamp passed in
     //
     virtual void removeStaleEntries(time_t tstamp);
+    virtual bool needsCleanup(time_t now, unsigned timeout)
+    {
+        return m_tLastCleanup < (now - timeout);
+    }
 private:
 
 
@@ -174,11 +178,31 @@ public:
     virtual void add (ISecUser& sec_user);
     virtual void removeFromUserCache(ISecUser& sec_user);
 
-    void  setCacheTimeout(int timeout) { m_cacheTimeout = timeout; }
+#define DEFAULT_CACHE_TIMEOUT_SECONDS 10
+    void  setCacheTimeout(int timeoutSeconds)
+    {
+        m_cacheTimeout = timeoutSeconds;
+        if(m_cacheTimeout == 0 && isTransactionalEnabled())//ensure transactional time is updated
+            setTransactionalCacheTimeout(DEFAULT_CACHE_TIMEOUT_SECONDS); //Transactional timeout is set to 10 seconds for long transactions that might take over 10 seconds.
+        else
+            setTransactionalCacheTimeout(timeoutSeconds);
+    }
     const int getCacheTimeout() { return m_cacheTimeout; }
     bool  isCacheEnabled() { return m_cacheTimeout > 0; }
-    void setTransactionalEnabled(bool enable) { m_transactionalEnabled = enable; }
+
+    void setTransactionalEnabled(bool enable)
+    {
+        m_transactionalEnabled = enable;
+        if(getCacheTimeout() == 0 && enable)//ensure transactional time is updated
+            setTransactionalCacheTimeout(DEFAULT_CACHE_TIMEOUT_SECONDS); //Transactional timeout is set to 10 seconds for long transactions that might take over 10 seconds.
+        else
+            setTransactionalCacheTimeout(getCacheTimeout());
+    }
+    void setTransactionalCacheTimeout(int timeoutSeconds) { m_transactionalCacheTimeout = timeoutSeconds; }
+    const int getTransactionalCacheTimeout() { return m_transactionalCacheTimeout; }
+
     bool isTransactionalEnabled() { return m_transactionalEnabled;}
+
     void flush();
     bool addManagedFileScopes(IArrayOf<ISecResource>& scopes);
     void removeManagedFileScopes(IArrayOf<ISecResource>& scopes);
@@ -196,6 +220,7 @@ private:
 
     int m_cacheTimeout; //cleanup cycle period
     bool m_transactionalEnabled;
+    int m_transactionalCacheTimeout;
 
     MapUserCache m_userCache;
     mutable ReadWriteLock m_userCacheRWLock;    //guards m_userCache