//+--------------------------------------------------------------------------- // // 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 derived class // // Author: mbend 17 Aug 2000 // // Notes: // Typically this class is used in an class object methods like so: // // class SynchronizedExample : public CComObjectRootEx { // public: // void LockedMethod() { // CALock lock(*this); // ... // } // }; class CALock { public: // Not attached CALock(CComObjectRootEx & object) : m_object(object) { m_object.Lock(); } ~CALock() { m_object.Unlock(); } private: CALock(const CLock &); CALock & operator=(const CLock &); CComObjectRootEx & m_object; }; #endif // __ATLCOM_H__