X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=simgear%2Fthreads%2FSGThread.hxx;h=7f3a651a800b195b493c86d676f68a11a1ab7f1b;hb=5f804cb0eb126ab7162855dad14d20eb381309c6;hp=9440a356ce5054f3a450cfc8b6f603704791710d;hpb=0b316a8c5ee9c36f183c2ad0ef6686e2ed5f47c1;p=simgear.git diff --git a/simgear/threads/SGThread.hxx b/simgear/threads/SGThread.hxx index 9440a356..7f3a651a 100644 --- a/simgear/threads/SGThread.hxx +++ b/simgear/threads/SGThread.hxx @@ -3,6 +3,7 @@ // Written by Bernie Bright, started April 2001. // // Copyright (C) 2001 Bernard Bright - bbright@bigpond.net.au +// Copyright (C) 2011 Mathias Froehlich // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -16,255 +17,166 @@ // // 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // -// $Id$ #ifndef SGTHREAD_HXX_INCLUDED #define SGTHREAD_HXX_INCLUDED 1 -#include -#include -#include - -class SGThread; - -extern "C" { - void* start_handler( void* ); -}; +#include /** * Encapsulate generic threading methods. * Users derive a class from SGThread and implement the run() member function. */ -class SGThread -{ +class SGThread { public: - /** - * + * Create a new thread object. + * When a SGThread object is created it does not begin execution + * immediately. It is started by calling the start() member function. */ SGThread(); /** - * - */ - virtual ~SGThread(); - - /** - * - */ - int start(); - - /** - * + * Start the underlying thread of execution. + * @return Pthread error code if execution fails, otherwise returns 0. */ - void cancel(); + bool start(); /** - * + * Suspends the exection of the calling thread until this thread + * terminates. */ void join(); protected: - /** - * + * Destroy a thread object. + * This is protected so that its illegal to simply delete a thread + * - it must return from its run() function. */ - virtual void run() = 0; - -private: + virtual ~SGThread(); /** - * + * All threads execute by deriving the run() method of SGThread. + * If this function terminates then the thread also terminates. */ - pthread_t tid; - - friend void* start_handler( void* ); + virtual void run() = 0; private: // Disable copying. - SGThread( const SGThread& ); - SGThread& operator=( const SGThread& ); -}; - -inline -SGThread::SGThread() -{ -} - -inline -SGThread::~SGThread() -{ -} + SGThread(const SGThread&); + SGThread& operator=(const SGThread&); -inline int -SGThread::start() -{ - int status = pthread_create( &tid, 0, start_handler, this ); - assert( status == 0 ); - return status; -} + struct PrivateData; + PrivateData* _privateData; -inline void -SGThread::join() -{ - int status = pthread_join( tid, 0 ); - assert( status == 0 ); -} + friend struct PrivateData; +}; -inline void -SGThread::cancel() -{ - int status = pthread_cancel( tid ); - assert( status == 0 ); -} +class SGWaitCondition; /** * A mutex is used to protect a section of code such that at any time * only a single thread can execute the code. */ -class SGMutex -{ - friend class SGCondition; - +class SGMutex { public: - /** * Create a new mutex. + * Under Linux this is a 'fast' mutex. */ SGMutex(); /** * Destroy a mutex object. + * Note: it is the responsibility of the caller to ensure the mutex is + * unlocked before destruction occurs. */ ~SGMutex(); /** - * + * Lock this mutex. + * If the mutex is currently unlocked, it becomes locked and owned by + * the calling thread. If the mutex is already locked by another thread, + * the calling thread is suspended until the mutex is unlocked. If the + * mutex is already locked and owned by the calling thread, the calling + * thread is suspended until the mutex is unlocked, effectively causing + * the calling thread to deadlock. */ void lock(); /** - * - */ - bool trylock(); - - /** - * + * Unlock this mutex. + * It is assumed that the mutex is locked and owned by the calling thread. */ void unlock(); -protected: - pthread_mutex_t mutex; -}; - -inline SGMutex::SGMutex() -{ - int status = pthread_mutex_init( &mutex, 0 ); - assert( status == 0 ); -} - -inline SGMutex::~SGMutex() -{ - int status = pthread_mutex_destroy( &mutex ); - assert( status == 0 ); -} - -inline void SGMutex::lock() -{ - int status = pthread_mutex_lock( &mutex ); - assert( status == 0 ); -} +private: + struct PrivateData; + PrivateData* _privateData; -inline void SGMutex::unlock() -{ - int status = pthread_mutex_unlock( &mutex ); - assert( status == 0 ); -} + friend class SGWaitCondition; +}; /** - * + * A condition variable is a synchronization device that allows threads to + * suspend execution until some predicate on shared data is satisfied. + * A condition variable is always associated with a mutex to avoid race + * conditions. */ -class SGCondition -{ +class SGWaitCondition { public: /** * Create a new condition variable. */ - SGCondition(); + SGWaitCondition(); /** * Destroy the condition object. */ - ~SGCondition(); + ~SGWaitCondition(); /** * Wait for this condition variable to be signaled. * * @param SGMutex& reference to a locked mutex. */ - void wait( SGMutex& ); + void wait(SGMutex&); /** * Wait for this condition variable to be signaled for at most * 'ms' milliseconds. * - * @param SGMutex& reference to a locked mutex. - * @param unsigned long milliseconds to wait for a signal. + * @param mutex reference to a locked mutex. + * @param ms milliseconds to wait for a signal. * - * @return + * @return */ - bool wait( SGMutex& mutex, unsigned long ms ); + bool wait(SGMutex& mutex, unsigned msec); /** * Wake one thread waiting on this condition variable. + * Nothing happens if no threads are waiting. + * If several threads are waiting exactly one thread is restarted. It + * is not specified which. */ void signal(); /** * Wake all threads waiting on this condition variable. + * Nothing happens if no threads are waiting. */ void broadcast(); private: // Disable copying. - SGCondition(const SGCondition& ); - SGCondition& operator=(const SGCondition& ); - -private: + SGWaitCondition(const SGWaitCondition&); + SGWaitCondition& operator=(const SGWaitCondition&); - pthread_cond_t cond; + struct PrivateData; + PrivateData* _privateData; }; -inline SGCondition::SGCondition() -{ - int status = pthread_cond_init( &cond, 0 ); - assert( status == 0 ); -} - -inline SGCondition::~SGCondition() -{ - int status = pthread_cond_destroy( &cond ); - assert( status == 0 ); -} - -inline void SGCondition::signal() -{ - int status = pthread_cond_signal( &cond ); - assert( status == 0 ); -} - -inline void SGCondition::broadcast() -{ - int status = pthread_cond_broadcast( &cond ); - assert( status == 0 ); -} - -inline void SGCondition::wait( SGMutex& mutex ) -{ - int status = pthread_cond_wait( &cond, &mutex.mutex ); - assert( status == 0 ); -} - #endif /* SGTHREAD_HXX_INCLUDED */