class Lock
{
HANDLE GetMutex()
{
static HANDLE hMutex = ::CreateMutex( NULL, FALSE, NULL );
return hMutex;
}
public:
Lock()
{
::WaitForSingleObject( GetMutex(), INFINITE );
}
~Lock()
{
::ReleaseMutex( GetMutex() );
}
};
// Handle the first time the assertion fails
#define assert_once_out_first( x ) \
std::cout << __FILE__ << "(" << __LINE__ << "): first assertion for expression '" << #x << "'" << std::endl;
// Handle further assertion fails
#define assert_once_out_next( x ) \
std::cout << __FILE__ << "(" << __LINE__ << "): known assertion for expression '" << #x << "'" << std::endl;
// Generates a file-wide unique variable name
#define assert_once_var __bAsserted__ ## __LINE__ ## __
// The unique assert macro
#define assert_once( x ) \
do { \
Lock _lock; \
static bool assert_once_v = false; \
if ( !(x) ) \
{ \
if ( !assert_once_v ) \
{ \
assert_once_v = true; \
assert_once_out_first( x ); \
} \
else \
{ \
assert_once_out_next( x ); \
} \
} \
} while ( 0 )
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (2)
Commented:
Author
Commented:I will think about how to do it best. In fact the implementation I implemented for use in my company is thread-safe.