/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */


#ifndef	__NMUTEX__
#define __NMUTEX__


#if		__PLATFORM_POSIX__
		#include <stdlib.h>
		#include <pthread.h>
#elif	__PLATFORM_NINTENDO_WII__
		#include <revolution.h>
#endif
		#include "ntypes.h"


namespace GS {
	namespace Threading {

/// Portable mutex class.
class	Mutex
{
protected:

#if		__PLATFORM_POSIX__
		pthread_mutex_t	mutex;
#elif	__PLATFORM_WINDOWS__
		void		*mutex;
#elif	__PLATFORM_NINTENDO_WII__
		OSMutex		mutex;
#endif

public:

		void		Lock();
		bool		TryLock();
		void		Unlock();

		Mutex();
		~Mutex();
};

/// Mutex helper class.
class	MutexLock
{
protected:

		Mutex		*mutex;

public:

		bool		HasLock() const
		{	return asbool(mutex);	}

		void		Lock(Mutex *m, bool try_only)
		{
			Unlock();

			if	(try_only)
			{
				if	(m && m->TryLock())
					mutex = m;
			}
			else
			{
				if	(m)
					(mutex = m)->Lock();
			}
		}
		void		Unlock()
		{
			if	(mutex)
				mutex->Unlock();
			mutex = 0;
		}

		MutexLock(Mutex *m, bool try_only = false) : mutex(0)
		{	Lock(m, try_only);	}
		~MutexLock()
		{	Unlock();	}
};

	}	// Threading
}	// GS


#endif	// __NMUTEX__
