
/* ****************************************************************************

 * eID Middleware Project.
 * Copyright (C) 2008-2010 FedICT.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License version
 * 3.0 as published by the Free Software Foundation.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, see
 * http://www.gnu.org/licenses/.

**************************************************************************** */
#ifndef __MUTEX_H__
#define __MUTEX_H__


#ifdef WIN32
#include <windows.h>
#else
#include <pthread.h>
#include "threaddefines.h"
#endif

namespace eIDMW
{

	class CMutex
	{
public:
		CMutex();
		~CMutex();

		void Lock();

		void Unlock();

private:
		// No copies allowed
		CMutex(const CMutex & oMutex);
		CMutex & operator =(const CMutex & oMutex);

#ifdef WIN32
		CRITICAL_SECTION m_Mutex;
#else
		pthread_mutex_t m_Mutex;
#endif
	};

/**
 * A usefull helper class, similar to the std::auto_ptr class.
 * The constructor does a Lock() and the destructor does an Unlock();
 * so you don't need to do an explicit Unlock(), it is done when
 * the CAutoMutex object goes out of scope.
 */
	class CAutoMutex
	{
public:
		CAutoMutex(CMutex * poMutex):m_poMutex(poMutex)
		{
			m_poMutex->Lock();
		}

		     ~CAutoMutex()
		{
			m_poMutex->Unlock();
		}

private:
		CMutex * m_poMutex;
	};

//-------------------------------
// Abstract base class for mutexes
//-------------------------------

/* The following code is untested
class IMutex
{
	virtual void Lock()   = 0;
	virtual void Unlock() = 0;
};

class SystemMutex : public IMutex
{
public:
#ifdef WIN32
	SystemMutex(HANDLE& mutex, std::string const& name)
		: m_Mutex(mutex)
	{
		SECURITY_ATTRIBUTES* pAttribs = 0;
		mutex = CreateMutex( pAttribs, FALSE, name); 
	}
	virtual ~SystemMutex()
	{
		CloseHandle(m_Mutex);
	}
	virtual void Lock()
	{
		WaitForSingleObject(m_Mutex, INFINITE));
	}
	virtual void Unlock()
	{
		ReleaseMutex(m_Mutex); 
	}
private:
	CRITICAL_SECTION& m_Mutex;

#else
	SystemMutex(pthread_mutex_t* pMutex)
		: m_Mutex(pMutex)
	{
		pthread_mutex_init(m_pMutex, NULL));
	}
	virtual ~SystemMutex()
	{
		pthread_mutex_destroy(m_pMutex);
	}
	virtual void Lock()
	{
		pthread_mutex_lock(m_pMutex);
	}
	virtual void Unlock()
	{
		pthread_mutex_unlock(m_pMutex) 
	}
private:
	pthread_mutex_t* m_pMutex;
	pthread_t		 m_MutexOwner;
	int				 m_MutexLockcount;
#endif

private:
	// No copies allowed
	SystemMutex(const SystemMutex & oMutex);
	SystemMutex & operator = (const SystemMutex & oMutex);

};
*/
}
#endif
