00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00032 #ifndef THREAD_HPP
00033 #define THREAD_HPP
00034
00035 #include <cstddef>
00036 #include <config.h>
00037 #include <Assert.hpp>
00038
00040
00041 class Runnable {
00042 public:
00044 virtual ~Runnable() { }
00045
00047 virtual void run() = 0;
00048
00050 virtual void clean() { }
00051 };
00052
00053
00057 #ifdef HAVE_PTHREAD
00058 #include <pthread.h>
00059 #include <semaphore.h>
00060
00061 extern "C" {
00063 inline void clean_function(void * t) {
00064 reinterpret_cast<Runnable *>(t)->clean();
00065 }
00066
00068 inline void * thread_function(void * t) {
00069 Runnable *f = reinterpret_cast<Runnable *>(t);
00070 ASSERT(f != NULL);
00071 pthread_cleanup_push(clean_function,f);
00072 f->run();
00073 pthread_cleanup_pop(0);
00074 pthread_exit(NULL);
00075 return NULL;
00076 }
00077 }
00078
00080 class Thread
00081 : public Runnable
00082 {
00083 protected:
00084 pthread_t thread;
00086 public:
00092 bool start()
00093 {
00094 if (thread) return false;
00095 #ifndef NDEBUG
00096 const int ret =
00097 #endif
00098 pthread_create(&thread,NULL,
00099 thread_function,
00100 this);
00101 ASSERT(ret == 0);
00102 return true;
00103 }
00104
00109 void cancel() const
00110 {
00111 pthread_cancel(thread);
00112 }
00113
00119 static inline void cancellable(const bool& b)
00120 {
00121 pthread_setcancelstate((b)?PTHREAD_CANCEL_ENABLE:PTHREAD_CANCEL_DISABLE
00122 ,NULL);
00123 }
00124
00129 static inline void cancellable()
00130 {
00131 pthread_testcancel();
00132 }
00133
00140 inline bool join()
00141 {
00142 if (thread) {
00143 void * ret;
00144 pthread_join(thread,&ret);
00145 return false;
00146 }
00147 return true;
00148 }
00149
00154 inline const pthread_t& getId() const
00155 {
00156 return thread;
00157 }
00158
00163 Thread()
00164 : thread(0)
00165 {
00166 ;
00167 }
00168
00173 virtual ~Thread()
00174 {
00175 this->join();
00176 }
00177 };
00178
00180 class Mutex
00181 {
00182 protected:
00183 pthread_mutex_t mutex;
00185 public:
00190 inline void lock()
00191 {
00192 pthread_mutex_lock(&mutex);
00193 }
00194
00199 inline void unlock()
00200 {
00201 pthread_mutex_unlock(&mutex);
00202 }
00203
00210 inline int trylock()
00211 {
00212 return pthread_mutex_trylock(&mutex);
00213 }
00214
00219 Mutex()
00220 {
00221 pthread_mutex_init(&mutex,NULL);
00222 }
00223
00228 ~Mutex()
00229 {
00230 pthread_mutex_destroy(&mutex);
00231 }
00232 };
00233
00235 class Semaphore
00236 {
00237 protected:
00238 sem_t semaphore;
00240 public:
00241
00246 inline void wait()
00247 {
00248 sem_wait(&semaphore);
00249 }
00250
00255 inline void post()
00256 {
00257 sem_post(&semaphore);
00258 }
00259
00266 inline int trywait()
00267 {
00268 return sem_trywait(&semaphore);
00269 }
00270
00275 Semaphore()
00276 {
00277 sem_init(&semaphore,
00278 0,
00279 1
00280 );
00281 }
00282
00287 ~Semaphore()
00288 {
00289 sem_destroy(&semaphore);
00290 }
00291 };
00292
00293 #else // HAVE_PTHREAD
00294
00302
00303 class Thread
00304 : public Runnable
00305 {
00306 public:
00307 typedef size_t Id;
00309 public:
00315 bool start()
00316 {
00317 this->run();
00318 return true;
00319 }
00320
00325 void cancel() const
00326 {
00327 ;
00328 }
00329
00335 static inline void cancellable(const bool& b)
00336 {
00337 ;
00338 }
00339
00344 static inline void cancellable()
00345 {
00346 ;
00347 }
00348
00355 inline bool join()
00356 {
00357 return true;
00358 }
00359
00364 inline Id getId() const
00365 {
00366 return 0;
00367 }
00368
00373 Thread()
00374 {
00375 ;
00376 }
00377
00382 virtual ~Thread()
00383 {
00384 ;
00385 }
00386 };
00387
00389 class Mutex
00390 {
00391 public:
00396 inline void lock()
00397 {
00398 ;
00399 }
00400
00405 inline void unlock()
00406 {
00407 ;
00408 }
00409
00416 inline int trylock()
00417 {
00418 return 0;
00419 }
00420
00425 Mutex()
00426 {
00427 ;
00428 }
00429
00434 ~Mutex()
00435 {
00436 ;
00437 }
00438 };
00439
00441 class Semaphore
00442 {
00443 public:
00448 inline void wait()
00449 {
00450 ;
00451 }
00452
00457 inline void post()
00458 {
00459 ;
00460 }
00461
00468 inline int trywait()
00469 {
00470 return 0;
00471 }
00472
00477 Semaphore()
00478 {
00479 ;
00480 }
00481
00486 ~Semaphore()
00487 {
00488 ;
00489 }
00490 };
00491
00492
00493 #endif // HAVE_PTHREAD
00494
00495 #endif