2025-04-27 07:49:33 -04:00

242 lines
5.9 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name :
cachep.cxx
Abstract:
This module contains the internal tsunami caching routines
Author:
Murali R. Krishnan ( MuraliK ) 16-Jan-1995
--*/
#include "TsunamiP.Hxx"
#pragma hdrstop
HASH_TYPE
CalculateHashAndLengthOfPathName(
LPCSTR pszPathName,
PULONG pcbLength
)
{
HASH_TYPE hash = 0;
CHAR ch;
DWORD start;
DWORD index;
ASSERT( pszPathName != NULL );
ASSERT( pcbLength != NULL );
*pcbLength = strlen(pszPathName);
//
// hash the last 8 characters
//
if ( *pcbLength < 8 ) {
start = 0;
} else {
start = *pcbLength - 8;
}
for ( index = start; pszPathName[index] != '\0'; index++ ) {
//
// This is an extremely slimey way of getting upper case.
// Kids, don't try this at home
// -johnson
//
ch = pszPathName[index] & (CHAR)~0x20;
hash <<= 1;
hash ^= ch;
hash <<= 1;
hash += ch;
}
//
// Multiply by length. Murali said so.
//
return( hash * *pcbLength);
} // CalculateHashAndLengthOfPathName
BOOL
DeCacheHelper(
PCACHE_OBJECT pCacheObject,
PLIST_ENTRY DeferredDerefListHead OPTIONAL,
PLIST_ENTRY DeferredDerefListEntry OPTIONAL
)
{
LPTS_OPEN_FILE_INFO openFileInfo = NULL;
PPHYS_OPEN_FILE_INFO physFileInfo;
PCACHE_OBJECT physCacheObject;
PBLOB_HEADER blob;
ASSERT( pCacheObject->Signature == CACHE_OBJ_SIGNATURE );
TSUNAMI_TRACE( TRACE_CACHE_DECACHE, pCacheObject );
//
// Already decached if not on any cache lists
//
if( RemoveCacheObjFromLists( pCacheObject, FALSE ) ) {
//
// If this is a URI_INFO or OPEN_FILE object, then mark the
// corresponding PHYSICAL_OPEN_FILE object as a Zombie.
//
blob = pCacheObject->pbhBlob;
if( blob != NULL ) {
ASSERT( blob->IsCached );
ASSERT( blob->pCache == pCacheObject );
if( pCacheObject->iDemux == RESERVED_DEMUX_URI_INFO ) {
//
// Map the blob pointer to a W3_URI_INFO pointer, then
// extract the TS_OPEN_FILE_INFO pointer.
//
openFileInfo = ((PW3_URI_INFO)( blob + 1 ))->pOpenFileInfo;
} else if( pCacheObject->iDemux == RESERVED_DEMUX_OPEN_FILE ) {
//
// Simply map the blob pointer to a TS_OPEN_FILE_INFO
// pointer.
//
openFileInfo = (LPTS_OPEN_FILE_INFO)( blob + 1 );
}
if( openFileInfo != NULL ) {
//
// OK, we have a TS_OPEN_FILE_INFO pointer. Extract the
// PHYS_OPEN_FILE_INFO pointer, and mark the containing
// CACHE_OBJECT as a zombie.
//
physFileInfo = openFileInfo->QueryPhysFileInfo();
if( physFileInfo != NULL ) {
ASSERT( physFileInfo->Signature == PHYS_OBJ_SIGNATURE );
blob = ((PBLOB_HEADER)physFileInfo) - 1;
if( blob->pCache != NULL ) {
ASSERT( blob->pCache->Signature == CACHE_OBJ_SIGNATURE );
TSUNAMI_TRACE( TRACE_CACHE_ZOMBIE, blob->pCache );
IF_DEBUG(OPLOCKS) {
DBGPRINTF((
DBG_CONTEXT,
"Marking cache @ %08lx as zombie\n",
blob->pCache
));
}
blob->pCache->fZombie = TRUE;
}
}
}
}
//
// This undoes the initial reference. The last person to check in
// this cache object will cause it to be deleted after this point.
//
if( DeferredDerefListHead == NULL ) {
ASSERT( DeferredDerefListEntry == NULL );
TsDereferenceCacheObj( pCacheObject, FALSE );
} else {
ASSERT( DeferredDerefListEntry != NULL );
ASSERT( (ULONG)DeferredDerefListEntry >= (ULONG)pCacheObject );
ASSERT( (ULONG)DeferredDerefListEntry <=
( (ULONG)pCacheObject + sizeof(*pCacheObject) - sizeof(LIST_ENTRY) ) );
InsertTailList( DeferredDerefListHead, DeferredDerefListEntry );
}
}
return TRUE;
} // DeCacheHelper
BOOL
DeCache(
PCACHE_OBJECT pCacheObject,
BOOL fLockCacheTable
)
/*++
Description:
This function removes this cache object from any list it may be on.
The cache table lock must be taken if fLockCacheTable is FALSE.
Arguments:
pCacheObject - Object to decache
fLockCacheTable - FALSE if the cache table lock has already been taken
--*/
{
LPTS_OPEN_FILE_INFO openFileInfo = NULL;
PPHYS_OPEN_FILE_INFO physFileInfo;
PCACHE_OBJECT physCacheObject;
PBLOB_HEADER blob;
ASSERT( pCacheObject->Signature == CACHE_OBJ_SIGNATURE );
if( fLockCacheTable ) {
EnterCriticalSection( &CacheTable.CriticalSection );
}
//
// Let the helper do the dirty work.
//
DeCacheHelper( pCacheObject, NULL, NULL );
if( fLockCacheTable ) {
LeaveCriticalSection( &CacheTable.CriticalSection );
}
return( TRUE );
}
BOOL
TsDeCacheCachedBlob(
PVOID pBlobPayload
)
/*++
Description:
This function removes a blob payload object from the cache
Arguments:
pCacheObject - Object to decache
--*/
{
return DeCache( (((PBLOB_HEADER)pBlobPayload)-1)->pCache, TRUE );
}