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.
|
|
/*++
Copyright (C) 1996-2001 Microsoft Corporation
Module Name:
SYNC.H
Abstract:
Synchronization
History:
--*/
#ifndef __WBEM_CRITSEC__H_
#define __WBEM_CRITSEC__H_
#include "corepol.h"
#include <corex.h>
class POLARITY CCritSec : public CRITICAL_SECTION { public: CCritSec() { __try { InitializeCriticalSection(this); } __except( GetExceptionCode() == STATUS_NO_MEMORY ) { throw CX_MemoryException(); } }
~CCritSec() { DeleteCriticalSection(this); }
void Enter() { __try { EnterCriticalSection(this); } __except( GetExceptionCode() == STATUS_NO_MEMORY ) { throw CX_MemoryException(); } }
void Leave() { LeaveCriticalSection(this); } };
class POLARITY CTryCritSec { protected: CCritSec m_cs; CCritSec m_csControl; long m_lCount;
public: CTryCritSec() : m_lCount(0){}
void Enter() { EnterCriticalSection(&m_csControl); m_lCount++; LeaveCriticalSection(&m_csControl); EnterCriticalSection(&m_cs); } void Leave() { LeaveCriticalSection(&m_cs); EnterCriticalSection(&m_csControl); m_lCount--; LeaveCriticalSection(&m_csControl); } BOOL TryEnter() { EnterCriticalSection(&m_csControl); if(m_lCount > 0) { LeaveCriticalSection(&m_csControl); return FALSE; } else { EnterCriticalSection(&m_cs); m_lCount++; LeaveCriticalSection(&m_csControl); return TRUE; } } };
class POLARITY CInCritSec { protected: CRITICAL_SECTION* m_pcs; public: CInCritSec(CRITICAL_SECTION* pcs) : m_pcs(pcs) { __try { EnterCriticalSection(m_pcs); } __except( GetExceptionCode() == STATUS_NO_MEMORY ) { throw CX_MemoryException(); } }
inline ~CInCritSec() { LeaveCriticalSection(m_pcs); } };
class POLARITY CInTryCritSec { protected: CTryCritSec* m_ptcs;
public: CInTryCritSec(CTryCritSec* ptcs) : m_ptcs(ptcs) { m_ptcs->Enter(); } ~CInTryCritSec() { m_ptcs->Leave(); } };
// Allows user to manually leave critical section, checks if inside before leaving
class POLARITY CCheckedInCritSec { protected: CRITICAL_SECTION* m_pcs; BOOL m_fInside; public: CCheckedInCritSec(CRITICAL_SECTION* pcs) : m_pcs(pcs), m_fInside( FALSE ) { EnterCriticalSection(m_pcs); m_fInside = TRUE; } ~CCheckedInCritSec() { Leave(); }
void Enter( void ) { if ( !m_fInside ) { EnterCriticalSection(m_pcs); m_fInside = TRUE; } }
void Leave( void ) { if ( m_fInside ) { m_fInside = FALSE; LeaveCriticalSection(m_pcs); } }
BOOL IsEntered( void ) { return m_fInside; } };
//
// This class implements a light-weight exclusive lock. Critical sections are
// not very good for this because they:
// 1) Do not allow lock/unlock to occur on different threads
// 2) Do not admit timeouts
//
// On the flip side, this guy is intentionally non-reentrant.
// TBD: efficiency
//
class POLARITY CSimpleLock { protected: HANDLE m_hEvent; DWORD m_dwOwningThread; long m_lWaiting; bool m_bLocked; CCritSec m_cs;
public: CSimpleLock(); ~CSimpleLock(); DWORD Enter(DWORD dwTimeout = INFINITE); void Leave(); };
class POLARITY CHaltable { public: CHaltable(); virtual ~CHaltable(); HRESULT Halt(); HRESULT Resume(); HRESULT ResumeAll(); HRESULT WaitForResumption(); BOOL IsHalted(); bool isValid();
private: CCritSec m_csHalt; HANDLE m_hReady; DWORD m_dwHaltCount; long m_lJustResumed; };
inline bool CHaltable::isValid() { return m_hReady != NULL; };
// This class is designed to provide the behavior of a critical section,
// but without any of that pesky Kernel code. In some circumstances, we
// need to lock resources across multiple threads (i.e. we lock on one
// thread and unlock on another). If we do this using a critical section,
// this appears to work, but in checked builds, we end up throwing an
// exception. Since we actually need to do this (for example using NextAsync
// in IEnumWbemClassObject) this class can be used to perform the
// operation, but without causing exceptions in checked builds.
// Please note that code that is going to do this MUST ensure that we don't
// get crossing Enter/Leave operations (in other words, it's responsible for
// synchronizing the Enter and Leave operations.) Please note that this
// is a dangerous thing to do, so be VERY careful if you are using this
// code for that purpose.
class POLARITY CWbemCriticalSection { private:
long m_lLock; long m_lRecursionCount; DWORD m_dwThreadId; HANDLE m_hEvent;
public:
CWbemCriticalSection(); ~CWbemCriticalSection();
BOOL Enter( DWORD dwTimeout = INFINITE ); void Leave( void );
DWORD GetOwningThreadId( void ) { return m_dwThreadId; }
long GetLockCount( void ) { return m_lLock; }
long GetRecursionCount( void ) { return m_lRecursionCount; }
};
class POLARITY CEnterWbemCriticalSection { CWbemCriticalSection* m_pcs; BOOL m_fInside; public:
CEnterWbemCriticalSection( CWbemCriticalSection* pcs, DWORD dwTimeout = INFINITE ) : m_pcs( pcs ), m_fInside( FALSE ) { if ( m_pcs ) { m_fInside = m_pcs->Enter( dwTimeout ); } }
~CEnterWbemCriticalSection( void ) { if ( m_fInside ) { m_pcs->Leave(); } }
BOOL IsEntered( void ) { return m_fInside; } };
class POLARITY CScopeLock { private:
long* m_plVal;
public:
CScopeLock( long* plVal ) : m_plVal( plVal ) { if ( NULL != m_plVal ) InterlockedIncrement( m_plVal ); }
~CScopeLock() { if ( NULL != m_plVal ) InterlockedDecrement( m_plVal ); }
};
#endif
|