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) 1997 Microsoft Corporation
Module Name:
lock.h
Abstract:
Portable synronization primitive class ( between Win9x and NT) Win9x does not
Author:
Vlad Sadovsky (vlads) 02-Jan-1997
Environment:
User Mode - Win32
Revision History:
02-Jan-1997 VladS created
--*/
# ifndef _LOCK_H_
# define _LOCK_H_
/************************************************************
* Include Headers ************************************************************/
# ifdef _cplusplus
extern "C" { # endif // _cplusplus
# ifdef _cplusplus
}; // extern "C"
# endif // _cplusplus
#ifndef DBG_REQUIRE
#define DBG_REQUIRE REQUIRE
#endif
#ifndef RTL_RESOURCE
//
// Shared resource function definitions. It is declared in NTRTL , but not in windows SDK header files
//
typedef struct _RTL_RESOURCE {
//
// The following field controls entering and exiting the critical
// section for the resource
//
RTL_CRITICAL_SECTION CriticalSection;
//
// The following four fields indicate the number of both shared or
// exclusive waiters
//
HANDLE SharedSemaphore; ULONG NumberOfWaitingShared; HANDLE ExclusiveSemaphore; ULONG NumberOfWaitingExclusive;
//
// The following indicates the current state of the resource
//
// <0 the resource is acquired for exclusive access with the
// absolute value indicating the number of recursive accesses
// to the resource
//
// 0 the resource is available
//
// >0 the resource is acquired for shared access with the
// value indicating the number of shared accesses to the resource
//
LONG NumberOfActive; HANDLE ExclusiveOwnerThread;
ULONG Flags; // See RTL_RESOURCE_FLAG_ equates below.
PVOID DebugInfo; } RTL_RESOURCE, *PRTL_RESOURCE;
#define RTL_RESOURCE_FLAG_LONG_TERM ((ULONG) 0x00000001)
#endif // RTL_RESOURCE
/************************************************************
* Type Definitions ************************************************************/
# ifdef _cplusplus
extern "C" { # endif // _cplusplus
BOOL InitializeResource( IN PRTL_RESOURCE Resource );
BOOL AcquireResourceShared( IN PRTL_RESOURCE Resource, IN BOOL Wait );
BOOL AcquireResourceExclusive( IN PRTL_RESOURCE Resource, IN BOOL Wait );
BOOL ReleaseResource( IN PRTL_RESOURCE Resource );
BOOL ConvertSharedToExclusive( IN PRTL_RESOURCE Resource );
BOOL ConvertExclusiveToShared( IN PRTL_RESOURCE Resource );
VOID DeleteResource ( IN PRTL_RESOURCE Resource );
# ifdef _cplusplus
}; // extern "C"
# endif // _cplusplus
///////////////////////////////////////////////////////////////////////
//
// Simple RTL_RESOURCE Wrapper class
//
//////////////////////////////////////////////////////////////////////
enum SYNC_LOCK_TYPE { SYNC_LOCK_READ = 0, // Take the lock for read only
SYNC_LOCK_WRITE // Take the lock for write
};
enum SYNC_CONV_TYPE { SYNC_CONV_READ = 0, // Convert the lock from write to read
SYNC_CONV_WRITE // Convert the lock from read to write
};
class SYNC_RESOURCE {
friend class TAKE_SYNC_RESOURCE;
public:
SYNC_RESOURCE() { InitializeResource( &_rtlres ); }
~SYNC_RESOURCE() { DeleteResource( &_rtlres ); }
void Lock( enum SYNC_LOCK_TYPE type ) { if ( type == SYNC_LOCK_READ ) { DBG_REQUIRE( AcquireResourceShared( &_rtlres, TRUE ) ); } else { DBG_REQUIRE( AcquireResourceExclusive( &_rtlres, TRUE )); } }
void Convert( enum SYNC_CONV_TYPE type ) { if ( type == SYNC_CONV_READ ) { DBG_REQUIRE( ConvertExclusiveToShared( &_rtlres )); } else { DBG_REQUIRE( ConvertSharedToExclusive( &_rtlres )); } }
void Unlock( VOID ) { DBG_REQUIRE( ReleaseResource( &_rtlres )); }
private: RTL_RESOURCE _rtlres; };
///////////////////////////////////////////////////////////////////
// Instantiate one of these classes in a block of code
// when you want that block of code to be protected
// against re-entrancy.
// The Take() and Release() functions should rarely be necessary,
// and must be used in matched pairs with Release() called first.
///////////////////////////////////////////////////////////////////
class TAKE_SYNC_RESOURCE { private: SYNC_RESOURCE& _syncres;
public: void Take(void) { _syncres.Lock(SYNC_LOCK_WRITE); } void Release(void) { _syncres.Unlock(); } TAKE_SYNC_RESOURCE(SYNC_RESOURCE& syncres) : _syncres(syncres) { Take(); } ~TAKE_SYNC_RESOURCE() { Release(); } };
//
// Auto critical section clss
//
class CRIT_SECT { public: BOOL Lock() { if (m_bInitialized) { EnterCriticalSection(&m_sec); return TRUE; } return FALSE; }
void Unlock() { LeaveCriticalSection(&m_sec); }
CRIT_SECT() { m_bInitialized = FALSE; __try { #ifdef UNICODE
if(InitializeCriticalSectionAndSpinCount(&m_sec, MINLONG)) { #else
InitializeCriticalSection(&m_sec); { #endif
m_bInitialized = TRUE; } } __except (EXCEPTION_EXECUTE_HANDLER) { } }
~CRIT_SECT() { if (m_bInitialized) { DeleteCriticalSection(&m_sec); m_bInitialized = FALSE; } } BOOL IsInitialized() {return m_bInitialized;}
CRITICAL_SECTION m_sec; BOOL m_bInitialized; };
class TAKE_CRIT_SECT { private: CRIT_SECT& _syncres; BOOL m_bLocked;
public: inline TAKE_CRIT_SECT(CRIT_SECT& syncres) : _syncres(syncres), m_bLocked(FALSE) { m_bLocked = _syncres.Lock(); } inline ~TAKE_CRIT_SECT() { if (m_bLocked) {_syncres.Unlock(); m_bLocked = FALSE;}; } };
//
// Auto mutex class
//
class MUTEX_OBJ { private: HANDLE m_hMutex;
public: BOOL inline IsValid(VOID) {return (m_hMutex!=INVALID_HANDLE_VALUE);} void Lock() { ::WaitForSingleObject(m_hMutex, INFINITE); } void Unlock() { ::ReleaseMutex(m_hMutex); } MUTEX_OBJ(LPCTSTR pszName) { m_hMutex = ::CreateMutex(NULL, FALSE, pszName ); }
~MUTEX_OBJ() {CloseHandle(m_hMutex);m_hMutex = INVALID_HANDLE_VALUE;} };
class TAKE_MUTEX { private: HANDLE const m_hMutex;
public: void Take(void) { ::WaitForSingleObject(m_hMutex, INFINITE); } void Release(void) { ::ReleaseMutex(m_hMutex); } TAKE_MUTEX(HANDLE hMutex) : m_hMutex(hMutex) { Take(); } ~TAKE_MUTEX() { Release(); } };
class TAKE_MUTEX_OBJ { private: MUTEX_OBJ& _syncres;
public: inline TAKE_MUTEX_OBJ(MUTEX_OBJ& syncres) : _syncres(syncres) { _syncres.Lock(); } inline ~TAKE_MUTEX_OBJ() { _syncres.Unlock(); } };
# endif // _LOCK_H_
|