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.
 
 
 
 
 
 

139 lines
3.0 KiB

// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
/*--------------------------------------------------
Filename: sync.hpp
Author: B.Rajeev
Purpose: Provides declarations for the MutexLock and
the SemaphoreLock classes (derived from a
generic Lock template class)
--------------------------------------------------*/
#ifndef __SYNC__
#define __SYNC__
// for exception specification
#include "excep.h"
typedef HANDLE Mutex;
typedef HANDLE Semaphore;
#define IMMEDIATE 0
// a generic template class used to build synchronization primitives
// like a Mutex and a Semaphore
template <class SyncObjType>
class Lock
{
protected:
// the sync_obj may be a mutex/semaphore etc.
SyncObjType sync_obj;
// number of locks on the sync obj
LONG num_locks;
// an option that specifies if the held locks must be released
// when the lock is destroyed
BOOL release_on_destroy;
virtual DWORD OpenOperation(DWORD wait_time) = 0 ;
virtual BOOL ReleaseOperation(LONG num_release = 1,
LONG *previous_count = NULL) = 0;
public:
Lock(SyncObjType sync_obj, BOOL release_on_destroy = TRUE) : sync_obj ( sync_obj )
{
num_locks = 0;
Lock::release_on_destroy = release_on_destroy;
}
BOOL GetLock(DWORD wait_time);
UINT UnLock(LONG num_release = 1);
};
template <class SyncObjType>
BOOL Lock<SyncObjType>::GetLock(DWORD wait_time)
{
DWORD wait_result = OpenOperation (wait_time);
if ( wait_result == WAIT_FAILED )
return FALSE;
else if ( wait_result == WAIT_TIMEOUT )
return FALSE;
else
{
num_locks++;
return TRUE;
}
}
template <class SyncObjType>
UINT Lock<SyncObjType>::UnLock(LONG num_release)
{
LONG previous_count;
BOOL release_result =
ReleaseOperation(num_release, &previous_count);
if ( release_result == TRUE )
num_locks -= num_release;
else
throw GeneralException(Snmp_Error, Snmp_Local_Error);
return previous_count;
}
class CriticalSectionLock;
class CriticalSection
{
friend CriticalSectionLock;
private:
CRITICAL_SECTION m_CriticalSection ;
public:
CriticalSection ()
{
InitializeCriticalSection ( &m_CriticalSection ) ;
}
~CriticalSection()
{
DeleteCriticalSection ( &m_CriticalSection ) ;
}
};
class CriticalSectionLock : public Lock<CriticalSection&>
{
private:
BOOL ReleaseOperation(LONG num_release = 1,
LONG *previous_count = NULL)
{
// both parameters are ignored
LeaveCriticalSection(&sync_obj.m_CriticalSection);
return TRUE;
}
DWORD OpenOperation(DWORD wait_time)
{
EnterCriticalSection(&sync_obj.m_CriticalSection);
return TRUE;
}
public:
CriticalSectionLock(CriticalSection &criticalSection, BOOL release_on_destroy = TRUE)
: Lock<CriticalSection &>(criticalSection, release_on_destroy)
{}
~CriticalSectionLock(void)
{
if ( (release_on_destroy == TRUE) && (num_locks != 0) )
UnLock(num_locks);
}
};
#endif // __SYNC__