Source code of Windows XP (NT5)
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.

328 lines
8.2 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1995 - 2000 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: LockedCFPM.h
  6. * Content: fixed size pool manager for classes that has its own locking mechanism
  7. *
  8. * History:
  9. * Date By Reason
  10. * ====== == ======
  11. * 12-18-97 aarono Original
  12. * 11-06-98 ejs Add custom handler for Release function
  13. * 04-12-99 jtk Trimmed unused functions and parameters, added size assert
  14. * 01-31-2000 jtk Added code to check for items already being in the pool on Release().
  15. * 02-09-2000 jtk Dereived from ClassFPM.h
  16. ***************************************************************************/
  17. #ifndef __LOCKED_CLASS_FPM_H__
  18. #define __LOCKED_CLASS_FPM_H__
  19. #include "dndbg.h"
  20. #undef DPF_SUBCOMP
  21. #define DPF_SUBCOMP DN_SUBCOMP_COMMON
  22. //**********************************************************************
  23. // Constant definitions
  24. //**********************************************************************
  25. #define LOCKEDCFPM_BLANK_NODE_VALUE 0x5A5A817E
  26. #define CHECK_FOR_DUPLICATE_LOCKEDCFPM_RELEASE
  27. //**********************************************************************
  28. // Macro definitions
  29. //**********************************************************************
  30. #ifndef OFFSETOF
  31. // Macro to compute the offset of an element inside of a larger structure (copied from MSDEV's STDLIB.H)
  32. #define OFFSETOF(s,m) ( (INT_PTR) &(((s *)0)->m) )
  33. #define __LOCAL_OFFSETOF_DEFINED__
  34. #endif // OFFSETOF
  35. //**********************************************************************
  36. // Structure definitions
  37. //**********************************************************************
  38. //**********************************************************************
  39. // Variable definitions
  40. //**********************************************************************
  41. //**********************************************************************
  42. // Function prototypes
  43. //**********************************************************************
  44. //**********************************************************************
  45. // Class definitions
  46. //**********************************************************************
  47. // class to act as a link in the pool
  48. template< class T >
  49. class CLockedPoolNode
  50. {
  51. public:
  52. CLockedPoolNode() { m_pNext = NULL; }
  53. ~CLockedPoolNode() {};
  54. T m_Item;
  55. CLockedPoolNode *m_pNext;
  56. protected:
  57. private:
  58. };
  59. // class to manage the pool
  60. template< class T >
  61. class CLockedFixedPool
  62. {
  63. public:
  64. CLockedFixedPool();
  65. ~CLockedFixedPool();
  66. BOOL Initialize( void );
  67. void Deinitialize( void );
  68. void Lock( void ) { DNEnterCriticalSection( &m_Lock ); }
  69. void Unlock( void ) { DNLeaveCriticalSection( &m_Lock ); }
  70. T *Get( void );
  71. void Release( T *const pItem );
  72. protected:
  73. private:
  74. DNCRITICAL_SECTION m_Lock; // critical section
  75. CLockedPoolNode< T > *m_pPool; // pointer to list of available elements
  76. DEBUG_ONLY( UINT_PTR m_uOutstandingItemCount );
  77. DEBUG_ONLY( BOOL m_fInitialized );
  78. };
  79. //**********************************************************************
  80. // Class function definitions
  81. //**********************************************************************
  82. //**********************************************************************
  83. // ------------------------------
  84. // CLockedFixedPool::CLockedFixedPool - constructor
  85. //
  86. // Entry: Nothing
  87. //
  88. // Exit: Nothing
  89. // ------------------------------
  90. #undef DPF_MODNAME
  91. #define DPF_MODNAME "CLockedFixedPool::CLockedFixedPool"
  92. template< class T >
  93. CLockedFixedPool< T >::CLockedFixedPool():m_pPool( NULL )
  94. {
  95. DEBUG_ONLY( m_uOutstandingItemCount = 0 );
  96. DEBUG_ONLY( m_fInitialized = FALSE );
  97. }
  98. //**********************************************************************
  99. //**********************************************************************
  100. // ------------------------------
  101. // CLockedFixedPool::~CLockedFixedPool - destructor
  102. //
  103. // Entry: Nothing
  104. //
  105. // Exit: Nothing
  106. // ------------------------------
  107. #undef DPF_MODNAME
  108. #define DPF_MODNAME "CLockedFixedPool::~CLockedFixedPool"
  109. template< class T >
  110. CLockedFixedPool< T >::~CLockedFixedPool()
  111. {
  112. DEBUG_ONLY( DNASSERT( m_uOutstandingItemCount == 0 ) );
  113. DEBUG_ONLY( DNASSERT( m_fInitialized == FALSE ) );
  114. while ( m_pPool != NULL )
  115. {
  116. CLockedPoolNode< T > *pTemp;
  117. pTemp = m_pPool;
  118. m_pPool = m_pPool->m_pNext;
  119. delete pTemp;
  120. }
  121. }
  122. //**********************************************************************
  123. //**********************************************************************
  124. // ------------------------------
  125. // CLockedFixedPool::Initialize - initialize this pool
  126. //
  127. // Entry: Nothing
  128. //
  129. // Exit: Boolean indicating success
  130. // TRUE = success
  131. // FALSE = failure
  132. // ------------------------------
  133. #undef DPF_MODNAME
  134. #define DPF_MODNAME "CLockedFixedPool::Initialize"
  135. template< class T >
  136. BOOL CLockedFixedPool< T >::Initialize( void )
  137. {
  138. BOOL fReturn;
  139. DEBUG_ONLY( DNASSERT( m_fInitialized == FALSE ) );
  140. fReturn = TRUE;
  141. if ( DNInitializeCriticalSection( &m_Lock ) == FALSE )
  142. {
  143. fReturn = FALSE;
  144. }
  145. else
  146. {
  147. DebugSetCriticalSectionRecursionCount( &m_Lock, 0 );
  148. }
  149. DEBUG_ONLY( m_fInitialized = TRUE );
  150. return fReturn;
  151. }
  152. //**********************************************************************
  153. //**********************************************************************
  154. // ------------------------------
  155. // CLockedFixedPool::Deinitialize - deinitialize pool
  156. //
  157. // Entry: Nothing
  158. //
  159. // Exit: Nothing
  160. // ------------------------------
  161. #undef DPF_MODNAME
  162. #define DPF_MODNAME "CLockedFixedPool::Deinitialize"
  163. template< class T >
  164. void CLockedFixedPool< T >::Deinitialize( void )
  165. {
  166. DNDeleteCriticalSection( &m_Lock );
  167. DEBUG_ONLY( m_fInitialized = FALSE );
  168. }
  169. //**********************************************************************
  170. //**********************************************************************
  171. // ------------------------------
  172. // CLockedFixedPool::Get - get an item from the pool
  173. //
  174. // Entry: Nothing
  175. //
  176. // Exit: Pointer to item
  177. // NULL = out of memory
  178. // ------------------------------
  179. #undef DPF_MODNAME
  180. #define DPF_MODNAME "CLockedFixedPool::Get"
  181. template< class T >
  182. T *CLockedFixedPool< T >::Get( void )
  183. {
  184. CLockedPoolNode< T > *pNode;
  185. T *pReturn;
  186. DEBUG_ONLY( DNASSERT( m_fInitialized != FALSE ) );
  187. //
  188. // initialize
  189. //
  190. pReturn = NULL;
  191. Lock();
  192. //
  193. // If the pool is empty, create a new item. If the pool isn't empty, use
  194. // the first item in the pool
  195. //
  196. if ( m_pPool == NULL )
  197. {
  198. pNode = new CLockedPoolNode< T >;
  199. }
  200. else
  201. {
  202. pNode = m_pPool;
  203. m_pPool = m_pPool->m_pNext;
  204. }
  205. Unlock();
  206. if ( pNode != NULL )
  207. {
  208. DEBUG_ONLY( pNode->m_pNext = (CLockedPoolNode<T>*) LOCKEDCFPM_BLANK_NODE_VALUE );
  209. pReturn = &pNode->m_Item;
  210. DEBUG_ONLY( m_uOutstandingItemCount++ );
  211. }
  212. return pReturn;
  213. }
  214. //**********************************************************************
  215. //**********************************************************************
  216. // ------------------------------
  217. // CLockedFixedPool::Release - return item to pool
  218. //
  219. // Entry: Pointer to item
  220. //
  221. // Exit: Nothing
  222. // ------------------------------
  223. #undef DPF_MODNAME
  224. #define DPF_MODNAME "CLockedFixedPool::Release"
  225. template< class T >
  226. void CLockedFixedPool< T >::Release( T *const pItem )
  227. {
  228. CLockedPoolNode< T > *pNode;
  229. DEBUG_ONLY( DNASSERT( m_fInitialized != FALSE ) );
  230. DNASSERT( pItem != NULL );
  231. DBG_CASSERT( sizeof( BYTE* ) == sizeof( pItem ) );
  232. DBG_CASSERT( sizeof( CLockedPoolNode< T >* ) == sizeof( BYTE* ) );
  233. pNode = reinterpret_cast<CLockedPoolNode< T >*>( &reinterpret_cast<BYTE*>( pItem )[ -OFFSETOF( CLockedPoolNode< T >, m_Item ) ] );
  234. Lock();
  235. #if defined(CHECK_FOR_DUPLICATE_LOCKEDCFPM_RELEASE) && defined(DEBUG)
  236. {
  237. CLockedPoolNode< T > *pTemp;
  238. pTemp = m_pPool;
  239. while ( pTemp != NULL )
  240. {
  241. DNASSERT( pTemp != pNode );
  242. pTemp = pTemp->m_pNext;
  243. }
  244. }
  245. #endif // CHECK_FOR_DUPLICATE_LOCKEDCFPM_RELEASE
  246. DNASSERT( pNode->m_pNext == (CLockedPoolNode< T >*)LOCKEDCFPM_BLANK_NODE_VALUE );
  247. #ifdef NO_POOLS
  248. delete pNode;
  249. #else
  250. pNode->m_pNext = m_pPool;
  251. m_pPool = pNode;
  252. #endif
  253. DEBUG_ONLY( m_uOutstandingItemCount-- );
  254. Unlock();
  255. }
  256. //**********************************************************************
  257. #ifdef __LOCAL_OFFSETOF_DEFINED__
  258. #undef __LOCAL_OFFSETOF_DEFINED__
  259. #undef OFFSETOF
  260. #endif // __LOCAL_OFFSETOF_DEFINED__
  261. #undef DPF_MODNAME
  262. #undef DPF_SUBCOMP
  263. #endif // __LOCKED_CLASS_FPM_H__