
Welcome to CCriticalSeciontEx, CThreadSafe and
CThreadSafeScalar, a collection of C++
wrapper class to provide thread safe access to objects. The classes are based on the code presented in Chapter Ten
of the book
"Programming Applications for Microsoft Windows" by Jeffrey Richter.
Features
- Simple and clean C++ interface.
- The code is Unicode enabled
and build configurations are provided.
- The classes integrate closely with MFC. i.e. instead of the CResGuard class we use
a derivative of the MFC class CCriticalSection.
- The classes provide a Critical section wrapper with timeouts and spin
counts. The class also handles the case where this functionality does not
exist i.e the presence of the functions
"InitializeCriticalSectionAndSpinCount", "SetCriticalSectionSpinCount" and "TryEnterCriticalSection" in Kernel32.dll.
- The CThreadSafe class (which corresponds to the Richter class CInterlockedType) uses inheritance rather
than encapsulation to implement locking. This allows an instance of a class to be treated just like a
critical section, for example:
CThreadSafe<CMyClass> variable;
CSingleLock sl(&variable, TRUE);
or
CThreadSafe<CMyClass> variable;
variable.Lock();
.
.
variable.Unlock();
- The CThreadSafe class correctly implements the arithmetic operators. e.g. the following code works
correctly:
CThreadSafe<int> variable(4);
(variable++)++;
ASSERT(variable == 6); //Richter code would have "variable" equal to 5 here
The reason why the Richter would code fail was because it did not return a reference to the correct
object for all of the arithmetic operators.
The enclosed
zip file contains the source code and a
simple test program to exercise all of the classes.
Copyright
- You are allowed to include the source code in
any product (commercial, shareware, freeware or otherwise) when your product
is released in binary form.
- You are allowed to modify the source code in
any way you want except you cannot modify the copyright details at the top
of each module.
- If you want to distribute source code with
your application, then you are only allowed to distribute versions released
by the author. This is to maintain a single distribution point for the
source code.
Updates
V1.0 (4 December 2002)
V1.01 (22 December 2006)
- Updated copyright details
- Optimized CThreadSafe constructor code
- Code now uses newer C++ style casts instead of C style casts.
- Updated the code to clean compile on VC 2005
- Made CCriticalSectionEx::Lock and Unlock non virtual
- Optimized _CRITICAL_SECTION_DATA constructor code
- CCriticalSectionEx constructors now throws an exception using
AfxThrowMemoryException instead of AfxThrowResourceException
- Removed unnecessary CThreadSafe destructor
- Removed unnecessary CThreadSafeScalar destructor
- Added postfix operator support to CThreadSafeScalar
- Addition of a operator TYPE*() in CThreadSafe
- m_Value member variable of CThreadSafe is now public
- Addition of a CCRITICALSECTIONEX_EXT_CLASS preprocessor macro to allow
the classes to be more easily added to an extension dll
V1.02 (11 January 2009)
- Updated copyright details
- Removed VC 6 style AppWizard comments from the code
- The code has now been updated to support VC 2005 or later only. It seems
that even though ATL's version of CCriticalSection now supports spin locks
the MFC version of CCriticalSection still does not support them, hence still
the need for CCriticalSectionEx.
- Fixed a bug in CCriticalSectionEx::Lock where it handled the wrong SEH
type being thrown. The code now only handles the STATUS_NO_MEMORY exception
- Code now compiles cleanly using Code Analysis (/analyze)
- Removed the bPreallocateEvent parameter from the
CCriticalSectionEx::Init and CCriticalSectionEx's overridden constructor.
- Removed the call to Unlock in the CCriticalSectionEx destructor. This is
to be consistent with MFC's CCriticalSection class.
- CCriticalSectionEx::Lock now throws a CMemoryException* exception. This
is to be consistent with MFC's CCriticalSection class.
- The m_bLocked member variable of CCriticalSectionEx is now a bool
instead of a BOOL. The IsLocked method has also been updated to return a
bool.