Merge pull request #602 from wowus/master

Cleaned up critical section code.
This commit is contained in:
Gavin Andresen 2011-11-21 11:33:14 -08:00
commit 42eb76a054
2 changed files with 34 additions and 9 deletions

View File

@ -8,6 +8,25 @@ using namespace std;
BOOST_AUTO_TEST_SUITE(util_tests) BOOST_AUTO_TEST_SUITE(util_tests)
BOOST_AUTO_TEST_CASE(util_criticalsection)
{
CCriticalSection cs;
do {
CRITICAL_BLOCK(cs)
break;
BOOST_ERROR("break was swallowed!");
} while(0);
do {
TRY_CRITICAL_BLOCK(cs)
break;
BOOST_ERROR("break was swallowed!");
} while(0);
}
BOOST_AUTO_TEST_CASE(util_MedianFilter) BOOST_AUTO_TEST_CASE(util_MedianFilter)
{ {
CMedianFilter<int> filter(5, 15); CMedianFilter<int> filter(5, 15);

View File

@ -243,19 +243,20 @@ public:
pcs = &csIn; pcs = &csIn;
pcs->Enter(pszName, pszFile, nLine); pcs->Enter(pszName, pszFile, nLine);
} }
operator bool() const
{
return true;
}
~CCriticalBlock() ~CCriticalBlock()
{ {
pcs->Leave(); pcs->Leave();
} }
}; };
// WARNING: This will catch continue and break!
// break is caught with an assertion, but there's no way to detect continue.
// I'd rather be careful than suffer the other more error prone syntax.
// The compiler will optimise away all this loop junk.
#define CRITICAL_BLOCK(cs) \ #define CRITICAL_BLOCK(cs) \
for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!" && !fcriticalblockonce)), fcriticalblockonce=false) \ if (CCriticalBlock criticalblock = CCriticalBlock(cs, #cs, __FILE__, __LINE__))
for (CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__); fcriticalblockonce; fcriticalblockonce=false)
class CTryCriticalBlock class CTryCriticalBlock
{ {
@ -267,6 +268,12 @@ public:
{ {
pcs = (csIn.TryEnter(pszName, pszFile, nLine) ? &csIn : NULL); pcs = (csIn.TryEnter(pszName, pszFile, nLine) ? &csIn : NULL);
} }
operator bool() const
{
return Entered();
}
~CTryCriticalBlock() ~CTryCriticalBlock()
{ {
if (pcs) if (pcs)
@ -274,12 +281,11 @@ public:
pcs->Leave(); pcs->Leave();
} }
} }
bool Entered() { return pcs != NULL; } bool Entered() const { return pcs != NULL; }
}; };
#define TRY_CRITICAL_BLOCK(cs) \ #define TRY_CRITICAL_BLOCK(cs) \
for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!" && !fcriticalblockonce)), fcriticalblockonce=false) \ if (CTryCriticalBlock criticalblock = CTryCriticalBlock(cs, #cs, __FILE__, __LINE__))
for (CTryCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__); fcriticalblockonce && (fcriticalblockonce = criticalblock.Entered()); fcriticalblockonce=false)