windows-nt/Source/XPSP1/NT/net/upnp/inc/upsync.h
2020-09-26 16:20:57 +08:00

155 lines
4 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 2000.
//
// File: U P 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__