155 lines
4 KiB
C
155 lines
4 KiB
C
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 2000.
|
||
|
//
|
||
|
// File: U H S Y N C . H
|
||
|
//
|
||
|
// Contents: Synchronization classes
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
// Author: mbend 17 Aug 2000
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#pragma once
|
||
|
#include "ncbase.h"
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Class: CUCriticalSection
|
||
|
//
|
||
|
// Purpose: Wrapper for Win32 critical sections
|
||
|
//
|
||
|
// Author: mbend 17 Aug 2000
|
||
|
//
|
||
|
// Notes:
|
||
|
// The most important and lightweight Windows NT synchronization primitive.
|
||
|
// Allows only one thread to enter itself at a single time.
|
||
|
// An important property of critical sections is that they are
|
||
|
// thread reentrant which means that if a thread owns a critical
|
||
|
// section and tries to enter it again, the thread is allowed to
|
||
|
// do so. When exiting the lock, the lock is not freed until it is
|
||
|
// exited once for each time that it was entered.
|
||
|
//
|
||
|
// Critical sections are lightweight because they are not kernel
|
||
|
// objects. Instead they are implemented through a simple in
|
||
|
// memory structure CRITICAL_SECTION. If there is no thread
|
||
|
// contention, they are implemented by simple memory operations
|
||
|
// and spin locks that are hundreds of times faster than
|
||
|
// alternative kernel object solutions such as mutexes. However,
|
||
|
// if there is thread contention, critical sections degraded into
|
||
|
// kernel objects.
|
||
|
//
|
||
|
class CUCriticalSection
|
||
|
{
|
||
|
public:
|
||
|
CUCriticalSection()
|
||
|
{
|
||
|
InitializeCriticalSection(&m_critsec);
|
||
|
}
|
||
|
~CUCriticalSection()
|
||
|
{
|
||
|
DeleteCriticalSection(&m_critsec);
|
||
|
}
|
||
|
void Enter()
|
||
|
{
|
||
|
EnterCriticalSection(&m_critsec);
|
||
|
}
|
||
|
BOOL FTryEnter()
|
||
|
{
|
||
|
return TryEnterCriticalSection(&m_critsec);
|
||
|
}
|
||
|
void Leave()
|
||
|
{
|
||
|
LeaveCriticalSection(&m_critsec);
|
||
|
}
|
||
|
DWORD DwSetSpinCount(DWORD dwSpinCount)
|
||
|
{
|
||
|
return SetCriticalSectionSpinCount(&m_critsec, dwSpinCount);
|
||
|
}
|
||
|
private:
|
||
|
CUCriticalSection(const CUCriticalSection &);
|
||
|
CUCriticalSection & operator=(const CUCriticalSection &);
|
||
|
CRITICAL_SECTION m_critsec;
|
||
|
};
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Class: CLock
|
||
|
//
|
||
|
// Purpose: Used to place an auto lock on a critical section
|
||
|
//
|
||
|
// Author: mbend 17 Aug 2000
|
||
|
//
|
||
|
// Notes:
|
||
|
// Typically this class is used in an class object methods like so:
|
||
|
//
|
||
|
// class SynchronizedExample {
|
||
|
// public:
|
||
|
// void LockedMethod() {
|
||
|
// CLock lock(m_critSec);
|
||
|
// ...
|
||
|
// }
|
||
|
// private:
|
||
|
// CUCriticalSection m_critSec;
|
||
|
// };
|
||
|
class CLock {
|
||
|
public:
|
||
|
// Not attached
|
||
|
CLock(CUCriticalSection & critsec) : m_critsec(critsec)
|
||
|
{
|
||
|
m_critsec.Enter();
|
||
|
}
|
||
|
~CLock()
|
||
|
{
|
||
|
m_critsec.Leave();
|
||
|
}
|
||
|
private:
|
||
|
CLock(const CLock &);
|
||
|
CLock & operator=(const CLock &);
|
||
|
CUCriticalSection & m_critsec;
|
||
|
};
|
||
|
|
||
|
#ifdef __ATLCOM_H__
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Class: CALock
|
||
|
//
|
||
|
// Purpose: Used to place an auto lock on a CComObjectRootEx<CComMultiThreadModel> derived class
|
||
|
//
|
||
|
// Author: mbend 17 Aug 2000
|
||
|
//
|
||
|
// Notes:
|
||
|
// Typically this class is used in an class object methods like so:
|
||
|
//
|
||
|
// class SynchronizedExample : public CComObjectRootEx<CComMultiThreadModel> {
|
||
|
// public:
|
||
|
// void LockedMethod() {
|
||
|
// CALock lock(*this);
|
||
|
// ...
|
||
|
// }
|
||
|
// };
|
||
|
class CALock {
|
||
|
public:
|
||
|
// Not attached
|
||
|
CALock(CComObjectRootEx<CComMultiThreadModel> & object) : m_object(object)
|
||
|
{
|
||
|
m_object.Lock();
|
||
|
}
|
||
|
~CALock()
|
||
|
{
|
||
|
m_object.Unlock();
|
||
|
}
|
||
|
private:
|
||
|
CALock(const CLock &);
|
||
|
CALock & operator=(const CLock &);
|
||
|
CComObjectRootEx<CComMultiThreadModel> & m_object;
|
||
|
};
|
||
|
|
||
|
#endif // __ATLCOM_H__
|
||
|
|
||
|
|