#include <../arch/arch.h>

#ifdef	ARCH_THREADING_SUPPORTED

vboolean V_CALL
archCreateMutex(arch_mutex_p mutex_ret)
{
#ifdef	MUST_DIE_DEAD
	InitializeCriticalSection(&mutex_ret->cs);
	mutex_ret->lock_count = 0;
#else
	mutex_ret->mutex = CreateMutex(NULL,FALSE,NULL);
#endif
	return true;
}

vboolean V_CALL
archDestroyMutex(arch_mutex_p mutex)
{
	/*
	 * First of all, release all waiting threads; it probably cause
	 * core dump, but deadlock is worse. In either case, presence of
	 * waiting threads at the time of mutexDestroy() mean broken code.
	 */
#ifdef	MUST_DIE_DEAD
	while(mutex->lock_count--)
		LeaveCriticalSection(&mutex->cs);
	DeleteCriticalSection(&mutex->cs);
#else	/* !MUST_DIE_DEAD */
	while(ReleaseMutex(mutex->mutex));
	CloseHandle(mutex->mutex);
#endif	/* !MUST_DIE_DEAD */
	return true;
}

vboolean V_CALL
archTryLockMutex(arch_mutex_p mutex)
{
#ifdef	MUST_DIE_DEAD
	if(TryEnterCriticalSection(&mutex->cs))
	{
		mutex->lock_count++;
		return true;
	}
	else
		return false;
#else	/* !MUST_DIE_DEAD */
	if(WaitForSingleObject(mutex->mutex,0) == WAIT_OBJECT_0)
		return true;
	else
		return false;
#endif	/* !MUST_DIE_DEAD */
}

vboolean V_CALL
archLockMutex(arch_mutex_p mutex)
{
#ifdef	MUST_DIE_DEAD
	EnterCriticalSection(&mutex->cs);
	mutex->lock_count++;
	return true;
#else	/* !MUST_DIE_DEAD */
	if(WaitForSingleObject(mutex->mutex,INFINITE) == WAIT_OBJECT_0)
		return true;
	else
		return false;
#endif	/* !MUST_DIE_DEAD */
}

vboolean V_CALL
archUnlockMutex(arch_mutex_p mutex)
{
#ifdef	MUST_DIE_DEAD
	if(!mutex->lock_count)
		return false;
	mutex->lock_count--;
	LeaveCriticalSection(&mutex->cs);
	return true;
#else	/* !MUST_DIE_DEAD */
	return ReleaseMutex(mutex->mutex) ? true : false;
#endif	/* !MUST_DIE_DEAD */
}

#endif	/* ARCH_THREADING_SUPPORTED */
