Windows2003-3790/base/screg/sc/server/lock.cxx
2020-09-30 16:53:55 +02:00

205 lines
4.6 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
lock.cxx
Abstract:
Contains code for the Service Control Database manager. This includes
all the database lock routines. This file contains the following
classes:
CCountingResource
CServiceListLock
CGroupListLock
Author:
Anirudh Sahni (anirudhs) 09-Jan-1997
Environment:
User Mode -Win32
Revision History:
09-Jan-1997 AnirudhS
Created, replacing the old locking functions in dataman.cxx.
--*/
//
// INCLUDES
//
#include "precomp.hxx"
//
// Macros
//
#define LOCK_LOG(string) SC_LOG3(LOCKS, " %s" string " level = %ld\n", \
_ShortName, _Name, CurrentLevel())
//
// Globals
//
CServiceRecordLock ScServiceRecordLock;
CServiceListLock ScServiceListLock;
CGroupListLock ScGroupListLock;
/*************************************************************************/
/* CCountingResource methods */
/*************************************************************************/
#if DBG
void
CCountingResource::GetShared()
{
LOCK_LOG(" Asking for %s lock shared...");
SC_ASSERT(!HaveExclusive());
RtlAcquireResourceShared(&_Lock, TRUE);
SetCurrentLevel(CurrentLevel() + 1);
LOCK_LOG("+Acquired %s lock shared,");
}
void
CCountingResource::GetExclusive()
{
LOCK_LOG(" Asking for %s lock exclusive...");
SC_ASSERT(!Have() || HaveExclusive());
RtlAcquireResourceExclusive(&_Lock, TRUE);
SetCurrentLevel(CurrentLevel() - 1);
LOCK_LOG("+Acquired %s lock exclusive,");
}
void
CCountingResource::MakeShared()
{
LOCK_LOG("vConverting %s lock to shared...");
SC_ASSERT(CurrentLevel() == -1);
RtlConvertExclusiveToShared(&_Lock);
SetCurrentLevel(1);
LOCK_LOG(" Converted %s lock to shared,");
}
void
CCountingResource::MakeExclusive()
{
// WARNING: This option is easily misused.
LOCK_LOG(" Converting %s lock to exclusive...");
SC_ASSERT(CurrentLevel() == 1);
RtlConvertSharedToExclusive(&_Lock);
SetCurrentLevel(-1);
LOCK_LOG("^Converted %s lock to exclusive,");
}
void
CCountingResource::Release()
{
LOCK_LOG("-Releasing %s lock...");
SC_ASSERT(Have());
RtlReleaseResource( &_Lock );
if (CurrentLevel() > 0)
{
SetCurrentLevel(CurrentLevel() - 1);
}
else
{
SetCurrentLevel(CurrentLevel() + 1);
}
LOCK_LOG(" Released %s lock,");
}
#endif // DBG
/*************************************************************************/
/* CServiceListLock methods */
/*************************************************************************/
#if DBG
void
CServiceListLock::GetShared()
{
// The record lock mustn't be acquired before the list lock
if (!Have())
{
SC_ASSERT(! ScServiceRecordLock.Have());
}
CCountingResource::GetShared();
}
void
CServiceListLock::GetExclusive()
{
// The record lock mustn't be acquired before the list lock
if (!Have())
{
SC_ASSERT(! ScServiceRecordLock.Have());
}
CCountingResource::GetExclusive();
}
void
CServiceListLock::Release()
{
// We mustn't release this if we still have the record lock
if (CurrentLevel() == 1 || CurrentLevel() == -1)
{
SC_ASSERT(! ScServiceRecordLock.Have());
}
CCountingResource::Release();
}
#endif // DBG
/*************************************************************************/
/* CGroupListLock methods */
/*************************************************************************/
#if DBG
void
CGroupListLock::GetShared()
{
// The service list lock mustn't be acquired before the group list lock
if (!Have())
{
SC_ASSERT(! ScServiceListLock.Have());
}
CCountingResource::GetShared();
}
void
CGroupListLock::GetExclusive()
{
// The service list lock mustn't be acquired before the group list lock
if (!Have())
{
SC_ASSERT(! ScServiceListLock.Have());
}
CCountingResource::GetExclusive();
}
void
CGroupListLock::Release()
{
// We mustn't release this if we still have the service list lock or
// service record lock
if (CurrentLevel() == 1 || CurrentLevel() == -1)
{
SC_ASSERT(! ScServiceRecordLock.Have());
SC_ASSERT(! ScServiceListLock.Have());
}
CCountingResource::Release();
}
#endif // DBG