jthread.cpp 4.66 KB
/***************************************************************************
 *   Copyright (C) 2005 by Jeff Ferr                                       *
 *   root@sat                                                              *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "jthread.h"
#include "jthreadexception.h"

#include <errno.h>

namespace jthread {

Thread::Thread()
{
	_is_running = false;
}

Thread::~Thread()
{
	// Interrupt();
}

/** Private */

void * Thread::ThreadMain(void *owner_)
{
	if (owner_ == NULL) {
		return NULL;
	}
	
	Thread *owner = (Thread *)(owner_);
     
	if (owner->SetUp() == 0) {
		owner->_is_running = true;
		owner->Run();
		owner->_is_running = false;
		owner->CleanUp();
	}

	owner->SignalThreadDead();

	// pthread_exit(NULL);
	
	return NULL;
}

void Thread::SignalThreadDead()
{
	// _condition.Notify();
}

/** End */
    
/** Protected */

int Thread::SetUp()
{
	return 0;
}

void Thread::Run() 
{
	return;
}

int Thread::CleanUp()
{
	return 0;
}

/** End */

void Thread::Start() throw(ThreadException)
{
	/**
	 * Permitir criar varias instancias na chamada de Start()
	 */
	
	if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == EINVAL) {
		throw ThreadException("Interrupt is not allowed !");
	}

	if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == EINVAL) {
		throw ThreadException("Thread is not asynchronous !");
	}
	
	if (pthread_create(&_thread, NULL, &(Thread::ThreadMain), this)) {
		throw ThreadException("Unable to create a process to suport the ... !");
	}

	pthread_detach(_thread);
}

void Thread::Interrupt() throw(ThreadException)
{
	if (_is_running == true) {
		_is_running = false;
		
		SignalThreadDead();
		
		if (pthread_cancel(_thread) == ESRCH) {
			// throw ThreadException("Thread cancel exception !");
		}
	}
}

void Thread::Suspend() 
{

}

void Thread::Resume()
{

}

bool Thread::IsStarted()
{
	return _is_running;
}

void Thread::SetPolicy(thread_policy_t policy, thread_priority_t priority) throw(ThreadException)
{
	struct sched_param param;

	param.__sched_priority = priority;

	int result;
	
	result = pthread_setschedparam(_thread, policy, &param);

	if (result == EINVAL) {
		throw ThreadException("Policy is not defined !");
	} else if (result == EPERM) {
		throw ThreadException("The process does not have superuser permission !");
	} else if (result == ESRCH) {
		throw ThreadException("This thread has already terminated !");
	} else if (result < 0) {
		throw ThreadException("Unknown exception in set policy !");
	}
}

void Thread::GetPolicy(thread_policy_t *policy, thread_priority_t *priority) throw(ThreadException)
{
	struct sched_param param;

	int policy_int, result;
	
	result = pthread_getschedparam(_thread, &policy_int, &param);

	if (result == ESRCH) {
		throw ThreadException("This thread has already terminated !");
	} else if (result < 0) {
		throw ThreadException("Unknown exception in set policy !");
	}

	switch (param.__sched_priority) {
		case 0:
			(*priority) = LOW_PRIORITY;
			break;
		case 1:
		case 2:
		case 3:
		case 4:
		case 5:
			(*priority) = NORMAL_PRIORITY;
			break;
		case 6:
		case 7:
		case 8:
		case 9:
		case 10:
			(*priority) = HIGH_PRIORITY;
			break;
		default:
			(*priority) = NORMAL_PRIORITY;
			break;
	}

	switch (policy_int) {
		case SCHED_OTHER:
			(*policy) = POLICY_OTHER;
			break;
		case SCHED_FIFO:
			(*policy) = POLICY_FIFO;
			break;
		case SCHED_RR:
			(*policy) = POLICY_ROUND_ROBIN;
			break;
	}

}

void Thread::WaitThread()
{
	/*
	while (_is_running == true) {
		_condition.Wait();
	}
	*/
	sleep(1);
}

};