/*
#########################################################################
#
# This file is part of trustyRC.
#
# trustyRC, fully modular IRC robot
# Copyright (C) 2006-2008 Nicoleau Fabien
#
# trustyRC 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 3 of the License, or
# (at your option) any later version.
#
# trustyRC 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 trustyRC. If not, see .
#
#########################################################################
*/
/** @file pthread.cpp
* @brief PThread implementation file
*/
#include "pthread.h"
#include
using namespace std;
/**
* The class constructor. Initialize private attributes
* @post An object is contructed
*/
PThread::PThread() {
this->finished = false;
this->running = false;
this->handle = new pthread_t;
}
/**
* The class destructor
*/
PThread::~PThread() {
this->terminate();
pthread_join (*this->handle, NULL);
delete this->handle;
}
/**
* Prepare and launch a thread.
* Stores a function to execute, and arguments,
* then create a thread, and launch the threadStartup
* @param myThreadProcess Function to execute
* @param args Arguments to send to the threaded function
* @return true if the thread has been launched, else false
*/
bool PThread::exec(threadProcess myThreadProcess,void*args) {
if ( ! this->isRunning() ) {
threadParams tp;
tp.process = myThreadProcess;
tp.args = args;
tp.running = &this->running;
tp.finished = &this->finished;
if (pthread_create (this->handle, NULL,PThread::threadStartup,(void*)&tp) < 0) {
return false;
}
return true;
}
return false;
}
/**
* Threaded function. In this function, the thread is prepared,
* then the function to execute is launched.
* @post running and finished flags are updated
* @param targs thread arguments
*/
void* PThread::threadStartup(void*targs) {
threadParams* tp = (threadParams*)targs;
bool* running = tp->running;
bool* finished = tp->finished;
threadProcess process = tp->process;
void * args = tp->args;
*running = true;
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
process(args);
*running = false;
*finished = true;
pthread_exit(0);
}
/**
* Cancel the thread
* @return true if the thread has been canceled, else false
*/
bool PThread::terminate() {
if ( this->isRunning() ) {
if (pthread_cancel (*this->handle) != 0) {
return false;
}
this->running = false;
return true;
}
return false;
}
/**
* Give running state
* @return True if the thread is running, else false
*/
bool PThread::isRunning() {
return this->running;
}
/**
* Tell if the thread is finished.
* The thread is concidered has finished if the exectuion has finished itself
* (not canceled)
* @return True if the thread is finished, else false
*/
bool PThread::isFinished() {
return this->finished;
}
/**
* Wait for thread end, and then free memory
*/
void* PThread::join() {
void* ret;
pthread_join(*this->handle,&ret);
return ret;
}
/**
* Return pthread handle.
* Use this handle to use pthread functions
* not provided by this class
* @return Handle's pointer
*/
pthread_t* PThread::getHandle() {
return this->handle;
}