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.

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