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.

391 lines
7.1 KiB

  1. #ifndef __QUEUE_CPP
  2. #define __QUEUE_CPP
  3. /*
  4. * Class:
  5. *
  6. * WmiAllocator
  7. *
  8. * Description:
  9. *
  10. * Provides abstraction above heap allocation functions
  11. *
  12. * Version:
  13. *
  14. * Initial
  15. *
  16. * Last Changed:
  17. *
  18. * See Source Depot for change history
  19. *
  20. */
  21. /******************************************************************************
  22. *
  23. * Name:
  24. *
  25. *
  26. * Description:
  27. *
  28. *
  29. *****************************************************************************/
  30. template <class WmiElement, ULONG ElementSize>
  31. WmiQueue <WmiElement,ElementSize> :: WmiQueue <WmiElement,ElementSize> (
  32. WmiAllocator &a_Allocator
  33. ) : m_Allocator ( a_Allocator ) ,
  34. m_Size ( 0 ) ,
  35. m_Top ( NULL ) ,
  36. m_Tail ( NULL ) ,
  37. m_TopIndex ( NULL ) ,
  38. m_TailIndex ( NULL ) ,
  39. m_AllocatedSize ( 0 )
  40. {
  41. }
  42. /******************************************************************************
  43. *
  44. * Name:
  45. *
  46. *
  47. * Description:
  48. *
  49. *
  50. *****************************************************************************/
  51. template <class WmiElement, ULONG ElementSize>
  52. WmiQueue <WmiElement,ElementSize > :: ~WmiQueue <WmiElement,ElementSize> ()
  53. {
  54. WmiStatusCode t_StatusCode = UnInitialize () ;
  55. }
  56. /******************************************************************************
  57. *
  58. * Name:
  59. *
  60. *
  61. * Description:
  62. *
  63. *
  64. *****************************************************************************/
  65. template <class WmiElement, ULONG ElementSize>
  66. WmiStatusCode WmiQueue <WmiElement,ElementSize > :: Initialize ()
  67. {
  68. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  69. if ( ElementSize < 31 )
  70. {
  71. t_StatusCode = Grow_ElementDir () ;
  72. }
  73. else
  74. {
  75. t_StatusCode = e_StatusCode_InvalidArgs ;
  76. }
  77. return t_StatusCode ;
  78. }
  79. /******************************************************************************
  80. *
  81. * Name:
  82. *
  83. *
  84. * Description:
  85. *
  86. *
  87. *****************************************************************************/
  88. template <class WmiElement, ULONG ElementSize>
  89. WmiStatusCode WmiQueue <WmiElement,ElementSize > :: UnInitialize ()
  90. {
  91. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  92. if ( m_AllocatedSize )
  93. {
  94. t_StatusCode = UnInitialize_ElementDir ( m_AllocatedSize ) ;
  95. }
  96. return t_StatusCode ;
  97. }
  98. /******************************************************************************
  99. *
  100. * Name:
  101. *
  102. *
  103. * Description:
  104. *
  105. *
  106. *****************************************************************************/
  107. template <class WmiElement, ULONG ElementSize>
  108. WmiStatusCode WmiQueue <WmiElement,ElementSize > :: EnQueue (
  109. const WmiElement &a_Element
  110. )
  111. {
  112. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  113. if ( ! m_AllocatedSize )
  114. {
  115. t_StatusCode = Initialize () ;
  116. }
  117. if ( t_StatusCode == e_StatusCode_Success )
  118. {
  119. m_TailIndex ++ ;
  120. if ( m_TailIndex == ( QUEUE_ELEMENT_DIR_SIZE ) )
  121. {
  122. WmiElementDir *t_Tail = m_Tail ;
  123. ULONG t_TailIndex = m_TailIndex ;
  124. t_StatusCode = Grow_ElementDir () ;
  125. if ( t_StatusCode != e_StatusCode_Success )
  126. {
  127. m_TailIndex -- ;
  128. }
  129. else
  130. {
  131. try
  132. {
  133. t_Tail->m_Block [ t_TailIndex - 1 ] = a_Element ;
  134. m_Size ++ ;
  135. }
  136. catch ( Wmi_Heap_Exception &a_Exception )
  137. {
  138. m_TailIndex -- ;
  139. return e_StatusCode_OutOfMemory ;
  140. }
  141. catch ( ... )
  142. {
  143. m_TailIndex -- ;
  144. return e_StatusCode_Unknown ;
  145. }
  146. }
  147. }
  148. else
  149. {
  150. try
  151. {
  152. m_Tail->m_Block [ m_TailIndex - 1 ] = a_Element ;
  153. m_Size ++ ;
  154. }
  155. catch ( Wmi_Heap_Exception &a_Exception )
  156. {
  157. m_TailIndex -- ;
  158. return e_StatusCode_OutOfMemory ;
  159. }
  160. catch ( ... )
  161. {
  162. m_TailIndex -- ;
  163. return e_StatusCode_Unknown ;
  164. }
  165. }
  166. }
  167. return t_StatusCode ;
  168. }
  169. /******************************************************************************
  170. *
  171. * Name:
  172. *
  173. *
  174. * Description:
  175. *
  176. *
  177. *****************************************************************************/
  178. template <class WmiElement, ULONG ElementSize>
  179. WmiStatusCode WmiQueue <WmiElement,ElementSize > :: Top ( WmiElement &a_Element )
  180. {
  181. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  182. if ( ! ( ( m_Top == m_Tail ) && ( m_TopIndex == m_TailIndex ) ) )
  183. {
  184. try
  185. {
  186. a_Element = m_Top->m_Block [ m_TopIndex ] ;
  187. }
  188. catch ( Wmi_Heap_Exception &a_Exception )
  189. {
  190. return e_StatusCode_OutOfMemory ;
  191. }
  192. catch ( ... )
  193. {
  194. return e_StatusCode_Unknown ;
  195. }
  196. }
  197. else
  198. {
  199. t_StatusCode = e_StatusCode_NotInitialized ;
  200. }
  201. return t_StatusCode ;
  202. }
  203. /******************************************************************************
  204. *
  205. * Name:
  206. *
  207. *
  208. * Description:
  209. *
  210. *
  211. *****************************************************************************/
  212. template <class WmiElement, ULONG ElementSize>
  213. WmiStatusCode WmiQueue <WmiElement,ElementSize > :: DeQueue ()
  214. {
  215. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  216. if ( ! ( ( m_Top == m_Tail ) && ( m_TopIndex == m_TailIndex ) ) )
  217. {
  218. m_TopIndex ++ ;
  219. if ( m_TopIndex == ( QUEUE_ELEMENT_DIR_SIZE ) )
  220. {
  221. t_StatusCode = Shrink_ElementDir () ;
  222. m_TopIndex = 0 ;
  223. }
  224. m_Size -- ;
  225. }
  226. else
  227. {
  228. t_StatusCode = e_StatusCode_NotInitialized ;
  229. }
  230. return t_StatusCode ;
  231. }
  232. /******************************************************************************
  233. *
  234. * Name:
  235. *
  236. *
  237. * Description:
  238. *
  239. *
  240. *****************************************************************************/
  241. template <class WmiElement, ULONG ElementSize>
  242. WmiStatusCode WmiQueue <WmiElement,ElementSize > :: UnInitialize_ElementDir (
  243. ULONG a_Size
  244. )
  245. {
  246. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  247. WmiElementDir *t_Current = m_Tail ;
  248. while ( t_Current )
  249. {
  250. WmiElementDir *t_Next = t_Current->m_Next ;
  251. t_Current->~WmiElementDir () ;
  252. t_StatusCode = m_Allocator.Delete (
  253. ( void * ) t_Current
  254. ) ;
  255. t_Current = t_Next ;
  256. }
  257. m_Size = m_AllocatedSize = 0 ;
  258. m_Top = m_Tail = NULL ;
  259. m_TopIndex = m_TailIndex = 0 ;
  260. return t_StatusCode ;
  261. }
  262. /******************************************************************************
  263. *
  264. * Name:
  265. *
  266. *
  267. * Description:
  268. *
  269. *
  270. *****************************************************************************/
  271. template <class WmiElement, ULONG ElementSize>
  272. WmiStatusCode WmiQueue <WmiElement,ElementSize > :: Grow_ElementDir ()
  273. {
  274. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  275. WmiElementDir *t_Tail = NULL ;
  276. t_StatusCode = m_Allocator.New (
  277. ( void ** ) & t_Tail ,
  278. sizeof ( WmiElementDir )
  279. ) ;
  280. if ( t_StatusCode == e_StatusCode_Success )
  281. {
  282. :: new ( ( void * ) t_Tail ) WmiElementDir ;
  283. if ( m_Tail )
  284. {
  285. m_Tail->m_Next = t_Tail ;
  286. }
  287. else
  288. {
  289. m_Top = t_Tail ;
  290. }
  291. m_Tail = t_Tail ;
  292. m_TailIndex = 0 ;
  293. m_AllocatedSize = m_AllocatedSize + ( QUEUE_ELEMENT_DIR_SIZE ) ;
  294. }
  295. return t_StatusCode ;
  296. }
  297. /******************************************************************************
  298. *
  299. * Name:
  300. *
  301. *
  302. * Description:
  303. *
  304. *
  305. *****************************************************************************/
  306. template <class WmiElement, ULONG ElementSize>
  307. WmiStatusCode WmiQueue <WmiElement,ElementSize > :: Shrink_ElementDir ()
  308. {
  309. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  310. if ( m_Top )
  311. {
  312. WmiElementDir *t_Next = m_Top->m_Next ;
  313. m_Top->~WmiElementDir () ;
  314. t_StatusCode = m_Allocator.Delete (
  315. ( void * ) m_Top
  316. ) ;
  317. m_Top = t_Next ;
  318. m_AllocatedSize = m_AllocatedSize - ( QUEUE_ELEMENT_DIR_SIZE ) ;
  319. }
  320. return t_StatusCode ;
  321. }
  322. #endif __QUEUE_CPP