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.

954 lines
19 KiB

  1. #ifndef __CACHE_CPP
  2. #define __CACHE_CPP
  3. /*++
  4. Copyright (C) 1996-2001 Microsoft Corporation
  5. Module Name:
  6. Thread.cpp
  7. Abstract:
  8. Enhancements to current functionality:
  9. Timeout mechanism should track across waits.
  10. AddRef/Release on task when scheduling.
  11. Enhancement Ticker logic.
  12. History:
  13. --*/
  14. #include <HelperFuncs.h>
  15. /******************************************************************************
  16. *
  17. * Name:
  18. *
  19. *
  20. * Description:
  21. *
  22. *
  23. *****************************************************************************/
  24. template <class WmiKey>
  25. LONG operator == ( const WmiCacheController <WmiKey> :: WmiUniqueTimeout &a_Arg1 , const WmiCacheController <WmiKey> :: WmiUniqueTimeout &a_Arg2 )
  26. {
  27. LONG t_Compare ;
  28. if ( ( t_Compare = a_Arg1.GetTicks () - a_Arg2.GetTicks () ) == 0 )
  29. {
  30. t_Compare = a_Arg1.GetCounter () - a_Arg2.GetCounter () ;
  31. }
  32. return t_Compare == 0 ? true : false ;
  33. }
  34. template <class WmiKey>
  35. bool operator < ( const WmiCacheController <WmiKey> :: WmiUniqueTimeout &a_Arg1 , const WmiCacheController <WmiKey> :: WmiUniqueTimeout &a_Arg2 )
  36. {
  37. LONG t_Compare ;
  38. if ( ( t_Compare = a_Arg1.GetTicks () - a_Arg2.GetTicks () ) == 0 )
  39. {
  40. t_Compare = a_Arg1.GetCounter () - a_Arg2.GetCounter () ;
  41. }
  42. return t_Compare < 0 ? true : false ;
  43. }
  44. /******************************************************************************
  45. *
  46. * Name:
  47. *
  48. *
  49. * Description:
  50. *
  51. *
  52. *****************************************************************************/
  53. template <class WmiKey>
  54. WmiCacheController <WmiKey> :: WmiCacheController (
  55. WmiAllocator &a_Allocator
  56. ) : m_Allocator ( a_Allocator ) ,
  57. m_Cache ( a_Allocator ) ,
  58. m_CacheDecay ( a_Allocator ) ,
  59. m_ReferenceCount ( 0 ) ,
  60. m_Counter ( 0 ),
  61. m_CriticalSection(NOTHROW_LOCK)
  62. {
  63. }
  64. /******************************************************************************
  65. *
  66. * Name:
  67. *
  68. *
  69. * Description:
  70. *
  71. *
  72. *****************************************************************************/
  73. template <class WmiKey>
  74. WmiCacheController <WmiKey> :: ~WmiCacheController ()
  75. {
  76. }
  77. /******************************************************************************
  78. *
  79. * Name:
  80. *
  81. *
  82. * Description:
  83. *
  84. *
  85. *****************************************************************************/
  86. template <class WmiKey>
  87. STDMETHODIMP_( ULONG ) WmiCacheController <WmiKey> :: AddRef ()
  88. {
  89. return InterlockedIncrement ( & m_ReferenceCount ) ;
  90. }
  91. /******************************************************************************
  92. *
  93. * Name:
  94. *
  95. *
  96. * Description:
  97. *
  98. *
  99. *****************************************************************************/
  100. template <class WmiKey>
  101. STDMETHODIMP_( ULONG ) WmiCacheController <WmiKey> :: Release ()
  102. {
  103. ULONG t_ReferenceCount = InterlockedDecrement ( & m_ReferenceCount ) ;
  104. if ( t_ReferenceCount == 0 )
  105. {
  106. delete this ;
  107. }
  108. return t_ReferenceCount ;
  109. }
  110. /******************************************************************************
  111. *
  112. * Name:
  113. *
  114. *
  115. * Description:
  116. *
  117. *
  118. *****************************************************************************/
  119. template <class WmiKey>
  120. STDMETHODIMP WmiCacheController <WmiKey> :: QueryInterface ( REFIID , LPVOID FAR * )
  121. {
  122. return E_NOINTERFACE ;
  123. }
  124. /******************************************************************************
  125. *
  126. * Name:
  127. *
  128. *
  129. * Description:
  130. *
  131. *
  132. *****************************************************************************/
  133. template <class WmiKey>
  134. WmiStatusCode WmiCacheController <WmiKey> :: Initialize ()
  135. {
  136. WmiStatusCode t_StatusCode = m_Cache.Initialize () ;
  137. if ( t_StatusCode == e_StatusCode_Success )
  138. {
  139. t_StatusCode = m_CacheDecay.Initialize () ;
  140. if ( t_StatusCode == e_StatusCode_Success )
  141. {
  142. t_StatusCode = WmiHelper :: InitializeCriticalSection ( & m_CriticalSection ) ;
  143. }
  144. }
  145. return t_StatusCode ;
  146. }
  147. /******************************************************************************
  148. *
  149. * Name:
  150. *
  151. *
  152. * Description:
  153. *
  154. *
  155. *****************************************************************************/
  156. template <class WmiKey>
  157. WmiStatusCode WmiCacheController <WmiKey> :: UnInitialize ()
  158. {
  159. WmiStatusCode t_StatusCode = m_Cache.UnInitialize () ;
  160. if ( t_StatusCode == e_StatusCode_Success )
  161. {
  162. t_StatusCode = m_CacheDecay.UnInitialize () ;
  163. }
  164. WmiHelper :: DeleteCriticalSection ( & m_CriticalSection ) ;
  165. return t_StatusCode ;
  166. }
  167. /******************************************************************************
  168. *
  169. * Name:
  170. *
  171. *
  172. * Description:
  173. *
  174. *
  175. *****************************************************************************/
  176. template <class WmiKey>
  177. WmiStatusCode WmiCacheController <WmiKey> :: Insert (
  178. WmiCacheElement &a_Element ,
  179. Cache_Iterator &a_Iterator
  180. )
  181. {
  182. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  183. Lock () ;
  184. Cache_Iterator t_Iterator ;
  185. t_StatusCode = m_Cache.Insert ( a_Element.GetKey () , & a_Element , t_Iterator ) ;
  186. if ( t_StatusCode == e_StatusCode_Success )
  187. {
  188. a_Element.InternalAddRef () ;
  189. a_Element.SetCached ( TRUE ) ;
  190. }
  191. UnLock () ;
  192. return t_StatusCode ;
  193. }
  194. /******************************************************************************
  195. *
  196. * Name:
  197. *
  198. *
  199. * Description:
  200. *
  201. *
  202. *****************************************************************************/
  203. template <class WmiKey>
  204. WmiStatusCode WmiCacheController <WmiKey> :: Delete (
  205. const WmiKey &a_Key
  206. )
  207. {
  208. Lock () ;
  209. WmiStatusCode t_StatusCode = m_Cache.Delete ( a_Key ) ;
  210. UnLock () ;
  211. return t_StatusCode ;
  212. }
  213. /******************************************************************************
  214. *
  215. * Name:
  216. *
  217. *
  218. * Description:
  219. *
  220. *
  221. *****************************************************************************/
  222. template <class WmiKey>
  223. WmiStatusCode WmiCacheController <WmiKey> :: Find (
  224. const WmiKey &a_Key ,
  225. Cache_Iterator &a_Iterator
  226. )
  227. {
  228. Lock () ;
  229. WmiStatusCode t_StatusCode = m_Cache.Find ( a_Key , a_Iterator ) ;
  230. if ( t_StatusCode == e_StatusCode_Success )
  231. {
  232. a_Iterator.GetElement ()->AddRef ( ) ;
  233. }
  234. UnLock () ;
  235. return t_StatusCode ;
  236. }
  237. /******************************************************************************
  238. *
  239. * Name:
  240. *
  241. *
  242. * Description:
  243. *
  244. *
  245. *****************************************************************************/
  246. template <class WmiKey>
  247. WmiStatusCode WmiCacheController <WmiKey> :: Lock ()
  248. {
  249. WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection ( & m_CriticalSection ) ;
  250. return t_StatusCode ;
  251. }
  252. /******************************************************************************
  253. *
  254. * Name:
  255. *
  256. *
  257. * Description:
  258. *
  259. *
  260. *****************************************************************************/
  261. template <class WmiKey>
  262. WmiStatusCode WmiCacheController <WmiKey> :: UnLock ()
  263. {
  264. WmiStatusCode t_StatusCode = WmiHelper :: LeaveCriticalSection ( & m_CriticalSection ) ;
  265. return t_StatusCode ;
  266. }
  267. /******************************************************************************
  268. *
  269. * Name:
  270. *
  271. *
  272. * Description:
  273. *
  274. *
  275. *****************************************************************************/
  276. template <class WmiKey>
  277. WmiStatusCode WmiCacheController <WmiKey> :: Shutdown ()
  278. {
  279. Lock () ;
  280. ULONG t_Index = 0 ;
  281. while ( true )
  282. {
  283. WmiUniqueTimeout t_Key ;
  284. WmiCacheElement *t_Element = NULL ;
  285. WmiStatusCode t_StatusCode = m_CacheDecay.Top ( t_Key , t_Element ) ;
  286. if ( t_StatusCode == e_StatusCode_Success )
  287. {
  288. t_Index ++ ;
  289. t_StatusCode = m_CacheDecay.DeQueue () ;
  290. }
  291. else
  292. {
  293. break ;
  294. }
  295. }
  296. ULONG t_ElementCount = m_Cache.Size () ;
  297. WmiCacheElement **t_Elements = NULL ;
  298. WmiStatusCode t_StatusCode = m_Allocator.New (
  299. ( void ** ) & t_Elements ,
  300. sizeof ( WmiCacheElement ) * t_ElementCount
  301. ) ;
  302. if ( t_StatusCode == e_StatusCode_Success )
  303. {
  304. for ( ULONG t_Index = 0 ; t_Index < t_ElementCount ; t_Index ++ )
  305. {
  306. t_Elements [ t_Index ] = NULL ;
  307. }
  308. ULONG t_ElementIndex = 0 ;
  309. Cache_Iterator t_Iterator = m_Cache.Root ();
  310. while ( ! t_Iterator.Null () )
  311. {
  312. if ( t_Iterator.GetElement ()->GetDecayed () == FALSE )
  313. {
  314. WmiCacheElement *t_Element = t_Iterator.GetElement () ;
  315. t_Elements [ t_ElementIndex ] = t_Element ;
  316. t_Element->SetDecayed ( TRUE ) ;
  317. t_Element->SetDecaying ( FALSE ) ;
  318. t_Element->SetCached ( FALSE ) ;
  319. m_Cache.Delete ( t_Iterator.GetKey () ) ;
  320. }
  321. else
  322. {
  323. m_Cache.Delete ( t_Iterator.GetKey () ) ;
  324. }
  325. t_ElementIndex ++ ;
  326. t_Iterator = m_Cache.Root () ;
  327. }
  328. }
  329. UnLock () ;
  330. if ( t_Elements )
  331. {
  332. for ( ULONG t_Index = 0 ; t_Index < t_ElementCount ; t_Index ++ )
  333. {
  334. if ( t_Elements [ t_Index ] )
  335. {
  336. t_Elements [ t_Index ]->InternalRelease () ;
  337. }
  338. }
  339. m_Allocator.Delete ( t_Elements ) ;
  340. }
  341. return e_StatusCode_Success ;
  342. }
  343. /******************************************************************************
  344. *
  345. * Name:
  346. *
  347. *
  348. * Description:
  349. *
  350. *
  351. *****************************************************************************/
  352. template <class WmiKey>
  353. WmiStatusCode WmiCacheController <WmiKey> :: Shutdown ( const WmiKey &a_Key )
  354. {
  355. Lock () ;
  356. Cache_Iterator t_Iterator ;
  357. WmiStatusCode t_StatusCode = m_Cache.Find ( a_Key , t_Iterator ) ;
  358. if ( t_StatusCode == e_StatusCode_Success )
  359. {
  360. if ( t_Iterator.GetElement ()->GetDecayed () == FALSE )
  361. {
  362. CacheDecay_Iterator t_QueueIterator = m_CacheDecay.Begin () ;
  363. while ( ! t_QueueIterator.Null () )
  364. {
  365. WmiCacheElement *t_Element = t_QueueIterator.GetElement () ;
  366. if ( t_Element == t_Iterator.GetElement () )
  367. {
  368. m_CacheDecay.Delete ( t_QueueIterator.GetKey () ) ;
  369. break ;
  370. }
  371. t_QueueIterator.Increment () ;
  372. }
  373. WmiCacheElement *t_Element = t_Iterator.GetElement () ;
  374. t_Element->SetDecayed ( TRUE ) ;
  375. t_Element->SetDecaying ( FALSE ) ;
  376. t_Element->SetCached ( FALSE ) ;
  377. m_Cache.Delete ( a_Key ) ;
  378. UnLock () ;
  379. t_Element->InternalRelease () ;
  380. }
  381. else
  382. {
  383. m_Cache.Delete ( a_Key ) ;
  384. UnLock () ;
  385. }
  386. }
  387. else
  388. {
  389. UnLock () ;
  390. }
  391. return e_StatusCode_Success ;
  392. }
  393. /******************************************************************************
  394. *
  395. * Name:
  396. *
  397. *
  398. * Description:
  399. *
  400. *
  401. *****************************************************************************/
  402. template <class WmiKey>
  403. WmiStatusCode WmiCacheController <WmiKey> :: StrobeBegin ( const ULONG &a_Timeout )
  404. {
  405. return e_StatusCode_Success ;
  406. }
  407. /******************************************************************************
  408. *
  409. * Name:
  410. *
  411. *
  412. * Description:
  413. *
  414. *
  415. *****************************************************************************/
  416. template <class WmiKey>
  417. WmiStatusCode WmiCacheController <WmiKey> :: Strobe ( ULONG &a_NextStrobeDelta )
  418. {
  419. while ( true )
  420. {
  421. Lock () ;
  422. WmiUniqueTimeout t_Key ;
  423. WmiCacheElement *t_Element = NULL ;
  424. WmiStatusCode t_StatusCode = m_CacheDecay.Top ( t_Key , t_Element ) ;
  425. if ( t_StatusCode == e_StatusCode_Success )
  426. {
  427. a_NextStrobeDelta = ( a_NextStrobeDelta < t_Element->GetPeriod () ) ? a_NextStrobeDelta : t_Element->GetPeriod () ;
  428. ULONG t_Ticks = GetTickCount () ;
  429. #if 0
  430. wchar_t t_Buffer [ 128 ] ;
  431. wsprintf ( t_Buffer , L"\n%lx - Checking ( %lx , %lx ) " , t_Ticks , t_Element , t_Key.GetTicks () ) ;
  432. OutputDebugString ( t_Buffer ) ;
  433. #endif
  434. if ( t_Ticks >= t_Key.GetTicks () )
  435. {
  436. if ( t_Element->GetDecaying () )
  437. {
  438. #if 0
  439. wchar_t t_Buffer [ 128 ] ;
  440. wsprintf ( t_Buffer , L"\n%lx - Strobe ( %lx , %lx ) " , t_Ticks , t_Element , t_Key.GetTicks () ) ;
  441. OutputDebugString ( t_Buffer ) ;
  442. #endif
  443. t_Element->SetDecaying ( FALSE ) ;
  444. t_Element->SetDecayed ( TRUE ) ;
  445. t_StatusCode = m_CacheDecay.DeQueue () ;
  446. UnLock () ;
  447. t_Element->InternalRelease () ;
  448. }
  449. else
  450. {
  451. t_StatusCode = m_CacheDecay.DeQueue () ;
  452. UnLock () ;
  453. }
  454. }
  455. else
  456. {
  457. UnLock () ;
  458. break ;
  459. }
  460. }
  461. else
  462. {
  463. UnLock () ;
  464. break ;
  465. }
  466. }
  467. return e_StatusCode_Success ;
  468. }
  469. /******************************************************************************
  470. *
  471. * Name:
  472. *
  473. *
  474. * Description:
  475. *
  476. *
  477. *****************************************************************************/
  478. template <class WmiKey>
  479. WmiStatusCode WmiCacheController <WmiKey> :: Decay (
  480. WmiCacheElement &a_Element
  481. )
  482. {
  483. Lock () ;
  484. ULONG t_Size = m_CacheDecay.Size () ;
  485. Cache_Iterator t_Iterator ;
  486. WmiStatusCode t_StatusCode = m_Cache.Find ( a_Element.GetKey () , t_Iterator ) ;
  487. if ( t_StatusCode == e_StatusCode_Success )
  488. {
  489. BOOL t_Found = FALSE ;
  490. CacheDecay_Iterator t_QueueIterator = m_CacheDecay.Begin () ;
  491. while ( ! t_QueueIterator.Null () )
  492. {
  493. WmiCacheElement *t_Element = t_QueueIterator.GetElement () ;
  494. if ( t_Element == & a_Element )
  495. {
  496. m_CacheDecay.Delete ( t_QueueIterator.GetKey () ) ;
  497. break ;
  498. }
  499. t_QueueIterator.Increment () ;
  500. }
  501. ULONG t_Ticks = GetTickCount () ;
  502. WmiUniqueTimeout t_Key (
  503. t_Ticks + a_Element.GetPeriod () ,
  504. InterlockedIncrement ( & m_Counter )
  505. ) ;
  506. #if 0
  507. wchar_t t_Buffer [ 128 ] ;
  508. wsprintf ( t_Buffer , L"\n%lx - Decaying ( %lx , %lx , %lx ) " , t_Ticks , & a_Element , t_Ticks + a_Element.GetPeriod () , a_Element.GetPeriod () ) ;
  509. OutputDebugString ( t_Buffer ) ;
  510. #endif
  511. t_StatusCode = m_CacheDecay.EnQueue (
  512. t_Key ,
  513. t_Iterator.GetElement ()
  514. ) ;
  515. UnLock () ;
  516. if ( t_Size == 0 )
  517. {
  518. StrobeBegin ( a_Element.GetPeriod () ) ;
  519. }
  520. if ( t_StatusCode != e_StatusCode_Success )
  521. {
  522. a_Element.InternalRelease () ;
  523. }
  524. }
  525. else
  526. {
  527. UnLock () ;
  528. }
  529. return t_StatusCode ;
  530. }
  531. /******************************************************************************
  532. *
  533. * Name:
  534. *
  535. *
  536. * Description:
  537. *
  538. *
  539. *****************************************************************************/
  540. template <class WmiKey>
  541. WmiContainerController <WmiKey> :: WmiContainerController (
  542. WmiAllocator &a_Allocator
  543. ) : m_Container ( a_Allocator ) ,
  544. m_ReferenceCount ( 0 ),
  545. m_CriticalSection(NOTHROW_LOCK)
  546. {
  547. }
  548. /******************************************************************************
  549. *
  550. * Name:
  551. *
  552. *
  553. * Description:
  554. *
  555. *
  556. *****************************************************************************/
  557. template <class WmiKey>
  558. WmiContainerController <WmiKey> :: ~WmiContainerController ()
  559. {
  560. }
  561. /******************************************************************************
  562. *
  563. * Name:
  564. *
  565. *
  566. * Description:
  567. *
  568. *
  569. *****************************************************************************/
  570. template <class WmiKey>
  571. STDMETHODIMP_( ULONG ) WmiContainerController <WmiKey> :: AddRef ()
  572. {
  573. return InterlockedIncrement ( & m_ReferenceCount ) ;
  574. }
  575. /******************************************************************************
  576. *
  577. * Name:
  578. *
  579. *
  580. * Description:
  581. *
  582. *
  583. *****************************************************************************/
  584. template <class WmiKey>
  585. STDMETHODIMP_( ULONG ) WmiContainerController <WmiKey> :: Release ()
  586. {
  587. ULONG t_ReferenceCount = InterlockedDecrement ( & m_ReferenceCount ) ;
  588. if ( t_ReferenceCount == 0 )
  589. {
  590. delete this ;
  591. }
  592. return t_ReferenceCount ;
  593. }
  594. /******************************************************************************
  595. *
  596. * Name:
  597. *
  598. *
  599. * Description:
  600. *
  601. *
  602. *****************************************************************************/
  603. template <class WmiKey>
  604. STDMETHODIMP WmiContainerController <WmiKey> :: QueryInterface ( REFIID , LPVOID FAR * )
  605. {
  606. return E_NOINTERFACE ;
  607. }
  608. /******************************************************************************
  609. *
  610. * Name:
  611. *
  612. *
  613. * Description:
  614. *
  615. *
  616. *****************************************************************************/
  617. template <class WmiKey>
  618. WmiStatusCode WmiContainerController <WmiKey> :: Initialize ()
  619. {
  620. WmiStatusCode t_StatusCode = m_Container.Initialize () ;
  621. if ( t_StatusCode == e_StatusCode_Success )
  622. {
  623. t_StatusCode = WmiHelper :: InitializeCriticalSection ( & m_CriticalSection ) ;
  624. }
  625. return t_StatusCode ;
  626. }
  627. /******************************************************************************
  628. *
  629. * Name:
  630. *
  631. *
  632. * Description:
  633. *
  634. *
  635. *****************************************************************************/
  636. template <class WmiKey>
  637. WmiStatusCode WmiContainerController <WmiKey> :: UnInitialize ()
  638. {
  639. WmiStatusCode t_StatusCode = m_Container.UnInitialize () ;
  640. if ( t_StatusCode == e_StatusCode_Success )
  641. {
  642. t_StatusCode = WmiHelper :: DeleteCriticalSection ( & m_CriticalSection ) ;
  643. }
  644. return t_StatusCode ;
  645. }
  646. /******************************************************************************
  647. *
  648. * Name:
  649. *
  650. *
  651. * Description:
  652. *
  653. *
  654. *****************************************************************************/
  655. template <class WmiKey>
  656. WmiStatusCode WmiContainerController <WmiKey> :: Insert (
  657. WmiContainerElement &a_Element ,
  658. Container_Iterator &a_Iterator
  659. )
  660. {
  661. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  662. Lock () ;
  663. Container_Iterator t_Iterator ;
  664. t_StatusCode = m_Container.Insert ( a_Element.GetKey () , & a_Element , t_Iterator ) ;
  665. if ( t_StatusCode == e_StatusCode_Success )
  666. {
  667. a_Element.InternalAddRef () ;
  668. a_Element.SetCached ( TRUE ) ;
  669. }
  670. UnLock () ;
  671. return t_StatusCode ;
  672. }
  673. /******************************************************************************
  674. *
  675. * Name:
  676. *
  677. *
  678. * Description:
  679. *
  680. *
  681. *****************************************************************************/
  682. template <class WmiKey>
  683. WmiStatusCode WmiContainerController <WmiKey> :: Delete (
  684. const WmiKey &a_Key
  685. )
  686. {
  687. Lock () ;
  688. WmiStatusCode t_StatusCode = m_Container.Delete ( a_Key ) ;
  689. UnLock () ;
  690. return t_StatusCode ;
  691. }
  692. /******************************************************************************
  693. *
  694. * Name:
  695. *
  696. *
  697. * Description:
  698. *
  699. *
  700. *****************************************************************************/
  701. template <class WmiKey>
  702. WmiStatusCode WmiContainerController <WmiKey> :: Find (
  703. const WmiKey &a_Key ,
  704. Container_Iterator &a_Iterator
  705. )
  706. {
  707. Lock () ;
  708. WmiStatusCode t_StatusCode = m_Container.Find ( a_Key , a_Iterator ) ;
  709. if ( t_StatusCode == e_StatusCode_Success )
  710. {
  711. a_Iterator.GetElement ()->AddRef ( ) ;
  712. }
  713. UnLock () ;
  714. return t_StatusCode ;
  715. }
  716. /******************************************************************************
  717. *
  718. * Name:
  719. *
  720. *
  721. * Description:
  722. *
  723. *
  724. *****************************************************************************/
  725. template <class WmiKey>
  726. WmiStatusCode WmiContainerController <WmiKey> :: Lock ()
  727. {
  728. return WmiHelper :: EnterCriticalSection ( & m_CriticalSection ) ;
  729. }
  730. /******************************************************************************
  731. *
  732. * Name:
  733. *
  734. *
  735. * Description:
  736. *
  737. *
  738. *****************************************************************************/
  739. template <class WmiKey>
  740. WmiStatusCode WmiContainerController <WmiKey> :: UnLock ()
  741. {
  742. WmiHelper :: LeaveCriticalSection ( & m_CriticalSection ) ;
  743. return e_StatusCode_Success ;
  744. }
  745. /******************************************************************************
  746. *
  747. * Name:
  748. *
  749. *
  750. * Description:
  751. *
  752. *
  753. *****************************************************************************/
  754. template <class WmiKey>
  755. WmiStatusCode WmiContainerController <WmiKey> :: Shutdown ()
  756. {
  757. Lock () ;
  758. Container_Iterator t_Iterator = m_Container.Root ();
  759. while ( ! t_Iterator.Null () )
  760. {
  761. m_Container.Delete ( t_Iterator.GetKey () ) ;
  762. t_Iterator = m_Container.Root () ;
  763. }
  764. UnLock () ;
  765. return e_StatusCode_Success ;
  766. }
  767. /******************************************************************************
  768. *
  769. * Name:
  770. *
  771. *
  772. * Description:
  773. *
  774. *
  775. *****************************************************************************/
  776. template <class WmiKey>
  777. WmiStatusCode WmiContainerController <WmiKey> :: Strobe ( ULONG &a_NextStrobeDelta )
  778. {
  779. return e_StatusCode_Success ;
  780. }
  781. #endif __CACHE_CPP