335 lines
7.0 KiB
C++
335 lines
7.0 KiB
C++
/*++
|
||
|
||
Copyright (c) 1996 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
reslock.cxx
|
||
|
||
Abstract:
|
||
|
||
Contains methods for RESOURCE_LOCK class
|
||
|
||
Contents:
|
||
RESOURCE_LOCK::Acquire()
|
||
RESOURCE_LOCK::Release()
|
||
|
||
Author:
|
||
|
||
Richard L Firth (rfirth) 18-Jun-1996
|
||
|
||
Revision History:
|
||
|
||
18-Jun-1996 rfirth
|
||
Created
|
||
|
||
--*/
|
||
|
||
#include <wininetp.h>
|
||
|
||
//
|
||
// class members
|
||
//
|
||
|
||
#ifdef OLD_VERSION
|
||
|
||
|
||
BOOL
|
||
RESOURCE_LOCK::Acquire(
|
||
IN BOOL bExclusiveMode
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Acquires the resource protected by this lock. Acquires for non-exclusive
|
||
(read) or exclusive (write) ownership
|
||
|
||
Arguments:
|
||
|
||
bExclusiveMode - TRUE if we are acquiring the resource for exclusive
|
||
(write) ownership
|
||
|
||
Return Value:
|
||
|
||
BOOL
|
||
TRUE - resource is acquired
|
||
|
||
FALSE - failed to acquire resource (timeout?)
|
||
|
||
--*/
|
||
|
||
{
|
||
DEBUG_ENTER((DBG_RESLOCK,
|
||
Bool,
|
||
"RESOURCE_LOCK::Acquire",
|
||
"%B",
|
||
bExclusiveMode
|
||
));
|
||
|
||
INET_ASSERT(this != NULL);
|
||
//INET_ASSERT(IsInitialized());
|
||
//INET_ASSERT(IsValid());
|
||
|
||
if (!IsInitialized()) {
|
||
|
||
DEBUG_LEAVE(FALSE);
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
BOOL acquired = TRUE;
|
||
|
||
//EnterCriticalSection(&_CritSect);
|
||
if (bExclusiveMode) {
|
||
|
||
//
|
||
// acquired for exclusive ownership (write access). Set the owning
|
||
// thread id and wait for the last current reader to release. Note
|
||
// that if we're being re-entered, EnterCriticalSection() has already
|
||
// done the work of checking the thread id and updating re-entrancy
|
||
// counts, so if its already not zero, we know it must be us
|
||
//
|
||
|
||
++_WriteCount;
|
||
if (_ThreadId == 0) {
|
||
_ThreadId = GetCurrentThreadId();
|
||
#if INET_DEBUG
|
||
INET_ASSERT(_ThreadId != _ThreadIdReader);
|
||
#endif
|
||
acquired = Wait(_hWriteEvent);
|
||
EnterCriticalSection(&_CritSect);
|
||
} else {
|
||
|
||
INET_ASSERT(_ThreadId == GetCurrentThreadId());
|
||
|
||
}
|
||
} else {
|
||
|
||
//
|
||
// don't allow re-entry if already held for exclusive access
|
||
//
|
||
|
||
INET_ASSERT(_ThreadId == 0);
|
||
|
||
//
|
||
// acquired for non-exclusive ownership (read access). Just increase
|
||
// the number of active readers. If this is the first then inhibit the
|
||
// writer
|
||
//
|
||
|
||
if (InterlockedIncrement(&_Readers) == 0) {
|
||
#if INET_DEBUG
|
||
if (_ThreadIdReader == 0) {
|
||
_ThreadIdReader = GetCurrentThreadId();
|
||
}
|
||
#endif
|
||
ResetEvent(_hWriteEvent);
|
||
}
|
||
|
||
//
|
||
// reader doesn't need to keep hold of critical section
|
||
//
|
||
|
||
//LeaveCriticalSection(&_CritSect);
|
||
}
|
||
|
||
DEBUG_LEAVE(acquired);
|
||
|
||
return acquired;
|
||
}
|
||
|
||
|
||
VOID
|
||
RESOURCE_LOCK::Release(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Releases a resource previously acquired by RESOURCE_LOCK::Acquire()
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
DEBUG_ENTER((DBG_RESLOCK,
|
||
None,
|
||
"RESOURCE_LOCK::Release",
|
||
NULL
|
||
));
|
||
|
||
INET_ASSERT(this != NULL);
|
||
//INET_ASSERT(IsInitialized());
|
||
//INET_ASSERT(IsValid());
|
||
|
||
if (!IsInitialized()) {
|
||
|
||
DEBUG_LEAVE(0);
|
||
|
||
return;
|
||
}
|
||
|
||
if ((_ThreadId != 0) && (_ThreadId == GetCurrentThreadId())) {
|
||
|
||
INET_ASSERT(_WriteCount > 0);
|
||
|
||
if (--_WriteCount == 0) {
|
||
|
||
//
|
||
// we acquired _hWriteEvent; signal it to allow next writer to continue
|
||
//
|
||
|
||
SetEvent(_hWriteEvent);
|
||
|
||
//
|
||
// this resource no longer owned for exclusive access
|
||
//
|
||
|
||
_ThreadId = 0;
|
||
}
|
||
LeaveCriticalSection(&_CritSect);
|
||
} else if (InterlockedDecrement(&_Readers) < 0) {
|
||
|
||
INET_ASSERT(_Readers >= -1);
|
||
|
||
//
|
||
// we are last currently active reader; allow waiting writer to continue
|
||
//
|
||
|
||
#if INET_DEBUG
|
||
if (_ThreadIdReader == GetCurrentThreadId()) {
|
||
_ThreadIdReader = 0;
|
||
}
|
||
#endif
|
||
SetEvent(_hWriteEvent);
|
||
}
|
||
|
||
DEBUG_LEAVE(0);
|
||
}
|
||
|
||
#else
|
||
|
||
BOOL
|
||
RESOURCE_LOCK::Acquire(
|
||
IN BOOL bExclusiveMode
|
||
)
|
||
{
|
||
DEBUG_ENTER((DBG_RESLOCK,
|
||
Bool,
|
||
"RESOURCE_LOCK::Acquire",
|
||
"%B",
|
||
bExclusiveMode
|
||
));
|
||
|
||
if (!IsInitialized()) {
|
||
|
||
DEBUG_LEAVE(FALSE);
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
if (bExclusiveMode) {
|
||
do {
|
||
|
||
DEBUG_PRINT(RESLOCK,
|
||
INFO,
|
||
("Waiting on WriteEvent\n")
|
||
);
|
||
|
||
if (_ThreadId != GetCurrentThreadId()) {
|
||
Wait(_hWriteEvent);
|
||
}
|
||
EnterCriticalSection(&_CritSect);
|
||
|
||
INET_ASSERT((_ThreadId == 0) || (_ThreadId == GetCurrentThreadId()));
|
||
|
||
if ((_Readers == -1)
|
||
&& ((_ThreadId == 0) || (_ThreadId == GetCurrentThreadId()))) {
|
||
_ThreadId = GetCurrentThreadId();
|
||
if (++_WriteCount == 1) {
|
||
ResetEvent(_hWriteEvent);
|
||
}
|
||
break;
|
||
}
|
||
|
||
DEBUG_PRINT(RESLOCK,
|
||
INFO,
|
||
("trying again\n")
|
||
);
|
||
|
||
LeaveCriticalSection(&_CritSect);
|
||
} while ( 1 );
|
||
} else {
|
||
EnterCriticalSection(&_CritSect);
|
||
if (++_Readers == 0) {
|
||
|
||
DEBUG_PRINT(RESLOCK,
|
||
INFO,
|
||
("Resetting WriteEvent\n")
|
||
);
|
||
|
||
ResetEvent(_hWriteEvent);
|
||
}
|
||
LeaveCriticalSection(&_CritSect);
|
||
}
|
||
|
||
DEBUG_LEAVE(TRUE);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
VOID
|
||
RESOURCE_LOCK::Release(
|
||
VOID
|
||
)
|
||
{
|
||
DEBUG_ENTER((DBG_RESLOCK,
|
||
None,
|
||
"RESOURCE_LOCK::Release",
|
||
NULL
|
||
));
|
||
|
||
if (IsInitialized()) {
|
||
if (_ThreadId == GetCurrentThreadId()) {
|
||
|
||
DEBUG_PRINT(RESLOCK,
|
||
INFO,
|
||
("Clearing writer\n")
|
||
);
|
||
|
||
if (--_WriteCount == 0) {
|
||
_ThreadId = 0;
|
||
SetEvent(_hWriteEvent);
|
||
}
|
||
LeaveCriticalSection(&_CritSect);
|
||
} else {
|
||
EnterCriticalSection(&_CritSect);
|
||
if (--_Readers == -1) {
|
||
|
||
DEBUG_PRINT(RESLOCK,
|
||
INFO,
|
||
("Setting WriteEvent\n")
|
||
);
|
||
|
||
SetEvent(_hWriteEvent);
|
||
}
|
||
LeaveCriticalSection(&_CritSect);
|
||
}
|
||
}
|
||
|
||
DEBUG_LEAVE(0);
|
||
}
|
||
|
||
#endif // OLD_VERSION
|