00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef _JOT_STD_THREAD_H
00025 #define _JOT_STD_THREAD_H
00026
00027 #include "std/dllimpexp.H"
00028 #include "std/config.H"
00029 #include "std/error.H"
00030 #include "std/thread_mutex.H"
00031
00032
00033
00034
00035 #ifdef USE_PTHREAD
00036 #if defined(sun) && !defined(_REENTRANT)
00037
00038 Need to compile thread stuff with -mt under Solaris
00039 #endif
00040 #include <pthread.h>
00041
00042 class Thread {
00043 public:
00044 Thread() { _running = false; }
00045 virtual ~Thread() { if (_running) pthread_cancel(_thread); }
00046
00047 void start() {
00048 pthread_attr_t attr;
00049 int retval;
00050 if ((retval = pthread_attr_init(&attr)) != 0) {
00051 err_sys("Thread:start - pthread_attr_init returned %d", retval);
00052 }
00053 if ((retval=pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)) != 0) {
00054
00055 err_quit("Thread:start - pthread_attr_setscope: %s",
00056 strerror(retval));
00057 }
00058 _running = !pthread_create(&_thread, &attr, kickstart, (void *)this);
00059 pthread_attr_destroy(&attr);
00060 }
00061 protected:
00062 virtual void threadProc() = 0;
00063
00064 private:
00065 bool _running;
00066 pthread_t _thread;
00067 static void *kickstart(void *me) { ((Thread *)me)->threadProc();
00068 return 0; }
00069 };
00070
00071
00072 class ThreadSync {
00073 private:
00074 pthread_mutex_t mut_;
00075 pthread_cond_t queue_;
00076 int count_;
00077 const int number_;
00078 int generation_;
00079
00080 public:
00081 ThreadSync(int number): number_(number) {
00082 pthread_mutex_init(&mut_, 0);
00083 pthread_cond_init(&queue_, 0);
00084 count_ = 0;
00085 generation_ = 0;
00086 }
00087
00088 ~ThreadSync() {
00089 pthread_mutex_destroy(&mut_);
00090 pthread_cond_destroy(&queue_);
00091 }
00092
00093 #ifndef sgi
00094 void wait() {
00095 pthread_mutex_lock(&mut_);
00096 if (++count_ < number_) {
00097 int my_generation = generation_;
00098 while(my_generation == generation_)
00099 pthread_cond_wait(&queue_, &mut_);
00100 } else {
00101 count_ = 0;
00102 generation_++;
00103 pthread_cond_broadcast(&queue_);
00104 }
00105 pthread_mutex_unlock(&mut_);
00106 }
00107 #else
00108 void wait() {
00109 pthread_mutex_lock(&mut_);
00110 if (++count_ < number_) {
00111 assert((count_ < number_) && (count_ > 0));
00112 int my_generation = generation_;
00113 pthread_mutex_unlock(&mut_);
00114 while(my_generation == generation_)
00115 ;
00116 } else {
00117 count_ = 0;
00118 generation_++;
00119 pthread_mutex_unlock(&mut_);
00120 }
00121 }
00122 #endif
00123 };
00124
00125 class ThreadData {
00126 public:
00127 ThreadData() : _key(0) { }
00128
00129 void create() {
00130 if (pthread_key_create(&_key, 0)) {
00131 cerr << "ThreadData::create - Could not create key" << endl;
00132 }
00133 }
00134
00135 void set(void *val) { pthread_setspecific(_key, val);}
00136 void *get() { return pthread_getspecific(_key);}
00137 protected:
00138 pthread_key_t _key;
00139 };
00140 #endif
00141
00142 #endif