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.
 
 
 
 
 
 

129 lines
3.1 KiB

/*-----------------------------------------------------------------------------
*
* File: ifaccach.h
* Author: Samuel Clement (samclem)
* Date: Wed Sep 01 14:36:33 1999
*
* Copyright (c) 1999 Microsoft Corporation
*
* Description:
* This contains the declarations of the templated interface caching
* objects. These are local objects which have a referance count.
*
* Usage: CInterfaceCache<string,IUnknown>* pUnkCache;
* pFoo = pFooCache->GetFromCache( "foo" );
* if ( pFoo )
* pUnkCache->AddToCache( "foo", pFoo );
*
* History:
* 01 Sep 1999: Created.
*----------------------------------------------------------------------------*/
#ifndef _IFACCACH_H_
#define _IFACCACH_H_
template<class K, class T>
class CInterfaceCache
{
public:
DECLARE_TRACKED_OBJECT
CInterfaceCache() : m_cRefs( 0 )
{
TRACK_OBJECT("CInterfaceCache");
}
~CInterfaceCache()
{
// we need to release all our interfaces by
// iterating over our map.
CCacheEntry* pEntry;
CCacheMap::iterator it = m_cacheMap.begin();
for ( ; it != m_cacheMap.end(); it++ )
{
pEntry = it->second;
Assert( pEntry != NULL );
delete pEntry;
}
// clear the map so its empty
m_cacheMap.clear();
}
inline bool HasRefs() { return ( m_cRefs > 0 ); }
inline void AddRef() { m_cRefs++; TraceTag((0, "CInterfaceCahe: addref: %ld", m_cRefs )); }
inline void Release() { m_cRefs--; TraceTag((0, "CInterfaceCahe: release: %ld", m_cRefs )); }
// returns the cached pointer, non-AddRef'd
// if the caller wants to hold it then they
// need to AddRef it.
inline T* GetFromCache( K key )
{
CCacheEntry* pEntry = m_cacheMap[key];
if ( !pEntry )
return NULL;
else
return reinterpret_cast<T*>(pEntry->GetCOMPtr());
}
// Adds the pointer to the map. IF the key
// already exists then this will simply overwrite
// that one, freeing the existing one
inline bool AddToCache( K key, T* pT )
{
Assert( pT != NULL );
RemoveFromCache( key );
CCacheEntry* pEntry = new CCacheEntry( reinterpret_cast<IUnknown*>(pT) );
if ( !pEntry )
return false;
m_cacheMap[key] = pEntry;
return true;
}
// remove the specified key from the cache, returns true if it
// was there or false if it was not
inline bool RemoveFromCache( const K& key )
{
CCacheEntry* pEntry = m_cacheMap[key];
if ( pEntry )
delete pEntry;
return ( m_cacheMap.erase( key ) != 0 );
}
private:
class CCacheEntry
{
public:
CCacheEntry( IUnknown* pif ) : m_pInterface( pif )
{
// add a referance, this forces the interface to
// live for the duration of our lifetime. we we are
// destroyed we will release the last referance on
// the interface.
Assert( m_pInterface );
m_pInterface->AddRef();
}
~CCacheEntry()
{
m_pInterface->Release();
m_pInterface = NULL;
}
inline IUnknown* GetCOMPtr() { return m_pInterface; }
private:
IUnknown* m_pInterface;
};
private:
typedef std::map<K,CCacheEntry*> CCacheMap;
CCacheMap m_cacheMap;
long m_cRefs;
};
#endif //_IFACCACH_H_