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.
|
|
/*--------------------------------------------------------
rwlock.h CReadWriteLock class provides functions that allow threads to lock any resource in two different modes (read-mode and write-mode). The class will allow multiple reader threads to access the resource simultaneously, but will make sure that a writer thread doesn't access the resource when reader threads or a writer thread is currently accessing the resource. The class also assures fairness in access i.e. the access will be regulated by a first-come-first-in policy.
Note:- ALL the functions in the class are INLINE functions. So, this header can be directly used in the source.
Copyright (C) 1995 Microsoft Corporation All rights reserved.
Authors: rsraghav R.S. Raghavan
History: 04-20-95 rsraghav Created.
-------------------------------------------------------*/
#ifdef __cplusplus // this file should be include only if this is
// is included in a c++ source file.
#ifndef _RWLOCK_H_
#define _RWLOCK_H_
#if defined(DEBUG) && defined(INLINE)
#undef THIS_FILE
static char BASED_CODE RWLOCK_H[] = "rwlock.h"; #define THIS_FILE RWLOCK_H
#endif
#include <windows.h>
#define INLINE_EXPORT_SPEC __declspec( dllexport)
typedef enum {RWLOCK_READ_MODE, RWLOCK_WRITE_MODE} RWLOCK_MODE;
//////////////////////////////////////////////////////////////////////
// CReadWriteLock - Class that can be used to regulate read-write
// access to resource, where multiple readers are
// allowed simultaneously, but writers are excluded
// from each other and from the readers.
class INLINE_EXPORT_SPEC CReadWriteLock { HANDLE hResource; CRITICAL_SECTION csReader; CRITICAL_SECTION csWriter; DWORD cReaders; DWORD cWriteRecursion;
public: CReadWriteLock() // object constructor
{ cReaders =0; cWriteRecursion = 0; hResource = CreateEvent(NULL, FALSE, TRUE, NULL); // no manual reset & initial state is signalled
InitializeCriticalSection(&csReader); InitializeCriticalSection(&csWriter); }
~CReadWriteLock() // object destructor
{ if (hResource) CloseHandle(hResource); DeleteCriticalSection(&csReader); DeleteCriticalSection(&csWriter); }
CReadWriteLock *PrwLock() { return this; }
BOOL FInit() { return (BOOL)hResource; }
void LockReadMode() // Get read access to the resource
{ EnterCriticalSection(&csWriter); LeaveCriticalSection(&csWriter); EnterCriticalSection(&csReader); if (!cReaders) { if (hResource) WaitForSingleObject(hResource, INFINITE); } cReaders++; LeaveCriticalSection(&csReader); }
int LockReadModeEx(int iTimeOut) // Get read access to the resource w/ Timeout
{ int status = 0;
EnterCriticalSection(&csWriter); LeaveCriticalSection(&csWriter); EnterCriticalSection(&csReader); if (!cReaders) { if (hResource) { status = WaitForSingleObject(hResource, iTimeOut); if (status == WAIT_TIMEOUT) { status = -1; } else { status = 0; } } } cReaders++; LeaveCriticalSection(&csReader);
return status; }
void UnlockReadMode() // Relinquish read access to the resource
{ EnterCriticalSection(&csReader); if (!(--cReaders)) { if (hResource) SetEvent(hResource); } LeaveCriticalSection(&csReader); }
void LockCSUnderRead() { EnterCriticalSection(&csReader); } void UnlockCSUnderRead() { LeaveCriticalSection(&csReader); }
void LockWriteMode() // Get write access to the resource
{ EnterCriticalSection(&csWriter); if (!cWriteRecursion) { if (hResource) WaitForSingleObject(hResource, INFINITE); } cWriteRecursion++; } int LockWriteModeEx(int iTimeOut) // Get write access to the resource
{ int status = 0;
EnterCriticalSection(&csWriter); if (!cWriteRecursion) { if (hResource) { status = WaitForSingleObject(hResource, iTimeOut); if (status == WAIT_TIMEOUT) { LeaveCriticalSection(&csWriter); status = -1; } else { status = 0; } } } if (status == 0) cWriteRecursion++;
return status; }
void UnlockWriteMode() // Relinquish write access to the resource
{ if (!(--cWriteRecursion)) { if (hResource) SetEvent(hResource); } LeaveCriticalSection(&csWriter); } };
//////////////////////////////////////////////////////////////////////
// Following class is just a utility class - users don't need to
// necessarily use this class for obtaining read-write lock functionalities.
//////////////////////////////////////////////////////////////////////
// CScopeRWLock - This can be used to lock the given CReadWriteLock
// object for the rest of the scope. The user just
// needs to define this object in the scope by passing
// a pointer to the CReadWriteLock object in the constructor.
// When this CScopeRWLock object goes out of scope the
// CReadWriteLock object will automatically be unlocked.
// This is provided just for user convenience so that the
// user can choose to avoid remembering to unlock the object
// before every possible return/break path of the scope.
// Use the RWLOCK_READ_MODE or RWLOCK_WRITE_MODE in the constructor
// to indicate which type of access is requested.
// Assumption:- CReadWriteLock object used here is expected to
// be valid at lease until the end of the scope.
class INLINE_EXPORT_SPEC CScopeRWLock { CReadWriteLock *m_prwLock; LPCRITICAL_SECTION m_pcs; RWLOCK_MODE m_rwMode;
public: CScopeRWLock(CReadWriteLock * prwLock, RWLOCK_MODE rwMode) { m_prwLock = prwLock; m_pcs = NULL; m_rwMode = rwMode; if (m_prwLock) { if (m_rwMode == RWLOCK_READ_MODE) m_prwLock->LockReadMode(); else if (m_rwMode == RWLOCK_WRITE_MODE) m_prwLock->LockWriteMode(); } }
CScopeRWLock(LPCRITICAL_SECTION pcsLock) { m_pcs = pcsLock; m_prwLock = NULL; if (m_pcs) EnterCriticalSection(m_pcs); }
~CScopeRWLock() { if (m_prwLock) { if (m_rwMode == RWLOCK_READ_MODE) m_prwLock->UnlockReadMode(); else if (m_rwMode == RWLOCK_WRITE_MODE) m_prwLock->UnlockWriteMode(); } if (m_pcs) { LeaveCriticalSection(m_pcs); } } };
#endif // _RWLOCK_H_
#endif // #if __cplusplus
|