浏览代码

HPCC-15507 Rework shared permissions cache

Add the capability to create a permissions cache that is shared by a class
of security managers. This will allow various security managers classes
to coexist without sharing a single cache.

Signed-off-by: Russ Whitehead <william.whitehead@lexisnexis.com>
Russ Whitehead 9 年之前
父节点
当前提交
71dd23b6bc

+ 2 - 4
system/security/LdapSecurity/ldapsecurity.cpp

@@ -536,9 +536,9 @@ void CLdapSecManager::init(const char *serviceName, IPropertyTree* cfg)
     int cachetimeout = cfg->getPropInt("@cacheTimeout", 5);
 
     if (cfg->getPropBool("@sharedCache", true))
-        m_permissionsCache = CPermissionsCache::queryInstance();
+        m_permissionsCache.setown(CPermissionsCache::getInstance(cfg->queryProp("@name")));
     else
-        m_permissionsCache = new CPermissionsCache();
+        m_permissionsCache.setown(new CPermissionsCache());
 
     m_permissionsCache->setCacheTimeout( 60 * cachetimeout);
     m_permissionsCache->setTransactionalEnabled(true);
@@ -554,8 +554,6 @@ CLdapSecManager::CLdapSecManager(const char *serviceName, IPropertyTree &config)
 
 CLdapSecManager::~CLdapSecManager()
 {
-    if (!m_cfg->getPropBool("@sharedCache", true))
-        delete m_permissionsCache;
 }
 
 //interface ISecManager : extends IInterface

+ 1 - 1
system/security/LdapSecurity/ldapsecurity.ipp

@@ -335,7 +335,7 @@ private:
     IUserArray m_user_array;
     Monitor m_monitor;
     Owned<IProperties> m_extraparams;
-    CPermissionsCache * m_permissionsCache;
+    Owned<CPermissionsCache> m_permissionsCache;
     bool m_cache_off[RT_SCOPE_MAX];
     bool m_usercache_off;
     bool authenticate(ISecUser* user);

+ 29 - 0
system/security/shared/caching.cpp

@@ -18,6 +18,11 @@
 #include "caching.hpp"
 #include "jtime.hpp"
 
+//define a container for multiple instances of a security manager cache
+typedef map<string, CPermissionsCache*> MapCache;
+static CriticalSection mapCacheCS;//guards modifications to the cache map
+static MapCache g_mapCache;
+
 /**********************************************************
  *     CResPermissionsCache                               *
  *     (used by CPermissionsCache defined below)          *
@@ -210,6 +215,11 @@ void CResPermissionsCache::remove(SecResourceType rtype, const char* resourcenam
 
 CPermissionsCache::~CPermissionsCache()
 {
+    if (!m_secMgrClass.isEmpty())
+    {
+        CriticalBlock block(mapCacheCS);
+        g_mapCache.erase(m_secMgrClass.str());
+    }
     flush();
 }
 
@@ -625,3 +635,22 @@ void CPermissionsCache::flush()
     m_lastManagedFileScopesRefresh = 0;
     m_defaultPermission = SecAccess_Unknown;//trigger refresh
 }
+
+CPermissionsCache* CPermissionsCache::getInstance(const char * _secMgrClass)
+{
+    const char * secMgrClass = (_secMgrClass != nullptr  &&  *_secMgrClass) ? _secMgrClass : "genericSecMgrClass";
+
+    CriticalBlock block(mapCacheCS);
+    MapCache::iterator it = g_mapCache.find(secMgrClass);
+    if (it != g_mapCache.end())//exists in cache
+    {
+        LINK((*it).second);
+        return (*it).second;
+    }
+    else
+    {
+        CPermissionsCache * instance = new CPermissionsCache(_secMgrClass);
+        g_mapCache.insert(pair<string, CPermissionsCache*>(secMgrClass, instance));
+        return instance;
+    }
+}

+ 15 - 21
system/security/shared/caching.hpp

@@ -18,7 +18,7 @@
 #ifndef _CACHING_HPP__
 #define _CACHING_HPP__
 #pragma warning(disable:4786)
- 
+
 #include "jliball.hpp"
 #include "seclib.hpp"
 #undef new
@@ -39,10 +39,10 @@ using std::string;
 
 typedef pair<time_t, ISecResource*> ResPermCacheEntry;
 typedef pair<string, SecResourceType> SecCacheKeyEntry;
-//this a cache for a given user that stores permissions for individual resources 
-//along with their timestamps when they were fetched.  The cache is periodically 
+//this a cache for a given user that stores permissions for individual resources
+//along with their timestamps when they were fetched.  The cache is periodically
 //cleaned up to remove stale (older than 5 minutes) entries - triggered by a lookup
-//itself.  Note that each user has an instance of this cache, which is stored in 
+//itself.  Note that each user has an instance of this cache, which is stored in
 //another map (CPermissionsCache) as defined below.
 //
 //
@@ -134,34 +134,27 @@ public:
 
 // main cache that stores all user-specific caches (defined by CResPermissionsCache above)
 //
-static CriticalSection PCCritSect;//guards instance factory
-static CPermissionsCache* instance = nullptr;//accessed via CPermissionsCache::queryInstance()
-
-class CPermissionsCache
+class CPermissionsCache : public CInterface, implements IInterface
 {
 public:
-    CPermissionsCache()
+    IMPLEMENT_IINTERFACE
+
+    CPermissionsCache(const char * _secMgrClass = nullptr)
     {
         m_cacheTimeout = 300;
         m_transactionalEnabled = false;
         m_secMgr = NULL;
         m_lastManagedFileScopesRefresh = 0;
         m_defaultPermission = SecAccess_Unknown;
+        m_secMgrClass.set(_secMgrClass);
     }
 
     virtual ~CPermissionsCache();
 
-    static CPermissionsCache* queryInstance()
-    {
-        {
-            CriticalBlock block(PCCritSect);
-            if (instance == nullptr)
-            {
-                instance = new CPermissionsCache();
-            }
-        }
-        return instance;
-    }
+    //Returns an owned reference to a shared cache of a given Sec Mgr class type.
+    //Call this method with a unique class string ("LDAP", "MyOtherSecMgr")
+    //to create a cache shared amongst security managers of the same class
+    static CPermissionsCache* getInstance(const char * _secMgrClass);
 
     //finds cached permissions for a number of resources and sets them in
     //and also returns status in the boolean array passed in
@@ -206,6 +199,8 @@ private:
     MapUserCache m_userCache;
     mutable ReadWriteLock m_userCacheRWLock;    //guards m_userCache
 
+    StringAttr                  m_secMgrClass;
+
     //Managed File Scope support
     int                         m_defaultPermission;
     map<string, ISecResource*>  m_managedFileScopesMap;
@@ -216,5 +211,4 @@ private:
 
 time_t getThreadCreateTime();
 
-
 #endif