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

  1. /*-----------------------------------------------------------------------------
  2. *
  3. * File: ifaccach.h
  4. * Author: Samuel Clement (samclem)
  5. * Date: Wed Sep 01 14:36:33 1999
  6. *
  7. * Copyright (c) 1999 Microsoft Corporation
  8. *
  9. * Description:
  10. * This contains the declarations of the templated interface caching
  11. * objects. These are local objects which have a referance count.
  12. *
  13. * Usage: CInterfaceCache<string,IUnknown>* pUnkCache;
  14. * pFoo = pFooCache->GetFromCache( "foo" );
  15. * if ( pFoo )
  16. * pUnkCache->AddToCache( "foo", pFoo );
  17. *
  18. * History:
  19. * 01 Sep 1999: Created.
  20. *----------------------------------------------------------------------------*/
  21. #ifndef _IFACCACH_H_
  22. #define _IFACCACH_H_
  23. template<class K, class T>
  24. class CInterfaceCache
  25. {
  26. public:
  27. DECLARE_TRACKED_OBJECT
  28. CInterfaceCache() : m_cRefs( 0 )
  29. {
  30. TRACK_OBJECT("CInterfaceCache");
  31. }
  32. ~CInterfaceCache()
  33. {
  34. // we need to release all our interfaces by
  35. // iterating over our map.
  36. CCacheEntry* pEntry;
  37. CCacheMap::iterator it = m_cacheMap.begin();
  38. for ( ; it != m_cacheMap.end(); it++ )
  39. {
  40. pEntry = it->second;
  41. Assert( pEntry != NULL );
  42. delete pEntry;
  43. }
  44. // clear the map so its empty
  45. m_cacheMap.clear();
  46. }
  47. inline bool HasRefs() { return ( m_cRefs > 0 ); }
  48. inline void AddRef() { m_cRefs++; TraceTag((0, "CInterfaceCahe: addref: %ld", m_cRefs )); }
  49. inline void Release() { m_cRefs--; TraceTag((0, "CInterfaceCahe: release: %ld", m_cRefs )); }
  50. // returns the cached pointer, non-AddRef'd
  51. // if the caller wants to hold it then they
  52. // need to AddRef it.
  53. inline T* GetFromCache( K key )
  54. {
  55. CCacheEntry* pEntry = m_cacheMap[key];
  56. if ( !pEntry )
  57. return NULL;
  58. else
  59. return reinterpret_cast<T*>(pEntry->GetCOMPtr());
  60. }
  61. // Adds the pointer to the map. IF the key
  62. // already exists then this will simply overwrite
  63. // that one, freeing the existing one
  64. inline bool AddToCache( K key, T* pT )
  65. {
  66. Assert( pT != NULL );
  67. RemoveFromCache( key );
  68. CCacheEntry* pEntry = new CCacheEntry( reinterpret_cast<IUnknown*>(pT) );
  69. if ( !pEntry )
  70. return false;
  71. m_cacheMap[key] = pEntry;
  72. return true;
  73. }
  74. // remove the specified key from the cache, returns true if it
  75. // was there or false if it was not
  76. inline bool RemoveFromCache( const K& key )
  77. {
  78. CCacheEntry* pEntry = m_cacheMap[key];
  79. if ( pEntry )
  80. delete pEntry;
  81. return ( m_cacheMap.erase( key ) != 0 );
  82. }
  83. private:
  84. class CCacheEntry
  85. {
  86. public:
  87. CCacheEntry( IUnknown* pif ) : m_pInterface( pif )
  88. {
  89. // add a referance, this forces the interface to
  90. // live for the duration of our lifetime. we we are
  91. // destroyed we will release the last referance on
  92. // the interface.
  93. Assert( m_pInterface );
  94. m_pInterface->AddRef();
  95. }
  96. ~CCacheEntry()
  97. {
  98. m_pInterface->Release();
  99. m_pInterface = NULL;
  100. }
  101. inline IUnknown* GetCOMPtr() { return m_pInterface; }
  102. private:
  103. IUnknown* m_pInterface;
  104. };
  105. private:
  106. typedef std::map<K,CCacheEntry*> CCacheMap;
  107. CCacheMap m_cacheMap;
  108. long m_cRefs;
  109. };
  110. #endif //_IFACCACH_H_