Unit Testing Refcounted Critical Section Class
Posted
by BillyONeal
on Stack Overflow
See other posts from Stack Overflow
or by BillyONeal
Published on 2010-03-11T05:18:21Z
Indexed on
2010/03/11
5:23 UTC
Read the original article
Hit count: 423
Hello all :)
I'm looking at a simple class I have to manage critical sections and locks, and I'd like to cover this with test cases. Does this make sense, and how would one go about doing it? It's difficult because the only way to verify the class works is to setup very complicated threading scenarios, and even then there's not a good way to test for a leak of a Critical Section in Win32. Is there a more direct way to make sure it's working correctly?
Here's the code:
CriticalSection.hpp:
#pragma once
#include <windows.h>
namespace WindowsAPI { namespace Threading {
class CriticalSection;
class CriticalLock
{
std::size_t *instanceCount;
CRITICAL_SECTION * criticalStructure;
bool lockValid;
friend class CriticalSection;
CriticalLock(std::size_t *, CRITICAL_SECTION *, bool);
public:
bool IsValid() { return lockValid; };
void Unlock();
~CriticalLock() { Unlock(); };
};
class CriticalSection
{
std::size_t *instanceCount;
CRITICAL_SECTION * criticalStructure;
public:
CriticalSection();
CriticalSection(const CriticalSection&);
CriticalSection& operator=(const CriticalSection&);
CriticalSection& swap(CriticalSection&);
~CriticalSection();
CriticalLock Enter();
CriticalLock TryEnter();
};
}}
CriticalSection.cpp:
#include "CriticalSection.hpp"
namespace WindowsAPI { namespace Threading {
CriticalSection::CriticalSection()
{
criticalStructure = new CRITICAL_SECTION;
instanceCount = new std::size_t;
*instanceCount = 1;
InitializeCriticalSection(criticalStructure);
}
CriticalSection::CriticalSection(const CriticalSection& other)
{
criticalStructure = other.criticalStructure;
instanceCount = other.instanceCount;
instanceCount++;
}
CriticalSection& CriticalSection::operator=(const CriticalSection& other)
{
CriticalSection copyOfOther(other);
swap(copyOfOther);
return *this;
}
CriticalSection& CriticalSection::swap(CriticalSection& other)
{
std::swap(other.instanceCount, instanceCount);
std::swap(other.criticalStructure, other.criticalStructure);
return *this;
}
CriticalSection::~CriticalSection()
{
if (!--(*instanceCount))
{
DeleteCriticalSection(criticalStructure);
delete criticalStructure;
delete instanceCount;
}
}
CriticalLock CriticalSection::Enter()
{
EnterCriticalSection(criticalStructure);
(*instanceCount)++;
return CriticalLock(instanceCount, criticalStructure, true);
}
CriticalLock CriticalSection::TryEnter()
{
bool lockAquired;
if (TryEnterCriticalSection(criticalStructure))
{
(*instanceCount)++;
lockAquired = true;
}
else
lockAquired = false;
return CriticalLock(instanceCount, criticalStructure, lockAquired);
}
void CriticalLock::Unlock()
{
if (!lockValid)
return;
LeaveCriticalSection(criticalStructure);
lockValid = false;
if (!--(*instanceCount))
{
DeleteCriticalSection(criticalStructure);
delete criticalStructure;
delete instanceCount;
}
}
}}
© Stack Overflow or respective owner