#ifdef _WIN32
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_NONSTDC_NO_WARNINGS
#include <windows.h>
#include <io.h>
#include "../Win32/w32def.h"
#endif	//	_WIN32

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#ifdef __linux__
#include <sys/file.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <linux/limits.h>
#include <sys/shm.h>
#endif	//	__linux__
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "defines.h"
#include "mutex.h"

/////////////////////////////////////////////////////////////////////////////

#define _IS_VALID_SHMID(id)				((id) >= 0)

/////////////////////////////////////////////////////////////////////////////

CLocalMutex::CLocalMutex(void) : m_bInit(false)
{
	memset(&m_mutex, 0, sizeof(m_mutex));
	memset(&m_mutexAttr, 0, sizeof(m_mutexAttr));
	::pthread_mutexattr_init(&m_mutexAttr);
	::pthread_mutexattr_settype(&m_mutexAttr, PTHREAD_MUTEX_RECURSIVE);
}

CLocalMutex::~CLocalMutex(void)
{
	Release();
	::pthread_mutexattr_destroy(&m_mutexAttr);
}

bool CLocalMutex::Create(bool bRecursive)
{
	if(!m_bInit)
	{
		if(!::pthread_mutex_init(&m_mutex, bRecursive ? &m_mutexAttr : NULL))
		{
			TRACE("CLocalMutex::Create: Created Mutex (recursive=%s)\n", bRecursive ? "true" : "false");
			m_bInit = true;
		}
		else
		{
			TRACE("CLocalMutex::Create failed!\n");
		}
	}
	
	return m_bInit;
}

void CLocalMutex::Release(void)
{
	if(m_bInit)
	{
		::pthread_mutex_destroy(&m_mutex);
		m_bInit = false;
		TRACE("CLocalMutex::Release: Mutex released.\n");
	}
}

bool CLocalMutex::Lock(void)
{
	return !::pthread_mutex_lock(&m_mutex);
}

bool CLocalMutex::TryLock(void)
{
	return !::pthread_mutex_trylock(&m_mutex);
}

bool CLocalMutex::Unlock(void)
{
	return !::pthread_mutex_unlock(&m_mutex);
}
