/* File: thread.h Copyright 2009 Chris Tonkinson (cmtonkinson@gmail.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /** * @file thread.h * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Header file for the Thread class (and associated classes). * @note Wrapper for the POSIX thread C API */ #ifndef __H_THREAD_ #define __H_THREAD_ #include #include #define THREAD_MAX_BUFFER 1024 /** * @class ThreadException * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Basic Thread exception class. */ class ThreadException { private: /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Holds the text of the exception message. */ std::string _message; public: /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Default constructor. */ ThreadException( void ); /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Copy constructor. */ ThreadException( const ThreadException& ref ); /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Constructor which initializes the _message member from the variable argument list. * @arg format A printf() style format string. * @arg ... A printf() style variable argument list. */ ThreadException( const char* format, ... ); /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Destructor. */ ~ThreadException( void ); /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Public accessor method for _message. * @arg message The new value of _message. */ void message( const std::string& message ) { _message = message; return; } /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Public accessor method for _message. * @return The current value of _message. */ std::string message( void ) const { return _message; } }; /** * @class Mutex * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief MUTual EXclusion class to interoperate with the Thread class. */ class Mutex { private: /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief The underlying pthreads mutex object. */ pthread_mutex_t _mutex; /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief A pthreads attribute object, to modify _mutex. */ pthread_mutexattr_t _attr; /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Holds the current state of the Mutex. */ bool _locked; /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Private accessor method for _message. * @arg locked Whether or not the Mutex object is in a locked state. */ void locked( const bool& locked ) { _locked = locked; return; } public: /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Default constructor. */ Mutex( void ); /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Destructor. */ ~Mutex( void ); /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Public accessor method for _locked. * @return Whether or not the Mutex object is in a locked state. */ bool locked( void ) const { return _locked; } /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Locks the Mutex object. */ void lock( void ); /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Unlocks the Mutex object. */ void unlock( void ); }; /** * @class WRMutex * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief MUTual EXclusion class for read/write locks to interoperate with the Thread class. */ class RWMutex { private: /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief The underlying pthreads mutex object. */ pthread_rwlock_t _mutex; /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief A pthreads rw lock attribute object, to modify _mutex. */ pthread_rwlockattr_t _attr; /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Holds the current state of the Mutex. */ bool _locked; /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Private accessor method for _message. * @arg locked Whether or not the Mutex object is in a locked state. */ void locked( const bool& locked ) { _locked = locked; return; } public: /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Default constructor. */ RWMutex( void ); /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Destructor. */ ~RWMutex( void ); /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Public accessor method for _locked. * @return Whether or not the Mutex object is in a locked state. */ bool locked( void ) const { return _locked; } /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Acquires a read lock on the object. */ void readLock( void ); /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Acquires a write lock on the object. */ void writeLock( void ); /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Unlocks the Mutex object. */ void unlock( void ); }; /** * @class Thread * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Main class used to abstract the pthreads C API. */ class Thread { private: /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Unsigned integer unique to a given thread. */ pthread_t _ID; /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief A pointer to store an arbitrary argument passed into the Thread. */ void* _argument; /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief A pointer to store an arbitrary return value of the Thread. */ void* _returnValue; /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Status of the Thread. */ bool _active; /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Completion status of the Thread. */ bool _complete; /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Generic initialization method (called by all Constructors). */ void init( void ); /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Method responsible for actually splitting a new pthread. */ void start( void* (*thread_start)(void* ptr), void* arg_ptr ); public: /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Default constructor. */ Thread( void ); /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Constructor which splits a new thread automatically. */ Thread( void* (*thread_start)(void* ptr), void* arg_ptr = NULL ); /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Destructor. */ ~Thread( void ); /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Public accessor method for _ID. * @arg ID The new value of _ID. */ void ID( const pthread_t& ID ) { _ID = ID; return; } /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Public accessor method for _ID. * @return The ID (unique integer) of the underlying pthread. */ pthread_t ID( void ) const { return _ID; } /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Public accessor method for _argument. * @arg argument An arbitrary pointer (to be accessible inside a new thread). */ void argument( void* const argument ) { _argument = argument; return; } /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Public accessor method for _argument. * @return A pointer to the Threads argument. */ void* argument( void ) const { return _argument; } /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Public accessor method for _returnValue. * @arg returnValue An arbitrary pointer (to be accessible after thread completion). */ void returnValue( void* returnValue ) { _returnValue = returnValue; return; } /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Public accessor method for _returnValue. * @return A pointer to the Threads return value. */ void* returnValue( void ) const { return _returnValue; } /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Public accessor method for _active * @arg active The current state of the Thread. */ void active( const bool& active ) { _active = active; return; } /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Public accessor method for _active * @return Whether or not the given Thread is currently executing. */ bool active( void ) const { return _active; } /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Public accessor method for _complete. * @arg complete Whether or not the Thread is finsihed executing. */ void complete( const bool& complete ) { _complete = complete; return; } /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Public accessor method for _complete. * @return Whether the Thread is finished executing. */ bool complete( void ) const { return _complete; } /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Splits a new thread of execution using pthread_create(). * @return True if thread was successfully created, false upon failure. */ bool create( void* (*thread_start)(void* ptr), void* arg_ptr = NULL ); /** * @author Chris Tonkinson (cmtonkinson@gmail.com) * @date April 2009 * @brief Blocks calling thread until the underlying thread is ready to be pthread_join()'d. * @return True if thread was successfully joined, false upon failure. */ bool join( void ); }; #endif // End of inclusion guard