/*******************************************************************************
 *	BThread.cc	BThread Classes
 *			T.Barnaby,	BEAM Ltd,	31/3/00
 *******************************************************************************
 *
 * Notes
 */
#include <BThread.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>

void* BThread::startFunc(void* arg){
	BThread*	t = (BThread*)arg;
	
	t->orunning = 1;
	t->oresult = t->function();
	t->orunning = 0;
	return t->oresult;
}

BThread::BThread(){
	int			policy;
	struct sched_param	p;
	
	othread = 0;
	orunning = 0;
	oresult = 0;
	ostackSize = 0;

	policy = sched_getscheduler(0);
	if(policy >= 0)
		opolicy = policy;
	else
		opolicy = SCHED_OTHER;
		
	if(sched_getparam(0, &p) == 0)
		opriority = p.sched_priority;
	else
		opriority = 0;
}

BThread::~BThread(){
}

int BThread::start(){
	int			r;
	pthread_attr_t		a;
	struct sched_param	p;
	
	orunning = 1;
	pthread_attr_init(&a);
	if(ostackSize)
		pthread_attr_setstacksize(&a, ostackSize);
		
	pthread_attr_setschedpolicy(&a, opolicy);
	p.sched_priority = opriority;
	pthread_attr_setschedparam(&a, &p);

	if(r = pthread_create(&othread, &a, startFunc, this))
		orunning = 0;

	return r;
}

void* BThread::result(){
	return oresult;
}

int BThread::running(){
	return orunning;
}

void* BThread::function(){
	return 0;
}

int BThread::cancel(){
	return pthread_cancel(othread);
}

void* BThread::waitForCompletion(){
	pthread_join(othread, &oresult);
	return oresult;
}

int BThread::setInitStackSize(size_t stackSize){
	ostackSize = stackSize;
	return 0;
}

int BThread::setInitPriority(int policy, int priority){
	opolicy = policy;
	opriority = priority;
	return 0;
}

int BThread::setPriority(int policy, int priority){
	struct sched_param	p;
	
	p.sched_priority = priority;
	return pthread_setschedparam(othread, policy, &p);
}


pthread_t BThread::getThread(){
	return othread;
}
