#ifndef __CRITICALHPP__
#define __CRITICALHPP__

#include <windows.h>
#include <assert.h>

// macro to help with using the SMART_CRITICAL class
// you can just say CRITICAL_CONTROL(ThreadSafe), this will
// place the current scope in a critical section
#define CRITICAL_CONTROL(x) SMART_CRITICAL crit##x (x)
#define CRITICAL_CONTROL_2(x,y) SMART_CRITICAL crit##x (y)

// class to handle controling critical sections
// you would use this class to create thread safe and exception safe code
// since the LeaveCriticalSection is in the destructor it will automatically 
// be called when the class goes out of scope, for instance when the stack
// is unwinding from an exception
class SMART_CRITICAL {
private:
	CRITICAL_SECTION *m_Crit;
public:
	SMART_CRITICAL (CRITICAL_SECTION& crit)
	{
		m_Crit = &crit;
		EnterCriticalSection (m_Crit);
	}
	~SMART_CRITICAL (void)
	{
		LeaveCriticalSection (m_Crit);
	}
};

// class to handle global critical sections
// the constructor will automatically init the critical section and
// the destructor will automatically delete the critical section.
// This makes it useful for globals for instance, the class will automatically
// create and destroy the critical section for you.
// Note: for various reason I made it bad to create this class dynamically
class ROOT_CRITICAL : public CRITICAL_SECTION {
public:
	ROOT_CRITICAL (void)
	{
		InitializeCriticalSection (this);
	}
  ROOT_CRITICAL( const ROOT_CRITICAL&) 
	{ 
		InitializeCriticalSection( this ); 
	}
	~ROOT_CRITICAL (void)
	{
		DeleteCriticalSection (this);
	}
    void Lock(void) 
	{ 
		EnterCriticalSection(this); 
	}
    void Unlock(void) 
	{ 
		LeaveCriticalSection(this); 
	}
    void *operator new (size_t)
	{
		assert (false);
		return NULL;
	}
};
#endif