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.
 
 
 
 
 
 

220 lines
8.2 KiB

// Ruler
// 1 2 3 4 5 6 7 8
//345678901234567890123456789012345678901234567890123456789012345678901234567890
/********************************************************************/
/* */
/* The standard layout. */
/* */
/* The standard layout for 'cpp' files in this code is as */
/* follows: */
/* */
/* 1. Include files. */
/* 2. Constants local to the class. */
/* 3. Data structures local to the class. */
/* 4. Data initializations. */
/* 5. Static functions. */
/* 6. Class functions. */
/* */
/* The constructor is typically the first function, class */
/* member functions appear in alphabetical order with the */
/* destructor appearing at the end of the file. Any section */
/* or function this is not required is simply omitted. */
/* */
/********************************************************************/
#include "HeapPCH.hpp"
#include "ThreadSafe.hpp"
/********************************************************************/
/* */
/* Constants local to the class. */
/* */
/* The constants supplied here control the global lock. */
/* */
/********************************************************************/
CONST SBIT32 NoThread = -1;
/********************************************************************/
/* */
/* Class constructor. */
/* */
/* Create a thread safe class and prepare it for use. This is */
/* pretty small but needs to be done with a bit of thought. */
/* */
/********************************************************************/
THREAD_SAFE::THREAD_SAFE( BOOLEAN NewThreadSafe )
{
//
// Setup the class variables.
//
Claim = NoThread;
Owner = NoThread;
Recursive = 0;
ThreadSafe = NewThreadSafe;
}
/********************************************************************/
/* */
/* Claim a global lock. */
/* */
/* When we try to claim the global lock we first need to be */
/* sure we have not already go it. If not we try to claim it */
/* and register our ownership. */
/* */
/********************************************************************/
BOOLEAN THREAD_SAFE::ClaimGlobalLock( VOID )
{
//
// We only need to do something when we have
// locking enabled for this heap.
//
if ( ThreadSafe )
{
REGISTER SBIT32 CurrentThread = GetThreadId();
//
// We only try to claim the global lock
// if we have not already got it.
//
if ( CurrentThread != Claim )
{
//
// Claim the associated spinlock and
// and then register our claim to the
// global lock.
//
Spinlock.ClaimLock();
Claim = CurrentThread;
return True;
}
else
{ Recursive ++; }
}
return False;
}
/********************************************************************/
/* */
/* Engage a global lock. */
/* */
/* When we have claimed the global lock we can wait for a */
/* while before we engage it. This gives us time to get the */
/* locks we want before disabling all further lock calls. */
/* */
/********************************************************************/
VOID THREAD_SAFE::EngageGlobalLock( VOID )
{
//
// We only need to do something when we have
// locking enabled for this heap.
//
if ( ThreadSafe )
{
REGISTER SBIT32 CurrentThread = GetThreadId();
//
// Just for fun lets make sure that the caller
// has already claimed the global lock. If not
// then we fail.
//
if ( CurrentThread == Claim )
{
//
// We now engage the global lock so all future
// locking calls will be disabled.
//
Owner = CurrentThread;
}
else
{ Failure( "No claim before engage in EngageGlobalLock" ); }
}
}
/********************************************************************/
/* */
/* Release the global lock. */
/* */
/* When we have finished we may release the global lock so */
/* that others may use it. */
/* */
/********************************************************************/
BOOLEAN THREAD_SAFE::ReleaseGlobalLock( BOOLEAN Force )
{
//
// We only need to do something when we have
// locking enabled for this heap.
//
if ( ThreadSafe )
{
REGISTER SBIT32 CurrentThread = GetThreadId();
//
// Just for fun lets make sure that the caller
// has already claimed the global lock. If not
// and we have not been told to force the issue
// then fail.
//
if
(
(CurrentThread == Claim)
||
((Force) && (Claim != NoThread))
)
{
//
// We may have had some recursive calls. If
// so then exit these calls before releasing
// the global lock.
//
if ( Recursive <= 0 )
{
//
// Delete the ownership information and
// free the associated spinlock.
//
Claim = NoThread;
Owner = NoThread;
Spinlock.ReleaseLock();
return True;
}
else
{ Recursive --; }
}
else
{ Failure( "No claim before release in ReleaseGlobalLock" ); }
}
return False;
}
/********************************************************************/
/* */
/* Class destructor. */
/* */
/* Delete the thread safe calls and free any associated */
/* resources. */
/* */
/********************************************************************/
THREAD_SAFE::~THREAD_SAFE( VOID )
{
//
// Just for fun lets just check that the
// lock is free. If not we fail.
//
if ( (Claim != NoThread) || (Owner != NoThread) || (Recursive != 0) )
{ Failure( "Global lock busy in destructor for THREAD_SAFE" ); }
}