mirror of https://github.com/lianthony/NT4.0
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.
164 lines
3.0 KiB
164 lines
3.0 KiB
/*++
|
|
|
|
Microsoft Windows NT RPC Name Service
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
mutex.cxx
|
|
|
|
Abstract:
|
|
|
|
This file contains the implementations for non inline member functions of
|
|
CReadWriteSection and CPrivateSemaphore, which implement a readers/writers
|
|
mutex and a multi-owner mutex, respectively.
|
|
|
|
Author:
|
|
|
|
Satish Thatte (SatishT) 09/01/95 Created all the code below except where
|
|
otherwise indicated.
|
|
|
|
--*/
|
|
|
|
#define NULL 0
|
|
|
|
extern "C" {
|
|
#include <windows.h>
|
|
}
|
|
|
|
#include <mutex.hxx>
|
|
|
|
int
|
|
CReadWriteSection::readerEnter()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Reader may enter if no writer is in the section or waiting to enter it.
|
|
Readers keep count of themselves and when the count drops to zero
|
|
they release PSemWriterBlock so writers may enter.
|
|
|
|
Results:
|
|
|
|
Count of current readers.
|
|
|
|
--*/
|
|
|
|
{
|
|
/* wait for writer if one is in or waiting, otherwise
|
|
bump up reader count and block writer if first reader */
|
|
|
|
DBGOUT(SEM, "Entering readerEnter\n");
|
|
|
|
SimpleCriticalSection me1(PCSReaderBlock);
|
|
|
|
SimpleCriticalSection me2(PCSCountBlock);
|
|
|
|
DBGOUT(SEM, "ulReaderCount = " << ulReaderCount << "\n");
|
|
|
|
if (ulReaderCount++); // other readers already in
|
|
else PSemWriterBlock.Enter(); // otherwise, block writer's entry
|
|
|
|
DBGOUT(SEM, "Leaving readerEnter\n");
|
|
DBGOUT(SEM, "ulReaderCount = " << ulReaderCount << "\n");
|
|
|
|
return ulReaderCount; // BUGBUG: this looks meaningless though harmless!
|
|
}
|
|
|
|
|
|
int
|
|
CReadWriteSection::readerLeave()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
A reader leaves, decrementing the ulReaderCount and releasing PSemWriterBlock
|
|
if appropriate.
|
|
|
|
Results:
|
|
|
|
Count of current readers as seen during count update.
|
|
|
|
--*/
|
|
|
|
{
|
|
DBGOUT(SEM, "Entering readerLeave\n");
|
|
DBGOUT(SEM, "ulReaderCount = " << ulReaderCount << "\n");
|
|
|
|
SimpleCriticalSection me(PCSCountBlock);
|
|
|
|
if (--ulReaderCount); // other readers still in
|
|
else PSemWriterBlock.Leave(); // otherwise, release writer's entry
|
|
|
|
return ulReaderCount; // BUGBUG: this looks meaningless though harmless!
|
|
}
|
|
|
|
|
|
|
|
CPrivateSemaphore::CPrivateSemaphore(
|
|
long lMaxCount
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
create a semaphore and initialize the handle member pNTSem.
|
|
|
|
--*/
|
|
{
|
|
// DBGOUT(SEM, "Creating Semaphore with counts =" << lMaxCount << "\n");
|
|
|
|
pNTSem = CreateSemaphore(
|
|
NULL, // pointer to security attributes
|
|
lMaxCount, // initial count
|
|
lMaxCount, // maximum count
|
|
NULL // pointer to semaphore-object name
|
|
);
|
|
}
|
|
|
|
|
|
|
|
CPrivateSemaphore::~CPrivateSemaphore()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
close the semaphore handle.
|
|
|
|
--*/
|
|
{
|
|
CloseHandle(pNTSem);
|
|
}
|
|
|
|
|
|
void
|
|
CPrivateSemaphore::Enter()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Wait for the semaphore count to become nonzero.
|
|
|
|
--*/
|
|
{
|
|
WaitForSingleObject(pNTSem,INFINITE);
|
|
}
|
|
|
|
|
|
void
|
|
CPrivateSemaphore::Leave(long lIncrement)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Increment the semaphore count by lIncrement to release lIncrement "slots".
|
|
|
|
--*/
|
|
{
|
|
DBGOUT(SEM1, "Releasing Semaphore with Increment =" << lIncrement << "\n");
|
|
|
|
ReleaseSemaphore(pNTSem,lIncrement,NULL);
|
|
}
|
|
|