00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef SGTHREAD_HXX_INCLUDED
00024 #define SGTHREAD_HXX_INCLUDED 1
00025
00026 #include <simgear/compiler.h>
00027
00028 #include <pthread.h>
00029 #include <cassert>
00030 #include <cerrno>
00031
00032 class SGThread;
00033
00034 extern "C" {
00035 void* start_handler( void* );
00036 };
00037
00042 class SGThread
00043 {
00044 public:
00048 enum cancel_t
00049 {
00050 CANCEL_DISABLE = 0,
00051 CANCEL_DEFERRED,
00052 CANCEL_IMMEDIATE
00053 };
00054 public:
00055
00061 SGThread();
00062
00069 int start( unsigned cpu = 0 );
00070
00076 void cancel();
00077
00082 void join();
00083
00084 protected:
00090 virtual ~SGThread();
00091
00096 void set_cancel( cancel_t mode );
00097
00102 virtual void run() = 0;
00103
00104 private:
00105
00109 pthread_t tid;
00110
00111 friend void* start_handler( void* );
00112
00113 private:
00114
00115 SGThread( const SGThread& );
00116 SGThread& operator=( const SGThread& );
00117 };
00118
00119 inline
00120 SGThread::SGThread()
00121 {
00122 }
00123
00124 inline
00125 SGThread::~SGThread()
00126 {
00127 }
00128
00129 inline int
00130 SGThread::start( unsigned cpu )
00131 {
00132 int status = pthread_create( &tid, 0, start_handler, this );
00133 assert( status == 0 );
00134 (void)status;
00135 #if defined( sgi )
00136 if ( !status && !cpu )
00137 pthread_setrunon_np( cpu );
00138 #endif
00139 return status;
00140 }
00141
00142 inline void
00143 SGThread::join()
00144 {
00145 int status = pthread_join( tid, 0 );
00146 assert( status == 0 );
00147 (void)status;
00148 }
00149
00150 inline void
00151 SGThread::cancel()
00152 {
00153 int status = pthread_cancel( tid );
00154 assert( status == 0 );
00155 (void)status;
00156 }
00157
00162 class SGMutex
00163 {
00164 friend class SGPthreadCond;
00165
00166 public:
00167
00172 SGMutex();
00173
00179 ~SGMutex();
00180
00192 void lock();
00193
00200 bool trylock();
00201
00206 void unlock();
00207
00208 protected:
00209
00213 pthread_mutex_t mutex;
00214 };
00215
00216 inline SGMutex::SGMutex()
00217 {
00218 int status = pthread_mutex_init( &mutex, 0 );
00219 assert( status == 0 );
00220 (void)status;
00221 }
00222
00223 inline SGMutex::~SGMutex()
00224 {
00225 int status = pthread_mutex_destroy( &mutex );
00226 assert( status == 0 );
00227 (void)status;
00228 }
00229
00230 inline void SGMutex::lock()
00231 {
00232 int status = pthread_mutex_lock( &mutex );
00233 assert( status == 0 );
00234 (void)status;
00235 }
00236
00237 inline void SGMutex::unlock()
00238 {
00239 int status = pthread_mutex_unlock( &mutex );
00240 assert( status == 0 );
00241 (void)status;
00242 }
00243
00250 class SGPthreadCond
00251 {
00252 public:
00256 SGPthreadCond();
00257
00261 ~SGPthreadCond();
00262
00268 void wait( SGMutex& );
00269
00279 bool wait( SGMutex& mutex, unsigned long ms );
00280
00287 void signal();
00288
00293 void broadcast();
00294
00295 private:
00296
00297 SGPthreadCond(const SGPthreadCond& );
00298 SGPthreadCond& operator=(const SGPthreadCond& );
00299
00300 private:
00301
00305 pthread_cond_t cond;
00306 };
00307
00308 inline SGPthreadCond::SGPthreadCond()
00309 {
00310 int status = pthread_cond_init( &cond, 0 );
00311 assert( status == 0 );
00312 (void)status;
00313 }
00314
00315 inline SGPthreadCond::~SGPthreadCond()
00316 {
00317 int status = pthread_cond_destroy( &cond );
00318 assert( status == 0 );
00319 (void)status;
00320 }
00321
00322 inline void SGPthreadCond::signal()
00323 {
00324 int status = pthread_cond_signal( &cond );
00325 assert( status == 0 );
00326 (void)status;
00327 }
00328
00329 inline void SGPthreadCond::broadcast()
00330 {
00331 int status = pthread_cond_broadcast( &cond );
00332 assert( status == 0 );
00333 (void)status;
00334 }
00335
00336 inline void SGPthreadCond::wait( SGMutex& mutex )
00337 {
00338 int status = pthread_cond_wait( &cond, &mutex.mutex );
00339 assert( status == 0 );
00340 (void)status;
00341 }
00342
00343 #endif