Click here to Skip to main content
15,893,790 members
Articles / Mobile Apps / Windows Mobile

Code that debugs itself

Rate me:
Please Sign up or sign in to vote.
4.78/5 (74 votes)
17 Feb 200534 min read 312.5K   5K   184  
A set of macros for detecting and reporting critical errors, combined with a technique of writing solid code.
/////////////////////////////////////////////////////////////////////////////////
//
//  Set of simple synchronization classes
//
//  Copyright (c) 2003-2004
//  Andrew Schetinin
//
//  This software is provided "as is" without express or implied warranty, 
//  and with no claim as to its suitability for any purpose.
//
//  Permission to use or copy this software for any purpose is hereby granted 
//  without fee, provided the above notices are retained on all copies.
//  Permission to modify the code and to distribute modified code is granted,
//  provided the above notices are retained, and a notice that the code was
//  modified is included with the above copyright notice.
//
//  This software accompanies the article "Code that debugs itself"
//  located at http://www.codeproject.com/debug/qafdebug.asp
//
//  You are welcomed to report bugs, send comments and post code modifications 
//  to aschetinin@hotmail.com 
//
/////////////////////////////////////////////////////////////////////////////////

///
/// @file	CSyncCS.h "../Include/CSyncCS.h"
/// @brief	Simple synchronization classes.
///         
///	This file defines simple synchronization classes like critical 
///     sections and mutexes.

#ifndef _QAFCSYNC_H_
#define _QAFCSYNC_H_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <wtypes.h>

#include "QAFDebug.h"

//
// Using of BEGIN_SYNC and END_SYNC:
//
// // Define it somewhere in your header file
// CAutoCS	m_cs; // critical section object
//
// // And synchronize your code in CPP file
// BEGIN_SYNC( m_cs );
//     .... do whatever you need ...
// END_SYNC;
//

/// Special define for organizing exception-safe synchronized blocks of code. 
/// This is the start macro, it must be enclosed with END_SYNC
#define BEGIN_SYNC( sync_obj ) do { CAutoLockCS sync( sync_obj )

/// Special define for organizing exception-safe synchronized blocks of code. 
/// This is the end macro
#define END_SYNC } while( FALSE )

/// A simple synchronization class, designed to be used as an automatic variable.
/// Once its instance is instanciated, it locks its visibility scope. 
class CSyncCS
{
public:
	
	/// Flag that the critical section object must be constructed or destroyed
	enum CSOP { CS_NOP = 0, CS_CREATE = 1, CS_DESTROY = 2 };
	
	/// Constructor creates and enters the critical section
	CSyncCS( CRITICAL_SECTION * pcs, const CSOP csop = CS_NOP )
	{
		m_pcs = pcs;
		m_csop = csop;
		if( CS_CREATE == m_csop )
			InitializeCriticalSection( m_pcs ); 
		EnterCriticalSection( m_pcs ); 
	}
	
	/// Destructor leaves and destroys the critical section
	~CSyncCS() 
	{
		LeaveCriticalSection( m_pcs ); 
		if( CS_DESTROY == m_csop )
			DeleteCriticalSection( m_pcs ); 
	}

private:
	
	/// Critical section is used for synchronization
	CRITICAL_SECTION * m_pcs;
	
	/// Flag that the critical section object must be constructed or destroyed
	CSOP m_csop;
	
};

/// Improved version of CSyncCS class
class CAutoCS
{
public:
	
	/// Constructor creates the critical section
	CAutoCS()
	{
		InitializeCriticalSection( &m_cs ); 
	}
	
	/// Destructor destroys the critical section
	~CAutoCS() 
	{
		DeleteCriticalSection( &m_cs ); 
	}

	/// Enter the critical section
	void Lock()
	{
		EnterCriticalSection( &m_cs ); 
	}
	
	/// Leave the critical section
	void Unlock()
	{
		LeaveCriticalSection( &m_cs ); 
	}
	
private:
	
	/// Critical section is used for synchronization
	CRITICAL_SECTION m_cs;
	
};

/// Automatic locker for different synchronization objects.
template <class SyncClass>
class CLockCS
{
public:
	
	/// Constructor locks the synchronization object
	CLockCS( SyncClass &SyncObj ) : m_SyncObj(SyncObj)
	{
		m_SyncObj.Lock(); 
	}
	
	/// Destructor unlocks the synchronization object
	~CLockCS() 
	{
		m_SyncObj.Unlock(); 
	}

private:

	/// Reference to the synchronization object
	SyncClass & m_SyncObj;

};

/// Shortcut for autolocking critical section.
typedef CLockCS<CAutoCS> CAutoLockCS;

/// Simple mutex class that is compatible to the CLockCS class.
class CMutex
{
public:
	
	/// default constructor
	CMutex() : m_hMutex(NULL), m_bOwned(false) 
	{
		m_hMutex = CreateMutex( NULL, FALSE, NULL );
		if( Q_ASSERT( NULL != m_hMutex ) )
			m_bOwned = true;
	}
	
	/// default constructor
	CMutex( LPCTSTR szMutexName ) : m_hMutex(NULL), m_bOwned(false) 
	{
		m_hMutex = CreateMutex( NULL, FALSE, szMutexName );
		if( Q_ASSERT( NULL != m_hMutex ) )
			m_bOwned = true;
	}
	
	/// copy constructor
	CMutex( HANDLE hMutex ) : m_hMutex(hMutex), m_bOwned(false) 
	{
		Q_ASSERT( NULL != m_hMutex );
	}
	
	/// copy constructor
	CMutex( const CMutex & obj ) : m_hMutex(obj.m_hMutex), m_bOwned(false) 
	{
		Q_ASSERT( NULL != m_hMutex );
	}

	/// destructor
	~CMutex() 
	{
		if( m_bOwned )
		{
			Q_ASSERT( CloseHandle( m_hMutex ) );
			m_hMutex = NULL;
		}
	}

	/// get the handle of the mutex. this handle must not be closed
	HANDLE GetHandle() const
	{
		return m_hMutex;
	}
	
	/// Enter the critical section
	bool Lock( DWORD dwMilliseconds = INFINITE )
	{
		DWORD dwRet = WaitForSingleObject( m_hMutex, dwMilliseconds );
		return Q_ASSERT( WAIT_OBJECT_0 == dwRet );
	}
	
	/// Leave the critical section
	void Unlock()
	{
		Q_ASSERT( ReleaseMutex( m_hMutex ) );
	}
	
protected:
private:

	/// Mutex handle
	HANDLE m_hMutex;

	/// Flag if this handle is owned by the object
	bool m_bOwned;

	/// assignment operator
	CMutex & operator=( const CMutex & obj ) 
	{
		if( this != &obj )
		{
			// copy the members
		}
		return *this;
	}
	
};


///////////////////////////////////////////////
// END OF FILE
///////////////////////////////////////////////
#endif

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Team Leader OpTier
Israel Israel
Programming computers since entering the university in 1992, but dreaming of programming long time before putting hands on my first computer.

Experienced in cross-platform software development using C++ and Java, as well as rapid GUI development using Delphi/C#. Strong background in networking, relational databases, Web development, and mobile platforms.

Like playing guitar, visiting historical sites (not in the Internet, in the car Smile | :) ) and cooking meat with friends (sorry about vegetarians). Look for more information on www.schetinin.com

Comments and Discussions