You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
315 lines
10 KiB
315 lines
10 KiB
|
|
/*-----------------------------------------------------------------------------
|
|
Microsoft Denali
|
|
|
|
Microsoft Confidential
|
|
Copyright 1996 Microsoft Corporation. All Rights Reserved.
|
|
|
|
Component: Template Cache Manager
|
|
|
|
File: CacheMgr.h
|
|
|
|
Owner: DGottner
|
|
|
|
Template cache manager definition
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
#ifndef _CACHEMGR_H
|
|
#define _CACHEMGR_H
|
|
|
|
// Includes -------------------------------------------------------------------
|
|
|
|
#include "Template.h"
|
|
#include "lkrhash.h"
|
|
#include "aspdmon.h"
|
|
|
|
class CHitObj;
|
|
|
|
#define MAX_CLEANUP_THREADS 32
|
|
|
|
// Types and Constants --------------------------------------------------------
|
|
|
|
#define CTEMPLATEBUCKETS 1021 // size of CTemplate hash table
|
|
#define CINCFILEBUCKETS 89 // size of CIncFile hash table
|
|
|
|
|
|
/* ****************************************************************************
|
|
Class: CTemplateCacheManager
|
|
Synopsis: A CCacheManager that manages a cache of Denali templates
|
|
*/
|
|
class CTemplateCacheManager
|
|
{
|
|
|
|
private:
|
|
class CTemplateHashTable;
|
|
friend class CTemplateHashTable;
|
|
|
|
// since there is only one CTemplateCacheManager object ever available, namely
|
|
// g_TemplateCache, this is safe to call these two members static.
|
|
|
|
static BOOL m_fFailedToInitPersistCache;
|
|
static char m_szPersistCacheDir[MAX_PATH];
|
|
|
|
HANDLE m_hOnInitCleanupThread;
|
|
|
|
HANDLE m_hCleanupThreads[MAX_CLEANUP_THREADS];
|
|
DWORD m_cCleanupThreads;
|
|
|
|
// The type for a hash table of CTemplates keyed on instance id + name
|
|
//
|
|
// since we provide new methods, make parent methods uncallable
|
|
class CTemplateHashTable : private CTypedHashTable<CTemplateHashTable, CTemplate, const CTemplateKey *>
|
|
{
|
|
private:
|
|
CDblLink m_listMemoryTemplates;
|
|
CDblLink m_listPersistTemplates;
|
|
DWORD m_dwInMemoryTemplates;
|
|
DWORD m_dwPersistedTemplates;
|
|
|
|
public:
|
|
// export some methods
|
|
DWORD InMemoryTemplates() { return m_dwInMemoryTemplates; };
|
|
//CTypedHashTable<CTemplateHashTable, CTemplate, const CTemplateKey *>::Size;
|
|
|
|
// test to see if the template can be persisted...
|
|
BOOL CanPersistTemplate(CTemplate *pTemplate);
|
|
|
|
// trim some number of templates from the persist cache...
|
|
BOOL TrimPersistCache(DWORD dwTrimCount);
|
|
|
|
VOID ScavengePersistCache();
|
|
|
|
// new methods
|
|
CTemplateHashTable()
|
|
: CTypedHashTable<CTemplateHashTable, CTemplate, const CTemplateKey *>("ASP Template Cache") {
|
|
m_dwInMemoryTemplates = 0;
|
|
m_dwPersistedTemplates = 0;
|
|
}
|
|
|
|
static const CTemplateKey *ExtractKey(const CTemplate *pTemplate)
|
|
{
|
|
return pTemplate->ExtractHashKey();
|
|
}
|
|
|
|
// NOTE: We don't hash the pTemplateKey->nInstanceID because it can be wildcarded.
|
|
// if we were to include in the hash, the wildcard won't hash to the same key
|
|
//
|
|
static DWORD CalcKeyHash(const CTemplateKey *pTemplateKey)
|
|
{
|
|
return HashString(pTemplateKey->szPathTranslated, 0);
|
|
}
|
|
|
|
static bool EqualKeys(const CTemplateKey *pKey1, const CTemplateKey *pKey2) {
|
|
return (_tcscmp(pKey1->szPathTranslated, pKey2->szPathTranslated) == 0)
|
|
&& (pKey1->dwInstanceID == pKey2->dwInstanceID
|
|
|| pKey1->dwInstanceID == MATCH_ALL_INSTANCE_IDS
|
|
|| pKey2->dwInstanceID == MATCH_ALL_INSTANCE_IDS);
|
|
}
|
|
|
|
// NOTE: In theory, the LKHash can help solve our ref. counting problems, by
|
|
// automatic addref/release. However, since prior code uses non-refcounting
|
|
// data structure, it's safer to leave old code alaone in this respect, and
|
|
// no-op the AddRefRecord method.
|
|
//
|
|
static void AddRefRecord(CTemplate *pTemplate, int nIncr)
|
|
{
|
|
}
|
|
|
|
// Provide new methods to automatically manage the LRU ordering.
|
|
// NOTE: We used to override the methods but ran into inconsistencies (bugs?)
|
|
// in VC compiler. Sometimes it would call derived & sometimes the base class
|
|
// given the same arguemt datatypes.
|
|
//
|
|
LK_RETCODE InsertTemplate(CTemplate *pTemplate);
|
|
|
|
LK_RETCODE RemoveTemplate(CTemplate *pTemplate, BOOL fPersist = FALSE, BOOL fScavengePersistCache = TRUE);
|
|
|
|
// NOTE: Template signature also requires const ptr to const data
|
|
LK_RETCODE FindTemplate(const CTemplateKey &rTemplateKey, CTemplate **ppTemplate, BOOL* pfNeedsCheck = NULL);
|
|
|
|
// accessor methods for hidden LRU cache
|
|
bool FMemoryTemplatesIsEmpty() const
|
|
{
|
|
return m_listMemoryTemplates.FIsEmpty();
|
|
}
|
|
|
|
// you CANNOT compare LRU nodes to NULL to know if you are at the end
|
|
// of the list! Instead use this member.
|
|
//
|
|
BOOL FMemoryTemplatesDblLinkAtEnd(CDblLink *pElem)
|
|
{
|
|
pElem->AssertValid();
|
|
return pElem == &m_listMemoryTemplates;
|
|
}
|
|
|
|
CDblLink *MemoryTemplatesBegin() // return pointer to last referenced item
|
|
{
|
|
return m_listMemoryTemplates.PNext();
|
|
}
|
|
|
|
CDblLink *MemoryTemplatesEnd() // return pointer to least recently accessed item
|
|
{
|
|
return m_listMemoryTemplates.PPrev();
|
|
}
|
|
|
|
// accessor methods for hidden LRU cache
|
|
bool FPersistTemplatesIsEmpty() const
|
|
{
|
|
return m_listPersistTemplates.FIsEmpty();
|
|
}
|
|
|
|
// you CANNOT compare LRU nodes to NULL to know if you are at the end
|
|
// of the list! Instead use this member.
|
|
//
|
|
BOOL FPersistTemplatesDblLinkAtEnd(CDblLink *pElem)
|
|
{
|
|
pElem->AssertValid();
|
|
return pElem == &m_listPersistTemplates;
|
|
}
|
|
|
|
CDblLink *PersistTemplatesBegin() // return pointer to last referenced item
|
|
{
|
|
return m_listPersistTemplates.PNext();
|
|
}
|
|
|
|
CDblLink *PersistTemplatesEnd() // return pointer to least recently accessed item
|
|
{
|
|
return m_listPersistTemplates.PPrev();
|
|
}
|
|
};
|
|
|
|
CRITICAL_SECTION m_csUpdate; // CS for updating the data structures
|
|
CTemplateHashTable *m_pHashTemplates; // the cache data structure
|
|
DWORD m_dwTemplateCacheTag; // Cache Tag to for cache consistency verification
|
|
|
|
// Initialize the persistant template cache
|
|
BOOL InitPersistCache(CIsapiReqInfo *pIReq);
|
|
|
|
// static methods primarily used from a seperate thread to flush
|
|
// the template cache out of band from the FCN thread notification.
|
|
|
|
static void FlushHashTable(CTemplateHashTable *pTable);
|
|
static DWORD __stdcall FlushHashTableThread(VOID *pArg);
|
|
|
|
// Spawned at FirstInit to cleanup leftover old cache directories
|
|
static DWORD OnInitCleanup(VOID *p);
|
|
|
|
public:
|
|
|
|
|
|
CTemplateCacheManager();
|
|
~CTemplateCacheManager();
|
|
|
|
inline void LockTemplateCache() { EnterCriticalSection(&m_csUpdate); }
|
|
inline void UnLockTemplateCache() { LeaveCriticalSection(&m_csUpdate); }
|
|
|
|
HRESULT Init();
|
|
HRESULT UnInit();
|
|
DWORD GetCacheTag() { return m_dwTemplateCacheTag;}
|
|
|
|
HRESULT FirstHitInit(CIsapiReqInfo *pIReq)
|
|
{ InitPersistCache(pIReq); return S_OK; }
|
|
|
|
// Find in cache (don't load) -- for look-aheads
|
|
/////
|
|
HRESULT FindCached(const TCHAR *szFile, DWORD dwInstanceID, CTemplate **ppTemplate);
|
|
|
|
// Get a template from the cache, or load it into cache
|
|
/////
|
|
HRESULT Load(BOOL fRunGlobalAsp, const TCHAR *szFile, DWORD dwInstanceID, CHitObj *pHitObj, CTemplate **ppTemplate, BOOL *pfTemplateInCache);
|
|
|
|
// Remove a template from the cache
|
|
// for backward compatibility, "nInstanceID" can be omitted, in which case all instance ID
|
|
// templates are flushed.
|
|
/////
|
|
void Flush(const TCHAR *szFile, DWORD dwInstanceID);
|
|
|
|
// Remove templates from the cache that have a common prefix
|
|
// Instance ID is ignored.
|
|
/////
|
|
void FlushFiles(const TCHAR *szFilePrefix);
|
|
|
|
// Remove all templates from the cache
|
|
/////
|
|
//void FlushAll(VOID);
|
|
void FlushAll(BOOL fDoLazyFlush = FALSE);
|
|
|
|
|
|
// Add all templates that form an application to the debugger's list of
|
|
// running documents
|
|
/////
|
|
void AddApplicationToDebuggerUI(CAppln *pAppln);
|
|
|
|
// Remove all templates that form an application from the debugger's list of
|
|
// running documents
|
|
/////
|
|
void RemoveApplicationFromDebuggerUI(CAppln *pAppln);
|
|
|
|
// Get directory change notification on directories used by template
|
|
BOOL RegisterTemplateForChangeNotification(CTemplate *pTemplate, CAppln *pApplication);
|
|
|
|
// Get directory change notification for applications
|
|
BOOL RegisterApplicationForChangeNotification(CTemplate *pTemplate, CAppln *pApplication);
|
|
|
|
// Stop getting change notification for changes to templates in the cache.
|
|
BOOL ShutdownCacheChangeNotification();
|
|
|
|
};
|
|
|
|
|
|
|
|
/* ****************************************************************************
|
|
Class: CIncFileMap
|
|
Synopsis: A database mapping template include files to a list of their users
|
|
*/
|
|
class CIncFileMap
|
|
{
|
|
CRITICAL_SECTION m_csUpdate; // CS for updating the data structures
|
|
CHashTable m_mpszIncFile; // the cache data structure
|
|
|
|
public:
|
|
|
|
CIncFileMap();
|
|
~CIncFileMap();
|
|
|
|
inline void LockIncFileCache() { EnterCriticalSection(&m_csUpdate); }
|
|
inline void UnLockIncFileCache() { LeaveCriticalSection(&m_csUpdate); }
|
|
|
|
HRESULT Init();
|
|
HRESULT UnInit();
|
|
|
|
HRESULT GetIncFile(const TCHAR *szIncFile, CIncFile **ppIncFile);
|
|
void Flush(const TCHAR *szIncFile);
|
|
void FlushFiles(const TCHAR *szIncFilePrefix);
|
|
};
|
|
|
|
|
|
|
|
/* ****************************************************************************
|
|
Non-class support functions
|
|
*/
|
|
BOOL FFileChangedSinceCached(const TCHAR *szFile, HANDLE hFile, FILETIME& ftPrevWriteTime);
|
|
|
|
|
|
|
|
// Globals --------------------------------------------------------------------
|
|
|
|
extern CTemplateCacheManager g_TemplateCache;
|
|
extern CIncFileMap g_IncFileMap;
|
|
|
|
inline void LockTemplateAndIncFileCaches()
|
|
{
|
|
g_TemplateCache.LockTemplateCache();
|
|
g_IncFileMap.LockIncFileCache();
|
|
}
|
|
|
|
inline void UnLockTemplateAndIncFileCaches()
|
|
{
|
|
g_TemplateCache.UnLockTemplateCache();
|
|
g_IncFileMap.UnLockIncFileCache();
|
|
}
|
|
|
|
|
|
// Prototypes -----------------------------------------------------------------
|
|
|
|
#endif // _CACHEMGR_H
|