Leaked source code of windows server 2003
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.
 
 
 
 
 
 

689 lines
13 KiB

#ifndef _USERCACHE_HXX_
#define _USERCACHE_HXX_
#include <lkrhash.h>
#include <dirmon.h>
#include <reftrace.h>
#ifndef W3CACHE_DLLEXP
# ifdef DLL_IMPLEMENTATION
# define W3CACHE_DLLEXP __declspec(dllexport)
# ifdef IMPLEMENTATION_EXPORT
# define W3CACHE_EXPIMP
# else
# undef W3CACHE_EXPIMP
# endif
# elif defined LIB_IMPLEMENTATION
# define W3CACHE_DLLEXP
# define W3CACHE_EXPIMP extern
# else
# define W3CACHE_DLLEXP __declspec(dllimport)
# define W3CACHE_EXPIMP extern
# endif // !DLL_IMPLEMENTATION
#endif // !W3CACHE_DLLEXP
#define CACHE_INVALIDATION_DIRMON_SPECIFIC 0x1
#define CACHE_INVALIDATION_DIRMON_FLUSH 0x2
#define CACHE_INVALIDATION_METADATA 0x4
//
// Configuration for dir monitoring
//
struct DIRMON_CONFIG
{
HANDLE hToken;
WCHAR * pszDirPath;
};
//
// When accessing file cache, file cache user describes the user trying to
// access the file (it is either a token or token/sid)
//
class CACHE_USER
{
public:
CACHE_USER()
: _hToken( NULL ),
_pSid( NULL )
{
}
HANDLE _hToken;
PSID _pSid;
};
//
// Key used to lookup any of the caches
//
class CACHE_KEY
{
public:
CACHE_KEY()
{
}
virtual ~CACHE_KEY()
{
}
virtual
WCHAR *
QueryHintKey(
VOID
)
{
return NULL;
}
virtual
DWORD
QueryKeyHash(
VOID
) const = 0;
virtual
BOOL
QueryIsEqual(
const CACHE_KEY * pCacheCompareKey
) const = 0;
};
class OBJECT_CACHE;
#define CACHE_ENTRY_SIGNATURE 'STEC'
#define CACHE_ENTRY_SIGNATURE_FREE 'xtec'
class W3CACHE_DLLEXP CACHE_ENTRY
{
public:
CACHE_ENTRY(
OBJECT_CACHE * pObjectCache,
DWORD cTTLOverride = 0
);
VOID
ReferenceCacheEntry(
VOID
);
VOID
DereferenceCacheEntry(
VOID
);
virtual
STRU *
QueryMetadataPath(
VOID
)
{
return NULL;
}
HRESULT
AddDirmonInvalidator(
DIRMON_CONFIG * pDirmonConfig
);
BOOL
QueryIsFlushed(
VOID
) const
{
return _fFlushed;
}
virtual
BOOL
Checkout(
CACHE_USER *pOpeningUser
);
VOID
SetCached(
BOOL fCached
)
{
_fCached = fCached;
}
BOOL
QueryCached(
VOID
) const
{
return _fCached;
}
VOID
SetFlushed(
VOID
)
{
_fFlushed = TRUE;
}
VOID
LockCacheEntry(
VOID
)
{
_lock.WriteLock();
}
VOID
UnlockCacheEntry(
VOID
)
{
_lock.WriteUnlock();
}
OBJECT_CACHE *
QueryCache(
VOID
) const
{
return _pObjectCache;
}
virtual
BOOL
QueryIsOkToFlushTTL(
VOID
);
BOOL
QueryIsOkToFlushMetadata(
WCHAR * pszPath,
DWORD cchPath
);
virtual
BOOL
QueryIsOkToFlushDirmon(
WCHAR *,
DWORD
)
{
return TRUE;
}
virtual
CACHE_KEY *
QueryCacheKey(
VOID
) const = 0;
BOOL
CheckSignature(
VOID
) const
{
return _dwSignature == CACHE_ENTRY_SIGNATURE;
}
LIST_ENTRY _listEntry;
protected:
virtual ~CACHE_ENTRY();
private:
DWORD _dwSignature;
LONG _cRefs;
BOOL _fFlushed;
LONG _cTTL;
LONG _cConfiguredTTL;
BOOL _fCached;
CSmallSpinLock _lock;
OBJECT_CACHE * _pObjectCache;
CDirMonitorEntry * _pDirmonInvalidator;
};
class CACHE_ENTRY_HASH : public CTypedHashTable< CACHE_ENTRY_HASH,
CACHE_ENTRY,
CACHE_KEY * >
{
public:
CACHE_ENTRY_HASH() : CTypedHashTable< CACHE_ENTRY_HASH,
CACHE_ENTRY,
CACHE_KEY * >
( "CACHE_ENTRY_HASH" )
{
}
static CACHE_KEY *
ExtractKey(
const CACHE_ENTRY * pCacheEntry
)
{
return pCacheEntry->QueryCacheKey();
}
static DWORD
CalcKeyHash(
const CACHE_KEY * pCacheKey
)
{
return pCacheKey->QueryKeyHash();
}
static bool
EqualKeys(
const CACHE_KEY * pCacheKey1,
const CACHE_KEY * pCacheKey2
)
{
return pCacheKey1->QueryIsEqual( pCacheKey2 ) ? true : false;
}
static void
AddRefRecord(
CACHE_ENTRY * pCacheEntry,
int nIncr
);
private:
CACHE_ENTRY_HASH(
const CACHE_ENTRY_HASH &
);
VOID operator=(
const CACHE_ENTRY_HASH &
);
};
struct CACHE_HINT_CONFIG
{
DWORD cmsecTTL;
DWORD cmsecScavengeTime;
DWORD cmsecActivityWindow;
};
class CACHE_HINT_MANAGER;
//
// All caches derive from this abstract class
//
#define OBJECT_CACHE_SIGNATURE 'SCBO'
#define OBJECT_CACHE_SIGNATURE_FREE 'xcbo'
class OBJECT_CACHE
{
public:
W3CACHE_DLLEXP OBJECT_CACHE();
W3CACHE_DLLEXP virtual ~OBJECT_CACHE();
W3CACHE_DLLEXP
HRESULT
SetCacheConfiguration(
DWORD cmsecScavenge,
DWORD cmsecTTL,
DWORD dwSupportedInvalidation,
CACHE_HINT_CONFIG * pCacheHintConfig
);
W3CACHE_DLLEXP
HRESULT
FindCacheEntry(
CACHE_KEY * pCacheKey,
CACHE_ENTRY ** ppCacheEntry,
BOOL * pfShouldCache = NULL
);
W3CACHE_DLLEXP
HRESULT
FlushCacheEntry(
CACHE_KEY * pCacheKey
);
W3CACHE_DLLEXP
HRESULT
AddCacheEntry(
CACHE_ENTRY * pCacheEntry
);
W3CACHE_DLLEXP
HRESULT
AddDirmonInvalidator(
DIRMON_CONFIG * pDirmonConfig,
CDirMonitorEntry ** ppDME
);
W3CACHE_DLLEXP
VOID
CleanupCacheEntryListItems(
LIST_ENTRY * pListHead
);
W3CACHE_DLLEXP
VOID
UnregisterScavenger(
VOID
);
VOID
FlushByTTL(
LIST_ENTRY * pListHead
);
W3CACHE_DLLEXP
VOID
FlushByRegChange(
LIST_ENTRY * pListHead
);
VOID
DoDirmonInvalidationFlush(
WCHAR * pszPath
);
VOID
DoMetadataInvalidationFlush(
WCHAR * pszMetapath
);
VOID
Clear(
VOID
)
{
_hashTable.Clear();
}
BOOL
QuerySupportsDirmonSpecific(
VOID
)
{
return !!( _dwSupportedInvalidation & CACHE_INVALIDATION_DIRMON_SPECIFIC );
}
BOOL
QuerySupportsDirmonFlush(
VOID
)
{
return !!( _dwSupportedInvalidation & CACHE_INVALIDATION_DIRMON_FLUSH );
}
BOOL
QuerySupportsMetadataFlush(
VOID
)
{
return !!( _dwSupportedInvalidation & CACHE_INVALIDATION_METADATA );
}
VOID
DoReferenceTrace(
CACHE_ENTRY * pCacheEntry,
DWORD cRefs
)
{
if ( _pTraceLog != NULL )
{
WriteRefTraceLog( _pTraceLog, cRefs, pCacheEntry );
}
}
virtual
WCHAR *
QueryName(
VOID
) const = 0;
virtual
VOID
DoDirmonInvalidationSpecific(
WCHAR *
)
{
}
static
VOID
WINAPI
ScavengerCallback(
PVOID pObjectCache,
BOOLEAN TimerOrWaitFired
);
static
LK_PREDICATE
CacheFlushByRegChange(
CACHE_ENTRY * pCacheEntry,
VOID * pvState
);
static
LK_PREDICATE
CacheFlushByTTL(
CACHE_ENTRY * pCacheEntry,
VOID * pvState
);
static
LK_PREDICATE
CacheFlushByDirmon(
CACHE_ENTRY * pCacheEntry,
VOID * pvState
);
static
LK_PREDICATE
CacheFlushByMetadata(
CACHE_ENTRY * pCacheEntry,
VOID * pvState
);
BOOL
CheckSignature(
VOID
) const
{
return _dwSignature == OBJECT_CACHE_SIGNATURE;
}
BOOL
SupportsInvalidation(
DWORD dwInvalidationType
)
{
return !!( dwInvalidationType & _dwSupportedInvalidation );
}
DWORD
QueryConfiguredTTL(
VOID
)
{
if ( _cmsecTTL == 0 || _cmsecScavengeTime == 0 )
{
return INFINITE;
}
else
{
return ( _cmsecTTL / _cmsecScavengeTime ) + 1;
}
}
VOID
IncHits(
VOID
)
{
InterlockedIncrement( (LPLONG) &_cCacheHits );
InterlockedIncrement( (LPLONG) &_cPerfCacheHits );
}
DWORD
PerfQueryHits(
VOID
)
{
return InterlockedExchange( (LPLONG) &_cPerfCacheHits, 0 );
}
VOID
IncMisses(
VOID
)
{
InterlockedIncrement( (LPLONG) &_cCacheMisses );
InterlockedIncrement( (LPLONG) &_cPerfCacheMisses );
}
DWORD
PerfQueryMisses(
VOID
)
{
return InterlockedExchange( (LPLONG) &_cPerfCacheMisses, 0 );
}
VOID
IncFlushes(
VOID
)
{
InterlockedIncrement( (LPLONG) &_cCacheFlushes );
InterlockedIncrement( (LPLONG) &_cPerfCacheFlushes );
InterlockedIncrement( (LPLONG) &_cActiveFlushedEntries );
}
DWORD
PerfQueryFlushes(
VOID
)
{
return InterlockedExchange( (LPLONG) &_cPerfCacheFlushes, 0 );
}
VOID
DecActiveFlushedEntries(
VOID
)
{
InterlockedDecrement( (LPLONG) &_cActiveFlushedEntries );
}
DWORD
PerfQueryActiveFlushedEntries(
VOID
)
{
return _cActiveFlushedEntries;
}
VOID
IncFlushCalls(
VOID
)
{
InterlockedIncrement( (LPLONG) &_cFlushCalls );
InterlockedIncrement( (LPLONG) &_cPerfFlushCalls );
}
DWORD
PerfQueryFlushCalls(
VOID
)
{
return InterlockedExchange( (LPLONG) &_cPerfFlushCalls, 0 );
}
VOID
IncEntriesCached(
VOID
)
{
InterlockedIncrement( (LPLONG) &_cEntriesCached );
InterlockedIncrement( (LPLONG) &_cTotalEntriesCached );
InterlockedIncrement( (LPLONG) &_cPerfTotalEntriesCached );
}
VOID
DecEntriesCached(
VOID
)
{
InterlockedDecrement( (LPLONG) &_cEntriesCached );
}
DWORD
PerfQueryCurrentEntryCount(
VOID
) const
{
return _cEntriesCached;
}
DWORD
PerfQueryTotalEntriesCached(
VOID
) const
{
return InterlockedExchange( (LPLONG) &_cTotalEntriesCached, 0 );
}
private:
DWORD _dwSignature;
CACHE_ENTRY_HASH _hashTable;
LIST_ENTRY _listEntry;
HANDLE _hTimer;
DWORD _cmsecScavengeTime;
DWORD _cmsecTTL;
DWORD _dwSupportedInvalidation;
//
// Some stats
//
DWORD _cCacheHits;
DWORD _cCacheMisses;
DWORD _cCacheFlushes;
DWORD _cActiveFlushedEntries;
DWORD _cFlushCalls;
DWORD _cEntriesCached;
DWORD _cTotalEntriesCached;
//
// Perfmon helper stats (when debugging, ignore these values)
//
DWORD _cPerfCacheHits;
DWORD _cPerfCacheMisses;
DWORD _cPerfCacheFlushes;
DWORD _cPerfFlushCalls;
DWORD _cPerfTotalEntriesCached;
//
// Cache hint manager (if needed)
//
CACHE_HINT_MANAGER * _pHintManager;
//
// Ref tracing for all
//
PTRACE_LOG _pTraceLog;
static LIST_ENTRY sm_CacheListHead;
};
#endif