/*******************************************************************************
 *	BMutex.cc	BMutex Classes
 *			T.Barnaby,	BEAM Ltd,	1/11/02
 *******************************************************************************
 */
#include <BMutex.h>

#define	MDEBUG	0

BMutex::BMutex(Type type){
	pthread_mutexattr_t	a;

	pthread_mutexattr_init(&a);

	if(type == Recursive){
		pthread_mutexattr_settype(&a, PTHREAD_MUTEX_RECURSIVE);
		pthread_mutex_init(&omutex, &a);
	}
	else {
		pthread_mutex_init(&omutex, 0);
	}
}

BMutex::BMutex(const BMutex& mutex){
	pthread_mutex_init(&omutex, 0);
}

BMutex& BMutex::operator=(const BMutex& mutex){
	return *this;
}

BMutex::~BMutex(){
	pthread_mutex_destroy(&omutex);
}

#if MDEBUG

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/unistd.h>
#include <errno.h>

static pid_t gettid(){
	return syscall(__NR_gettid);
}

int BMutex::lock(){
	int	e;
	
	printf("BMutex::lock: %p Thread: %u\n", this, gettid()); 
	e = pthread_mutex_lock(&omutex);
	printf("BMutex::lock: %p: Thread: %u: Acquired\n", this, gettid()); 

	return e;
}

int BMutex::timedLock(int timeoutUs){
	int		e;
	struct timespec	t;
	 
	t.tv_sec = timeoutUs / 1000000;
	t.tv_nsec = (timeoutUs % 1000000) * 1000;

	printf("BMutex::timedLock: %p Thread: %u\n", this, gettid()); 
	e = pthread_mutex_timedlock(&omutex, &t);
	printf("BMutex::timedLock: %p: Thread: %u: Acquired\n", this, gettid()); 

	return e;
}

int BMutex::unlock(){
	printf("BMutex::unlock: %p Thread: %u\n", this, gettid()); 
	return pthread_mutex_unlock(&omutex);
}

int BMutex::tryLock(){
	return pthread_mutex_trylock(&omutex);
}

#else

int BMutex::lock(){
	return pthread_mutex_lock(&omutex);
}

int BMutex::timedLock(int timeoutUs){
	 struct timespec	t;
	 
	 t.tv_sec = timeoutUs / 1000000;
	 t.tv_nsec = (timeoutUs % 1000000) * 1000;

	 return pthread_mutex_timedlock(&omutex, &t);
}

int BMutex::unlock(){
	return pthread_mutex_unlock(&omutex);
}

int BMutex::tryLock(){
	return pthread_mutex_trylock(&omutex);
}

#endif
