/************************************************************************
 * AUTHOR: NiuJiuRu
 * FILENAME: swmutex.c
 * DESCRIPTION: 互斥量, 也称独占锁
 * NOTE: 主要用于多线程同步访问全局共享资源
 * HISTORY:
 * 1, [2010-12-17] created by NiuJiuRu
 ***********************************************************************/
#include "swapi.h"
#include "swmem.h"
#include "swmutex.h"

/* 创建互斥量 */
void *sw_mutex_create()
{
	pthread_mutex_t *mt = NULL;
	pthread_mutexattr_t attr;
	
	mt = (pthread_mutex_t *)sw_heap_malloc(sizeof(pthread_mutex_t));
	if(mt)
	{
		memset(mt, 0, sizeof(pthread_mutex_t));
		pthread_mutexattr_init(&attr);
		if(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP) == 0) pthread_mutex_init(mt, &attr); // 检错锁
		else{ sw_heap_free(mt); mt = NULL; }
		pthread_mutexattr_destroy(&attr);
	}
	
	return mt;	
}

/* 销毁互斥量 */
void sw_mutex_destroy(void *hMutex)
{
	pthread_mutex_t *mt = (pthread_mutex_t *)hMutex;
	pthread_mutex_destroy(mt);
	sw_heap_free(mt);
}

/* 互斥量上锁(超时设置的时间单位为: 毫秒, 并且当timeout = -1时表示无限等待) */
int sw_mutex_lock(void *hMutex, int timeout)
{
	pthread_mutex_t *mt = (pthread_mutex_t *)hMutex;
	struct timespec ts = { 0 };
	
	if(timeout < 0)
	{
		return pthread_mutex_lock(mt);
	}
	else
	{
		ts.tv_sec = time(NULL) + timeout/1000;
		ts.tv_nsec = (timeout%1000)*1000;
		if(pthread_mutex_timedlock(mt, &ts) != 0) return -1;
	}
	
	return 0;
}

/* 互斥量解锁 */
void sw_mutex_unlock(void *hMutex)
{
	pthread_mutex_t *mt = (pthread_mutex_t *)hMutex;
	if(mt) pthread_mutex_unlock(mt);
}
