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.
936 lines
17 KiB
936 lines
17 KiB
/*++
|
|
|
|
Copyright (C) 1996-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
Cache.H
|
|
|
|
Abstract:
|
|
|
|
|
|
History:
|
|
|
|
--*/
|
|
|
|
#ifndef _Cache_H
|
|
#define _Cache_H
|
|
|
|
#include <Allocator.h>
|
|
#include <Algorithms.h>
|
|
#include <TPQueue.h>
|
|
#include <AvlTree.h>
|
|
#include <lockst.h>
|
|
|
|
|
|
template<typename T>
|
|
class AutoLockGuard
|
|
{
|
|
T& m_lock;
|
|
int m_lockCount;
|
|
public:
|
|
AutoLockGuard(T& target);
|
|
~AutoLockGuard();
|
|
void Lock();
|
|
void UnLock();
|
|
};
|
|
|
|
template<typename T>
|
|
AutoLockGuard<T>::AutoLockGuard(T& target): m_lock(target), m_lockCount(0)
|
|
{
|
|
Lock();
|
|
}
|
|
|
|
template<typename T>
|
|
AutoLockGuard<T>::~AutoLockGuard()
|
|
{
|
|
if (m_lockCount) UnLock();
|
|
}
|
|
|
|
template<typename T>
|
|
void AutoLockGuard<T>::Lock()
|
|
{
|
|
_DBG_ASSERT(m_lockCount == 0);
|
|
m_lock.Lock();
|
|
m_lockCount++;
|
|
}
|
|
|
|
template<typename T>
|
|
void AutoLockGuard<T>::UnLock()
|
|
{
|
|
_DBG_ASSERT(m_lockCount > 0);
|
|
m_lock.UnLock();
|
|
m_lockCount--;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
class WmiCacheController : public IUnknown
|
|
{
|
|
public:
|
|
|
|
class WmiUniqueTimeout
|
|
{
|
|
private:
|
|
|
|
ULONG m_Ticks ;
|
|
LONG m_Counter ;
|
|
|
|
public:
|
|
|
|
WmiUniqueTimeout () : m_Ticks ( 0 ) , m_Counter ( 0 ) { ; }
|
|
WmiUniqueTimeout (
|
|
|
|
const ULONG &a_Ticks ,
|
|
const LONG &a_Counter
|
|
|
|
) : m_Ticks ( a_Ticks ) ,
|
|
m_Counter ( a_Counter )
|
|
{ ; }
|
|
|
|
ULONG GetTicks () const { return m_Ticks ; }
|
|
LONG GetCounter () const { return m_Counter ; }
|
|
|
|
friend bool operator == ( const WmiUniqueTimeout &a_Arg1 , const 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 ;
|
|
}
|
|
|
|
friend bool operator < ( const WmiUniqueTimeout &a_Arg1 , const 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 ;
|
|
}
|
|
|
|
} ;
|
|
|
|
class WmiCacheElement : public IUnknown
|
|
{
|
|
private:
|
|
|
|
LONG m_ReferenceCount ;
|
|
LONG m_InternalReferenceCount ;
|
|
LONG m_NonCylicReferenceCount ;
|
|
BOOL m_Decaying ;
|
|
BOOL m_Cached ;
|
|
BOOL m_Decayed ;
|
|
ULONG m_CallBackInternalRelease ;
|
|
|
|
WmiCacheController <WmiKey> *m_Controller ;
|
|
WmiKey m_Key ;
|
|
ULONG m_Period ;
|
|
|
|
public:
|
|
|
|
WmiCacheElement () :
|
|
m_ReferenceCount ( 0 ) ,
|
|
m_InternalReferenceCount ( 0 ) ,
|
|
m_NonCylicReferenceCount ( 0 ) ,
|
|
m_Controller ( NULL ) ,
|
|
m_Period ( 0 ) ,
|
|
m_Decaying ( FALSE ) ,
|
|
m_Decayed ( FALSE ) ,
|
|
m_Cached ( FALSE ) ,
|
|
m_CallBackInternalRelease ( 1 )
|
|
{
|
|
}
|
|
|
|
WmiCacheElement (
|
|
|
|
WmiCacheController <WmiKey> *a_Controller ,
|
|
const WmiKey &a_Key ,
|
|
const ULONG &a_Period
|
|
|
|
) : m_ReferenceCount ( 0 ) ,
|
|
m_InternalReferenceCount ( 0 ) ,
|
|
m_NonCylicReferenceCount ( 0 ) ,
|
|
m_Controller ( a_Controller ) ,
|
|
m_Period ( a_Period ) ,
|
|
m_Decaying ( FALSE ) ,
|
|
m_Decayed ( FALSE ) ,
|
|
m_Cached ( FALSE ) ,
|
|
m_CallBackInternalRelease ( 1 )
|
|
{
|
|
m_Key = a_Key ;
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->AddRef () ;
|
|
}
|
|
}
|
|
|
|
virtual ~WmiCacheElement ()
|
|
{
|
|
#if 0
|
|
wchar_t t_Buffer [ 128 ] ;
|
|
wsprintf ( t_Buffer , L"\n%lx - ~WmiCacheElement ( %lx ) " , GetTickCount () , this ) ;
|
|
OutputDebugString ( t_Buffer ) ;
|
|
#endif
|
|
|
|
#ifdef DBG
|
|
if ( m_ReferenceCount != 0 )
|
|
{
|
|
DebugBreak () ;
|
|
}
|
|
|
|
if ( m_InternalReferenceCount != 0 )
|
|
{
|
|
DebugBreak () ;
|
|
}
|
|
|
|
if ( m_NonCylicReferenceCount != 0 )
|
|
{
|
|
DebugBreak () ;
|
|
}
|
|
#endif
|
|
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->Release () ;
|
|
}
|
|
}
|
|
|
|
virtual void CallBackRelease () {} ;
|
|
virtual void CallBackInternalRelease () {} ;
|
|
|
|
virtual STDMETHODIMP QueryInterface ( REFIID , LPVOID FAR * )
|
|
{
|
|
return E_NOINTERFACE ;
|
|
}
|
|
|
|
virtual STDMETHODIMP_( ULONG ) AddRef ()
|
|
{
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->Lock () ;
|
|
}
|
|
|
|
ULONG t_ReferenceCount = InterlockedIncrement ( & m_ReferenceCount ) ;
|
|
if ( t_ReferenceCount == 1 )
|
|
{
|
|
InternalAddRef () ;
|
|
|
|
SetDecaying ( FALSE ) ;
|
|
}
|
|
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->UnLock () ;
|
|
}
|
|
|
|
return t_ReferenceCount ;
|
|
}
|
|
|
|
virtual STDMETHODIMP_( ULONG ) Release ()
|
|
{
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->Lock () ;
|
|
}
|
|
|
|
LONG t_ReferenceCount = InterlockedDecrement ( & m_ReferenceCount ) ;
|
|
if ( t_ReferenceCount == 0 )
|
|
{
|
|
CallBackRelease () ;
|
|
|
|
if ( m_Controller )
|
|
{
|
|
if ( GetCached () )
|
|
{
|
|
if ( GetDecayed () == FALSE )
|
|
{
|
|
if ( GetDecaying () == FALSE )
|
|
{
|
|
WmiStatusCode t_StatusCode = m_Controller->Decay ( *this ) ;
|
|
|
|
if ( t_StatusCode == e_StatusCode_Success )
|
|
{
|
|
SetDecaying ( TRUE ) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
t_ReferenceCount = UnLockedInternalRelease () ;
|
|
}
|
|
else
|
|
{
|
|
t_ReferenceCount = UnLockedInternalRelease () ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_ReferenceCount = UnLockedInternalRelease () ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
#ifdef DBG
|
|
if ( t_ReferenceCount < 0 )
|
|
{
|
|
DebugBreak () ;
|
|
}
|
|
#endif
|
|
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->UnLock () ;
|
|
}
|
|
}
|
|
|
|
return t_ReferenceCount ;
|
|
}
|
|
|
|
STDMETHODIMP_( ULONG ) InternalAddRef ()
|
|
{
|
|
ULONG t_ReferenceCount = InterlockedIncrement ( & m_InternalReferenceCount ) ;
|
|
if ( t_ReferenceCount == 1 )
|
|
{
|
|
NonCyclicAddRef () ;
|
|
}
|
|
|
|
return t_ReferenceCount ;
|
|
}
|
|
|
|
STDMETHODIMP_( ULONG ) UnLockedInternalRelease ()
|
|
{
|
|
LONG t_ReferenceCount = InterlockedDecrement ( & m_InternalReferenceCount ) ;
|
|
if ( t_ReferenceCount == 0 )
|
|
{
|
|
BOOL t_DoCallBack = m_CallBackInternalRelease ;
|
|
m_CallBackInternalRelease = 0xbabab1ac ;
|
|
|
|
if ( GetCached () )
|
|
{
|
|
m_Controller->Delete ( m_Key ) ;
|
|
|
|
SetCached ( FALSE ) ;
|
|
}
|
|
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->UnLock () ;
|
|
}
|
|
|
|
if ( t_DoCallBack == 1 )
|
|
{
|
|
CallBackInternalRelease () ;
|
|
}
|
|
else
|
|
{
|
|
#ifdef DBG
|
|
DebugBreak () ;
|
|
#endif
|
|
}
|
|
|
|
NonCyclicRelease () ;
|
|
}
|
|
else
|
|
{
|
|
#ifdef DBG
|
|
if ( t_ReferenceCount < 0 )
|
|
{
|
|
DebugBreak () ;
|
|
}
|
|
#endif
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->UnLock () ;
|
|
}
|
|
}
|
|
|
|
return t_ReferenceCount ;
|
|
}
|
|
|
|
STDMETHODIMP_( ULONG ) InternalRelease ()
|
|
{
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->Lock () ;
|
|
}
|
|
|
|
LONG t_ReferenceCount = InterlockedDecrement ( & m_InternalReferenceCount ) ;
|
|
if ( t_ReferenceCount == 0 )
|
|
{
|
|
BOOL t_DoCallBack = m_CallBackInternalRelease ;
|
|
m_CallBackInternalRelease = 0xbabab1ac ;
|
|
|
|
BOOL t_Cached = GetCached () ;
|
|
if ( t_Cached )
|
|
{
|
|
m_Controller->Delete ( m_Key ) ;
|
|
SetCached ( FALSE ) ;
|
|
}
|
|
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->UnLock () ;
|
|
}
|
|
|
|
if ( t_DoCallBack == 1 )
|
|
{
|
|
CallBackInternalRelease () ;
|
|
}
|
|
else
|
|
{
|
|
#ifdef DBG
|
|
DebugBreak () ;
|
|
#endif
|
|
}
|
|
|
|
NonCyclicRelease () ;
|
|
}
|
|
else
|
|
{
|
|
#ifdef DBG
|
|
if ( t_ReferenceCount < 0 )
|
|
{
|
|
DebugBreak () ;
|
|
}
|
|
#endif
|
|
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->UnLock () ;
|
|
}
|
|
}
|
|
|
|
return t_ReferenceCount ;
|
|
}
|
|
|
|
STDMETHODIMP_( ULONG ) NonCyclicAddRef ()
|
|
{
|
|
return InterlockedIncrement ( & m_NonCylicReferenceCount ) ;
|
|
}
|
|
|
|
STDMETHODIMP_( ULONG ) NonCyclicRelease ()
|
|
{
|
|
ULONG t_ReferenceCount = InterlockedDecrement ( & m_NonCylicReferenceCount ) ;
|
|
if ( t_ReferenceCount == 0 )
|
|
{
|
|
delete this ;
|
|
}
|
|
|
|
return t_ReferenceCount ;
|
|
}
|
|
|
|
ULONG GetPeriod ()
|
|
{
|
|
return m_Period ;
|
|
}
|
|
|
|
void SetPeriod ( const ULONG &a_Period )
|
|
{
|
|
m_Period = a_Period ;
|
|
}
|
|
|
|
WmiKey &GetKey ()
|
|
{
|
|
return m_Key ;
|
|
}
|
|
|
|
void SetKey ( const WmiKey &a_Key )
|
|
{
|
|
m_Key = a_Key ;
|
|
}
|
|
|
|
BOOL GetDecaying ()
|
|
{
|
|
return m_Decaying ;
|
|
}
|
|
|
|
BOOL GetDecayed ()
|
|
{
|
|
return m_Decayed ;
|
|
}
|
|
|
|
BOOL GetCached ()
|
|
{
|
|
return m_Cached ;
|
|
}
|
|
|
|
void SetDecayed ( BOOL a_Decayed )
|
|
{
|
|
m_Decayed = a_Decayed ;
|
|
}
|
|
|
|
void SetDecaying ( BOOL a_Decay )
|
|
{
|
|
m_Decaying = a_Decay ;
|
|
}
|
|
|
|
void SetCached ( BOOL a_Cached )
|
|
{
|
|
m_Cached = a_Cached ;
|
|
}
|
|
|
|
void SetController ( WmiCacheController <WmiKey> *a_Controller )
|
|
{
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->Release () ;
|
|
}
|
|
|
|
m_Controller = a_Controller ;
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->AddRef () ;
|
|
}
|
|
}
|
|
|
|
WmiCacheController <WmiKey> *GetController ()
|
|
{
|
|
return m_Controller ;
|
|
}
|
|
} ;
|
|
|
|
typedef WmiAvlTree <WmiKey,WmiCacheElement *> Cache ;
|
|
typedef typename Cache :: Iterator Cache_Iterator ;
|
|
|
|
private:
|
|
|
|
typedef WmiTreePriorityQueue <WmiUniqueTimeout,WmiCacheElement *> CacheDecay ;
|
|
typedef typename CacheDecay :: Iterator CacheDecay_Iterator ;
|
|
|
|
WmiAllocator &m_Allocator ;
|
|
CriticalSection m_CriticalSection ;
|
|
|
|
LONG m_ReferenceCount ;
|
|
|
|
Cache m_Cache ;
|
|
CacheDecay m_CacheDecay ;
|
|
LONG m_Counter ;
|
|
|
|
protected:
|
|
public:
|
|
|
|
WmiCacheController ( WmiAllocator &a_Allocator ) ;
|
|
virtual ~WmiCacheController () ;
|
|
|
|
virtual STDMETHODIMP QueryInterface ( REFIID , LPVOID FAR * ) ;
|
|
|
|
virtual STDMETHODIMP_( ULONG ) AddRef () ;
|
|
|
|
virtual STDMETHODIMP_( ULONG ) Release () ;
|
|
|
|
virtual WmiStatusCode Initialize () ;
|
|
|
|
virtual WmiStatusCode UnInitialize () ;
|
|
|
|
virtual WmiStatusCode Lock () ;
|
|
|
|
virtual WmiStatusCode UnLock () ;
|
|
|
|
virtual WmiStatusCode Insert (
|
|
|
|
WmiCacheElement &a_Element ,
|
|
Cache_Iterator &a_Iterator
|
|
) ;
|
|
|
|
virtual WmiStatusCode Find ( const WmiKey &a_Key , Cache_Iterator &a_Iterator ) ;
|
|
|
|
virtual WmiStatusCode Shutdown () ;
|
|
|
|
virtual WmiStatusCode Shutdown ( const WmiKey &a_Key ) ;
|
|
|
|
virtual WmiStatusCode StrobeBegin ( const ULONG &a_Timeout ) ;
|
|
|
|
virtual WmiStatusCode Strobe ( ULONG &a_NextStrobeDelta ) ;
|
|
|
|
virtual WmiStatusCode Delete ( const WmiKey &a_Key ) ;
|
|
|
|
virtual WmiStatusCode Decay (
|
|
|
|
WmiCacheElement &a_Element
|
|
) ;
|
|
|
|
WmiStatusCode GetCache ( Cache *&a_Cache )
|
|
{
|
|
a_Cache = & m_Cache ;
|
|
return e_StatusCode_Success ;
|
|
}
|
|
|
|
CriticalSection* GetCriticalSection ()
|
|
{
|
|
return &m_CriticalSection ;
|
|
}
|
|
} ;
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Name:
|
|
*
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
template <class WmiKey>
|
|
class WmiContainerController : public IUnknown
|
|
{
|
|
public:
|
|
|
|
class WmiContainerElement : public IUnknown
|
|
{
|
|
private:
|
|
|
|
LONG m_ReferenceCount ;
|
|
LONG m_InternalReferenceCount ;
|
|
LONG m_NonCylicReferenceCount ;
|
|
BOOL m_Cached ;
|
|
|
|
WmiContainerController <WmiKey> *m_Controller ;
|
|
WmiKey m_Key ;
|
|
ULONG m_CallBackInternalRelease ;
|
|
|
|
public:
|
|
|
|
WmiContainerElement () :
|
|
m_ReferenceCount ( 0 ) ,
|
|
m_InternalReferenceCount ( 0 ) ,
|
|
m_NonCylicReferenceCount ( 0 ) ,
|
|
m_Cached ( FALSE ) ,
|
|
m_Controller ( NULL ) ,
|
|
m_CallBackInternalRelease ( 1 )
|
|
{
|
|
}
|
|
|
|
WmiContainerElement (
|
|
|
|
WmiContainerController <WmiKey> *a_Controller ,
|
|
const WmiKey &a_Key
|
|
|
|
) : m_ReferenceCount ( 0 ) ,
|
|
m_InternalReferenceCount ( 0 ) ,
|
|
m_NonCylicReferenceCount ( 0 ) ,
|
|
m_Cached ( FALSE ) ,
|
|
m_Controller ( a_Controller ) ,
|
|
m_Key ( a_Key ) ,
|
|
m_CallBackInternalRelease ( 1 )
|
|
{
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->AddRef () ;
|
|
}
|
|
}
|
|
|
|
virtual ~WmiContainerElement ()
|
|
{
|
|
#ifdef DBG
|
|
if ( m_ReferenceCount != 0 )
|
|
{
|
|
DebugBreak () ;
|
|
}
|
|
|
|
if ( m_InternalReferenceCount != 0 )
|
|
{
|
|
DebugBreak () ;
|
|
}
|
|
|
|
if ( m_NonCylicReferenceCount != 0 )
|
|
{
|
|
DebugBreak () ;
|
|
}
|
|
#endif
|
|
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->Release () ;
|
|
}
|
|
}
|
|
|
|
virtual void CallBackRelease () {} ;
|
|
virtual void CallBackInternalRelease () {} ;
|
|
|
|
virtual STDMETHODIMP QueryInterface ( REFIID , LPVOID FAR * )
|
|
{
|
|
return E_NOINTERFACE ;
|
|
}
|
|
|
|
virtual STDMETHODIMP_( ULONG ) AddRef ()
|
|
{
|
|
ULONG t_ReferenceCount = InterlockedIncrement ( & m_ReferenceCount ) ;
|
|
if ( t_ReferenceCount == 1 )
|
|
{
|
|
InternalAddRef () ;
|
|
}
|
|
|
|
return t_ReferenceCount ;
|
|
}
|
|
|
|
virtual STDMETHODIMP_( ULONG ) Release ()
|
|
{
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->Lock () ;
|
|
}
|
|
|
|
LONG t_ReferenceCount = InterlockedDecrement ( & m_ReferenceCount ) ;
|
|
if ( t_ReferenceCount == 0 )
|
|
{
|
|
CallBackRelease () ;
|
|
|
|
if ( GetCached () )
|
|
{
|
|
LONG t_ReferenceCount = InterlockedDecrement ( & m_InternalReferenceCount ) ;
|
|
}
|
|
|
|
UnLockedInternalRelease () ;
|
|
}
|
|
else
|
|
{
|
|
#ifdef DBG
|
|
if ( t_ReferenceCount < 0 )
|
|
{
|
|
DebugBreak () ;
|
|
}
|
|
#endif
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->UnLock () ;
|
|
}
|
|
}
|
|
|
|
return t_ReferenceCount ;
|
|
}
|
|
|
|
virtual STDMETHODIMP_( ULONG ) InternalAddRef ()
|
|
{
|
|
ULONG t_ReferenceCount = InterlockedIncrement ( & m_InternalReferenceCount ) ;
|
|
if ( t_ReferenceCount == 1 )
|
|
{
|
|
NonCyclicAddRef () ;
|
|
}
|
|
|
|
return t_ReferenceCount ;
|
|
}
|
|
|
|
virtual STDMETHODIMP_( ULONG ) UnLockedInternalRelease ()
|
|
{
|
|
LONG t_ReferenceCount = InterlockedDecrement ( & m_InternalReferenceCount ) ;
|
|
if ( t_ReferenceCount == 0 )
|
|
{
|
|
BOOL t_DoCallBack = m_CallBackInternalRelease ;
|
|
m_CallBackInternalRelease = 0xbabab1ac ;
|
|
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->Delete ( m_Key ) ;
|
|
|
|
m_Controller->UnLock () ;
|
|
}
|
|
|
|
if ( t_DoCallBack == 1 )
|
|
{
|
|
CallBackInternalRelease () ;
|
|
}
|
|
|
|
NonCyclicRelease () ;
|
|
}
|
|
else
|
|
{
|
|
#ifdef DBG
|
|
if ( t_ReferenceCount < 0 )
|
|
{
|
|
DebugBreak () ;
|
|
}
|
|
#endif
|
|
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->UnLock () ;
|
|
}
|
|
}
|
|
|
|
return t_ReferenceCount ;
|
|
}
|
|
|
|
virtual STDMETHODIMP_( ULONG ) InternalRelease ()
|
|
{
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->Lock () ;
|
|
}
|
|
|
|
LONG t_ReferenceCount = InterlockedDecrement ( & m_InternalReferenceCount ) ;
|
|
if ( t_ReferenceCount == 0 )
|
|
{
|
|
BOOL t_DoCallBack = m_CallBackInternalRelease ;
|
|
m_CallBackInternalRelease = 0xbabab1ac ;
|
|
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->Delete ( m_Key ) ;
|
|
|
|
m_Controller->UnLock () ;
|
|
}
|
|
|
|
if ( t_DoCallBack == 1 )
|
|
{
|
|
CallBackInternalRelease () ;
|
|
}
|
|
else
|
|
{
|
|
#ifdef DBG
|
|
DebugBreak () ;
|
|
#endif
|
|
}
|
|
|
|
NonCyclicRelease () ;
|
|
}
|
|
else
|
|
{
|
|
#ifdef DBG
|
|
if ( t_ReferenceCount < 0 )
|
|
{
|
|
DebugBreak () ;
|
|
}
|
|
#endif
|
|
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->UnLock () ;
|
|
}
|
|
}
|
|
|
|
return t_ReferenceCount ;
|
|
}
|
|
|
|
virtual STDMETHODIMP_( ULONG ) NonCyclicAddRef ()
|
|
{
|
|
return InterlockedIncrement ( & m_NonCylicReferenceCount ) ;
|
|
}
|
|
|
|
virtual STDMETHODIMP_( ULONG ) NonCyclicRelease ()
|
|
{
|
|
ULONG t_ReferenceCount = InterlockedDecrement ( & m_NonCylicReferenceCount ) ;
|
|
if ( t_ReferenceCount == 0 )
|
|
{
|
|
delete this ;
|
|
}
|
|
|
|
return t_ReferenceCount ;
|
|
}
|
|
|
|
BOOL GetCached ()
|
|
{
|
|
return m_Cached ;
|
|
}
|
|
|
|
void SetCached ( BOOL a_Cached )
|
|
{
|
|
m_Cached = a_Cached ;
|
|
}
|
|
|
|
WmiKey &GetKey ()
|
|
{
|
|
return m_Key ;
|
|
}
|
|
|
|
void SetKey ( const WmiKey &a_Key )
|
|
{
|
|
m_Key = a_Key ;
|
|
}
|
|
|
|
void SetController ( WmiContainerController <WmiKey> *a_Controller )
|
|
{
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->Release () ;
|
|
}
|
|
|
|
m_Controller = a_Controller ;
|
|
if ( m_Controller )
|
|
{
|
|
m_Controller->AddRef () ;
|
|
}
|
|
}
|
|
|
|
WmiContainerController <WmiKey> *GetController ()
|
|
{
|
|
return m_Controller ;
|
|
}
|
|
|
|
} ;
|
|
|
|
typedef WmiAvlTree <WmiKey,WmiContainerElement *> Container ;
|
|
typedef typename Container :: Iterator Container_Iterator ;
|
|
|
|
private:
|
|
|
|
LONG m_ReferenceCount ;
|
|
|
|
CriticalSection m_CriticalSection ;
|
|
|
|
Container m_Container ;
|
|
|
|
protected:
|
|
public:
|
|
|
|
WmiContainerController ( WmiAllocator &a_Allocator ) ;
|
|
virtual ~WmiContainerController () ;
|
|
|
|
virtual STDMETHODIMP QueryInterface ( REFIID , LPVOID FAR * ) ;
|
|
|
|
virtual STDMETHODIMP_( ULONG ) AddRef () ;
|
|
|
|
virtual STDMETHODIMP_( ULONG ) Release () ;
|
|
|
|
virtual WmiStatusCode Initialize () ;
|
|
|
|
virtual WmiStatusCode UnInitialize () ;
|
|
|
|
virtual WmiStatusCode Lock () ;
|
|
|
|
virtual WmiStatusCode UnLock () ;
|
|
|
|
virtual WmiStatusCode Insert (
|
|
|
|
WmiContainerElement &a_Element ,
|
|
Container_Iterator &a_Iterator
|
|
) ;
|
|
|
|
virtual WmiStatusCode Find ( const WmiKey &a_Key , Container_Iterator &a_Iterator ) ;
|
|
|
|
virtual WmiStatusCode Shutdown () ;
|
|
|
|
virtual WmiStatusCode Delete ( const WmiKey &a_Key ) ;
|
|
|
|
virtual WmiStatusCode Strobe ( ULONG &a_NextStrobeDelta ) ;
|
|
|
|
WmiStatusCode GetContainer ( Container *&a_Container )
|
|
{
|
|
a_Container = & m_Container ;
|
|
return e_StatusCode_Success ;
|
|
}
|
|
|
|
CriticalSection* GetCriticalSection ()
|
|
{
|
|
return &m_CriticalSection ;
|
|
}
|
|
|
|
} ;
|
|
|
|
#include <Cache.cpp>
|
|
|
|
#endif _Cache_H
|