955 lines
19 KiB
C++
955 lines
19 KiB
C++
#ifndef __CACHE_CPP
|
|
#define __CACHE_CPP
|
|
|
|
/*++
|
|
|
|
Copyright (C) 1996-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
Thread.cpp
|
|
|
|
Abstract:
|
|
|
|
Enhancements to current functionality:
|
|
|
|
Timeout mechanism should track across waits.
|
|
AddRef/Release on task when scheduling.
|
|
Enhancement Ticker logic.
|
|
|
|
History:
|
|
|
|
--*/
|
|
|
|
#include <HelperFuncs.h>
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
LONG operator == ( const WmiCacheController <WmiKey> :: WmiUniqueTimeout &a_Arg1 , const WmiCacheController <WmiKey> :: WmiUniqueTimeout &a_Arg2 )
|
|
{
|
|
LONG t_Compare ;
|
|
if ( ( t_Compare = a_Arg1.GetTicks () - a_Arg2.GetTicks () ) == 0 )
|
|
{
|
|
t_Compare = a_Arg1.GetCounter () - a_Arg2.GetCounter () ;
|
|
}
|
|
|
|
return t_Compare == 0 ? true : false ;
|
|
}
|
|
|
|
template <class WmiKey>
|
|
bool operator < ( const WmiCacheController <WmiKey> :: WmiUniqueTimeout &a_Arg1 , const WmiCacheController <WmiKey> :: WmiUniqueTimeout &a_Arg2 )
|
|
{
|
|
LONG t_Compare ;
|
|
if ( ( t_Compare = a_Arg1.GetTicks () - a_Arg2.GetTicks () ) == 0 )
|
|
{
|
|
t_Compare = a_Arg1.GetCounter () - a_Arg2.GetCounter () ;
|
|
}
|
|
|
|
return t_Compare < 0 ? true : false ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiCacheController <WmiKey> :: WmiCacheController (
|
|
|
|
WmiAllocator &a_Allocator
|
|
|
|
) : m_Allocator ( a_Allocator ) ,
|
|
m_Cache ( a_Allocator ) ,
|
|
m_CacheDecay ( a_Allocator ) ,
|
|
m_ReferenceCount ( 0 ) ,
|
|
m_Counter ( 0 ),
|
|
m_CriticalSection(NOTHROW_LOCK)
|
|
{
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiCacheController <WmiKey> :: ~WmiCacheController ()
|
|
{
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
STDMETHODIMP_( ULONG ) WmiCacheController <WmiKey> :: AddRef ()
|
|
{
|
|
return InterlockedIncrement ( & m_ReferenceCount ) ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
STDMETHODIMP_( ULONG ) WmiCacheController <WmiKey> :: Release ()
|
|
{
|
|
ULONG t_ReferenceCount = InterlockedDecrement ( & m_ReferenceCount ) ;
|
|
if ( t_ReferenceCount == 0 )
|
|
{
|
|
delete this ;
|
|
}
|
|
|
|
return t_ReferenceCount ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
STDMETHODIMP WmiCacheController <WmiKey> :: QueryInterface ( REFIID , LPVOID FAR * )
|
|
{
|
|
return E_NOINTERFACE ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiCacheController <WmiKey> :: Initialize ()
|
|
{
|
|
WmiStatusCode t_StatusCode = m_Cache.Initialize () ;
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
t_StatusCode = m_CacheDecay.Initialize () ;
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
t_StatusCode = WmiHelper :: InitializeCriticalSection ( & m_CriticalSection ) ;
|
|
}
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiCacheController <WmiKey> :: UnInitialize ()
|
|
{
|
|
WmiStatusCode t_StatusCode = m_Cache.UnInitialize () ;
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
t_StatusCode = m_CacheDecay.UnInitialize () ;
|
|
}
|
|
|
|
WmiHelper :: DeleteCriticalSection ( & m_CriticalSection ) ;
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiCacheController <WmiKey> :: Insert (
|
|
|
|
WmiCacheElement &a_Element ,
|
|
Cache_Iterator &a_Iterator
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
Lock () ;
|
|
|
|
Cache_Iterator t_Iterator ;
|
|
t_StatusCode = m_Cache.Insert ( a_Element.GetKey () , & a_Element , t_Iterator ) ;
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
a_Element.InternalAddRef () ;
|
|
a_Element.SetCached ( TRUE ) ;
|
|
}
|
|
|
|
UnLock () ;
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiCacheController <WmiKey> :: Delete (
|
|
|
|
const WmiKey &a_Key
|
|
)
|
|
{
|
|
Lock () ;
|
|
|
|
WmiStatusCode t_StatusCode = m_Cache.Delete ( a_Key ) ;
|
|
|
|
UnLock () ;
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiCacheController <WmiKey> :: Find (
|
|
|
|
const WmiKey &a_Key ,
|
|
Cache_Iterator &a_Iterator
|
|
)
|
|
{
|
|
Lock () ;
|
|
|
|
WmiStatusCode t_StatusCode = m_Cache.Find ( a_Key , a_Iterator ) ;
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
a_Iterator.GetElement ()->AddRef ( ) ;
|
|
}
|
|
|
|
UnLock () ;
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiCacheController <WmiKey> :: Lock ()
|
|
{
|
|
WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection ( & m_CriticalSection ) ;
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiCacheController <WmiKey> :: UnLock ()
|
|
{
|
|
WmiStatusCode t_StatusCode = WmiHelper :: LeaveCriticalSection ( & m_CriticalSection ) ;
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiCacheController <WmiKey> :: Shutdown ()
|
|
{
|
|
Lock () ;
|
|
|
|
ULONG t_Index = 0 ;
|
|
while ( true )
|
|
{
|
|
WmiUniqueTimeout t_Key ;
|
|
WmiCacheElement *t_Element = NULL ;
|
|
|
|
WmiStatusCode t_StatusCode = m_CacheDecay.Top ( t_Key , t_Element ) ;
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
t_Index ++ ;
|
|
|
|
t_StatusCode = m_CacheDecay.DeQueue () ;
|
|
}
|
|
else
|
|
{
|
|
break ;
|
|
}
|
|
}
|
|
|
|
ULONG t_ElementCount = m_Cache.Size () ;
|
|
|
|
WmiCacheElement **t_Elements = NULL ;
|
|
WmiStatusCode t_StatusCode = m_Allocator.New (
|
|
|
|
( void ** ) & t_Elements ,
|
|
sizeof ( WmiCacheElement ) * t_ElementCount
|
|
) ;
|
|
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
for ( ULONG t_Index = 0 ; t_Index < t_ElementCount ; t_Index ++ )
|
|
{
|
|
t_Elements [ t_Index ] = NULL ;
|
|
}
|
|
|
|
ULONG t_ElementIndex = 0 ;
|
|
|
|
Cache_Iterator t_Iterator = m_Cache.Root ();
|
|
while ( ! t_Iterator.Null () )
|
|
{
|
|
if ( t_Iterator.GetElement ()->GetDecayed () == FALSE )
|
|
{
|
|
WmiCacheElement *t_Element = t_Iterator.GetElement () ;
|
|
t_Elements [ t_ElementIndex ] = t_Element ;
|
|
|
|
t_Element->SetDecayed ( TRUE ) ;
|
|
t_Element->SetDecaying ( FALSE ) ;
|
|
t_Element->SetCached ( FALSE ) ;
|
|
|
|
m_Cache.Delete ( t_Iterator.GetKey () ) ;
|
|
}
|
|
else
|
|
{
|
|
m_Cache.Delete ( t_Iterator.GetKey () ) ;
|
|
}
|
|
|
|
t_ElementIndex ++ ;
|
|
|
|
t_Iterator = m_Cache.Root () ;
|
|
}
|
|
}
|
|
|
|
UnLock () ;
|
|
|
|
if ( t_Elements )
|
|
{
|
|
for ( ULONG t_Index = 0 ; t_Index < t_ElementCount ; t_Index ++ )
|
|
{
|
|
if ( t_Elements [ t_Index ] )
|
|
{
|
|
t_Elements [ t_Index ]->InternalRelease () ;
|
|
}
|
|
}
|
|
|
|
m_Allocator.Delete ( t_Elements ) ;
|
|
}
|
|
|
|
return e_StatusCode_Success ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiCacheController <WmiKey> :: Shutdown ( const WmiKey &a_Key )
|
|
{
|
|
Lock () ;
|
|
|
|
Cache_Iterator t_Iterator ;
|
|
WmiStatusCode t_StatusCode = m_Cache.Find ( a_Key , t_Iterator ) ;
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
if ( t_Iterator.GetElement ()->GetDecayed () == FALSE )
|
|
{
|
|
CacheDecay_Iterator t_QueueIterator = m_CacheDecay.Begin () ;
|
|
while ( ! t_QueueIterator.Null () )
|
|
{
|
|
WmiCacheElement *t_Element = t_QueueIterator.GetElement () ;
|
|
if ( t_Element == t_Iterator.GetElement () )
|
|
{
|
|
m_CacheDecay.Delete ( t_QueueIterator.GetKey () ) ;
|
|
break ;
|
|
}
|
|
|
|
t_QueueIterator.Increment () ;
|
|
}
|
|
|
|
WmiCacheElement *t_Element = t_Iterator.GetElement () ;
|
|
t_Element->SetDecayed ( TRUE ) ;
|
|
t_Element->SetDecaying ( FALSE ) ;
|
|
t_Element->SetCached ( FALSE ) ;
|
|
|
|
m_Cache.Delete ( a_Key ) ;
|
|
|
|
UnLock () ;
|
|
|
|
t_Element->InternalRelease () ;
|
|
}
|
|
else
|
|
{
|
|
m_Cache.Delete ( a_Key ) ;
|
|
|
|
UnLock () ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UnLock () ;
|
|
}
|
|
|
|
return e_StatusCode_Success ;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiCacheController <WmiKey> :: StrobeBegin ( const ULONG &a_Timeout )
|
|
{
|
|
return e_StatusCode_Success ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiCacheController <WmiKey> :: Strobe ( ULONG &a_NextStrobeDelta )
|
|
{
|
|
while ( true )
|
|
{
|
|
Lock () ;
|
|
|
|
WmiUniqueTimeout t_Key ;
|
|
WmiCacheElement *t_Element = NULL ;
|
|
|
|
WmiStatusCode t_StatusCode = m_CacheDecay.Top ( t_Key , t_Element ) ;
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
a_NextStrobeDelta = ( a_NextStrobeDelta < t_Element->GetPeriod () ) ? a_NextStrobeDelta : t_Element->GetPeriod () ;
|
|
|
|
ULONG t_Ticks = GetTickCount () ;
|
|
|
|
#if 0
|
|
wchar_t t_Buffer [ 128 ] ;
|
|
wsprintf ( t_Buffer , L"\n%lx - Checking ( %lx , %lx ) " , t_Ticks , t_Element , t_Key.GetTicks () ) ;
|
|
OutputDebugString ( t_Buffer ) ;
|
|
#endif
|
|
|
|
if ( t_Ticks >= t_Key.GetTicks () )
|
|
{
|
|
if ( t_Element->GetDecaying () )
|
|
{
|
|
#if 0
|
|
wchar_t t_Buffer [ 128 ] ;
|
|
wsprintf ( t_Buffer , L"\n%lx - Strobe ( %lx , %lx ) " , t_Ticks , t_Element , t_Key.GetTicks () ) ;
|
|
OutputDebugString ( t_Buffer ) ;
|
|
#endif
|
|
|
|
t_Element->SetDecaying ( FALSE ) ;
|
|
t_Element->SetDecayed ( TRUE ) ;
|
|
|
|
t_StatusCode = m_CacheDecay.DeQueue () ;
|
|
|
|
UnLock () ;
|
|
|
|
t_Element->InternalRelease () ;
|
|
}
|
|
else
|
|
{
|
|
t_StatusCode = m_CacheDecay.DeQueue () ;
|
|
|
|
UnLock () ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UnLock () ;
|
|
break ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UnLock () ;
|
|
break ;
|
|
}
|
|
}
|
|
|
|
return e_StatusCode_Success ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiCacheController <WmiKey> :: Decay (
|
|
|
|
WmiCacheElement &a_Element
|
|
)
|
|
{
|
|
Lock () ;
|
|
|
|
ULONG t_Size = m_CacheDecay.Size () ;
|
|
|
|
Cache_Iterator t_Iterator ;
|
|
WmiStatusCode t_StatusCode = m_Cache.Find ( a_Element.GetKey () , t_Iterator ) ;
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
BOOL t_Found = FALSE ;
|
|
CacheDecay_Iterator t_QueueIterator = m_CacheDecay.Begin () ;
|
|
while ( ! t_QueueIterator.Null () )
|
|
{
|
|
WmiCacheElement *t_Element = t_QueueIterator.GetElement () ;
|
|
if ( t_Element == & a_Element )
|
|
{
|
|
m_CacheDecay.Delete ( t_QueueIterator.GetKey () ) ;
|
|
break ;
|
|
}
|
|
|
|
t_QueueIterator.Increment () ;
|
|
}
|
|
|
|
ULONG t_Ticks = GetTickCount () ;
|
|
WmiUniqueTimeout t_Key (
|
|
|
|
t_Ticks + a_Element.GetPeriod () ,
|
|
InterlockedIncrement ( & m_Counter )
|
|
) ;
|
|
|
|
#if 0
|
|
wchar_t t_Buffer [ 128 ] ;
|
|
wsprintf ( t_Buffer , L"\n%lx - Decaying ( %lx , %lx , %lx ) " , t_Ticks , & a_Element , t_Ticks + a_Element.GetPeriod () , a_Element.GetPeriod () ) ;
|
|
OutputDebugString ( t_Buffer ) ;
|
|
#endif
|
|
|
|
t_StatusCode = m_CacheDecay.EnQueue (
|
|
|
|
t_Key ,
|
|
t_Iterator.GetElement ()
|
|
) ;
|
|
|
|
UnLock () ;
|
|
|
|
if ( t_Size == 0 )
|
|
{
|
|
StrobeBegin ( a_Element.GetPeriod () ) ;
|
|
}
|
|
|
|
if ( t_StatusCode != e_StatusCode_Success )
|
|
{
|
|
a_Element.InternalRelease () ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UnLock () ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiContainerController <WmiKey> :: WmiContainerController (
|
|
|
|
WmiAllocator &a_Allocator
|
|
|
|
) : m_Container ( a_Allocator ) ,
|
|
m_ReferenceCount ( 0 ),
|
|
m_CriticalSection(NOTHROW_LOCK)
|
|
{
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiContainerController <WmiKey> :: ~WmiContainerController ()
|
|
{
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
STDMETHODIMP_( ULONG ) WmiContainerController <WmiKey> :: AddRef ()
|
|
{
|
|
return InterlockedIncrement ( & m_ReferenceCount ) ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
STDMETHODIMP_( ULONG ) WmiContainerController <WmiKey> :: Release ()
|
|
{
|
|
ULONG t_ReferenceCount = InterlockedDecrement ( & m_ReferenceCount ) ;
|
|
if ( t_ReferenceCount == 0 )
|
|
{
|
|
delete this ;
|
|
}
|
|
|
|
return t_ReferenceCount ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
STDMETHODIMP WmiContainerController <WmiKey> :: QueryInterface ( REFIID , LPVOID FAR * )
|
|
{
|
|
return E_NOINTERFACE ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiContainerController <WmiKey> :: Initialize ()
|
|
{
|
|
WmiStatusCode t_StatusCode = m_Container.Initialize () ;
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
t_StatusCode = WmiHelper :: InitializeCriticalSection ( & m_CriticalSection ) ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiContainerController <WmiKey> :: UnInitialize ()
|
|
{
|
|
WmiStatusCode t_StatusCode = m_Container.UnInitialize () ;
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
t_StatusCode = WmiHelper :: DeleteCriticalSection ( & m_CriticalSection ) ;
|
|
}
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiContainerController <WmiKey> :: Insert (
|
|
|
|
WmiContainerElement &a_Element ,
|
|
Container_Iterator &a_Iterator
|
|
)
|
|
{
|
|
WmiStatusCode t_StatusCode = e_StatusCode_Success ;
|
|
|
|
Lock () ;
|
|
|
|
Container_Iterator t_Iterator ;
|
|
t_StatusCode = m_Container.Insert ( a_Element.GetKey () , & a_Element , t_Iterator ) ;
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
a_Element.InternalAddRef () ;
|
|
a_Element.SetCached ( TRUE ) ;
|
|
}
|
|
|
|
UnLock () ;
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiContainerController <WmiKey> :: Delete (
|
|
|
|
const WmiKey &a_Key
|
|
)
|
|
{
|
|
Lock () ;
|
|
|
|
WmiStatusCode t_StatusCode = m_Container.Delete ( a_Key ) ;
|
|
|
|
UnLock () ;
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiContainerController <WmiKey> :: Find (
|
|
|
|
const WmiKey &a_Key ,
|
|
Container_Iterator &a_Iterator
|
|
)
|
|
{
|
|
Lock () ;
|
|
|
|
WmiStatusCode t_StatusCode = m_Container.Find ( a_Key , a_Iterator ) ;
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
a_Iterator.GetElement ()->AddRef ( ) ;
|
|
}
|
|
|
|
UnLock () ;
|
|
|
|
return t_StatusCode ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiContainerController <WmiKey> :: Lock ()
|
|
{
|
|
return WmiHelper :: EnterCriticalSection ( & m_CriticalSection ) ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiContainerController <WmiKey> :: UnLock ()
|
|
{
|
|
WmiHelper :: LeaveCriticalSection ( & m_CriticalSection ) ;
|
|
|
|
return e_StatusCode_Success ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiContainerController <WmiKey> :: Shutdown ()
|
|
{
|
|
Lock () ;
|
|
|
|
Container_Iterator t_Iterator = m_Container.Root ();
|
|
|
|
while ( ! t_Iterator.Null () )
|
|
{
|
|
m_Container.Delete ( t_Iterator.GetKey () ) ;
|
|
|
|
t_Iterator = m_Container.Root () ;
|
|
}
|
|
|
|
UnLock () ;
|
|
|
|
return e_StatusCode_Success ;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
WmiStatusCode WmiContainerController <WmiKey> :: Strobe ( ULONG &a_NextStrobeDelta )
|
|
{
|
|
return e_StatusCode_Success ;
|
|
}
|
|
|
|
#endif __CACHE_CPP
|