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.
 
 
 
 
 
 

191 lines
3.8 KiB

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
reslock.hxx
Abstract:
Contains RESOURCE_LOCK class
Author:
Richard L Firth (rfirth) 18-Jun-1996
Revision History:
18-Jun-1996 rfirth
Created
--*/
//
// manifests
//
#if INET_DEBUG
#define DEFAULT_RESOURCE_LOCK_TIMEOUT 30000 // 30 seconds
#else
#define DEFAULT_RESOURCE_LOCK_TIMEOUT INFINITE
#endif
//
// class definition
//
class RESOURCE_LOCK {
private:
//
// _Initialized - TRUE when the critical section & event have been created
//
BOOL _Initialized;
//
// _WriteCount - number of times writer has re-entered
//
LONG _WriteCount;
//
// _ThreadId - ID of the owning writer thread
//
DWORD _ThreadId;
//
// _Readers - number of reader threads. Used as a switch in concert with
// InterlockedIncrement/InterlockedDecrement: -1 => 0 means this is the
// first reader, and we reset the writer wait event; 0 => -1 means this is
// the last reader and we set the writer wait event
//
LONG _Readers;
//
// _Timeout - number of milliseconds to wait for one of the event handles
//
DWORD _Timeout;
//
// _hWriteEvent - signalled when the last reader thread exits. At this time
// the writer thread has exclusive access
//
HANDLE _hWriteEvent;
//
// _CritSect - used to serialize access. Writer keeps this until Releas()ed.
// Readers just keep it long enough to update _Readers variable
//
CCritSec _CritSect;
//
// Wait - wait for an event to become signalled
//
BOOL Wait(HANDLE hEvent) {
DWORD error = WaitForSingleObject(hEvent, _Timeout);
if (error == WAIT_OBJECT_0) {
return TRUE;
} else {
DEBUG_PRINT(UTIL,
ERROR,
("RESOURCE_LOCK::Wait(): WaitForSingleObject() returns %d\n",
error
));
if (error == WAIT_TIMEOUT) {
error = ERROR_WINHTTP_TIMEOUT;
} else {
error = ERROR_WINHTTP_INTERNAL_ERROR;
}
SetLastError(error);
return FALSE;
}
}
VOID SetTimeout(DWORD Timeout) {
_Timeout = Timeout;
}
DWORD GetTimeout(VOID) const {
return _Timeout;
}
public:
RESOURCE_LOCK() {
_WriteCount = 0;
_ThreadId = 0;
_Readers = -1;
_Timeout = DEFAULT_RESOURCE_LOCK_TIMEOUT;
_hWriteEvent = NULL;
_Initialized = FALSE;
}
~RESOURCE_LOCK() {
INET_ASSERT(_WriteCount == 0);
INET_ASSERT(_ThreadId == 0);
INET_ASSERT(_Readers == -1);
if (_hWriteEvent != NULL) {
CloseHandle(_hWriteEvent);
}
}
VOID Initialize(VOID) {
_WriteCount = 0;
_ThreadId = 0;
_Readers = -1;
_Timeout = DEFAULT_RESOURCE_LOCK_TIMEOUT;
_CritSect.Init();
//
// _hWriteEvent is an auto-reset, initially-signalled event
//
_hWriteEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
if (_CritSect.IsInitialized() && _hWriteEvent != NULL)
_Initialized = TRUE;
else
_Initialized = FALSE;
}
BOOL IsInitialized(VOID) const {
return _Initialized;
}
BOOL IsValid(VOID) const {
return (_hWriteEvent != NULL) ? TRUE : FALSE;
}
BOOL
Acquire(
IN BOOL bExclusiveMode = FALSE
);
BOOL AcquireExclusive(VOID) {
return Acquire(TRUE);
}
VOID
Release(
VOID
);
};