00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00027
00029
00030 #ifndef __THREADS_H__
00031 #define __THREADS_H__
00032
00033 #include "H3DApi.h"
00034 #include <list>
00035 #include <vector>
00036 #include <pthread.h>
00037
00038 #ifdef WIN32
00039 #ifdef _MSC_VER
00040 #pragma comment( lib, "pthreadVC2.lib" )
00041 #endif
00042 #define DEFAULT_THREAD_PRIORITY THREAD_PRIORITY_NORMAL
00043 #else
00044 #define DEFAULT_THREAD_PRIORITY 0
00045 #endif
00046
00047 namespace H3D {
00053 class H3DAPI_API MutexLock {
00054 public:
00056 MutexLock();
00057
00059 ~MutexLock();
00060
00063 void lock();
00064
00066 void unlock();
00067
00069 bool tryLock();
00070
00071 protected:
00072 pthread_mutex_t mutex;
00073 };
00074
00075
00091 class H3DAPI_API ConditionLock: public MutexLock {
00092 public:
00094 ConditionLock();
00095
00097 ~ConditionLock();
00098
00101 void wait();
00102
00106 bool timedWait( unsigned int ms );
00107
00109 void signal();
00110
00112 void broadcast();
00113
00114 protected:
00115 pthread_cond_t cond;
00116 };
00117
00118
00120 class H3DAPI_API ThreadBase {
00121 public:
00123 virtual ~ThreadBase() {}
00124
00125 typedef pthread_t ThreadId;
00126
00128 static ThreadId getCurrentThreadId();
00129
00131 static ThreadId getMainThreadId() {
00132 return main_thread_id;
00133 }
00134
00136 static bool inMainThread();
00137
00139 inline ThreadId getThreadId() { return thread_id; }
00140 protected:
00142 ThreadId thread_id;
00143
00145 static ThreadId main_thread_id;
00146 };
00147
00150 class H3DAPI_API PeriodicThreadBase: public ThreadBase {
00151 public:
00153 typedef enum {
00155 CALLBACK_DONE,
00158 CALLBACK_CONTINUE
00159 } CallbackCode;
00160
00162 typedef CallbackCode (*CallbackFunc)(void *data);
00163
00167 virtual void synchronousCallback( CallbackFunc func, void *data ) = 0;
00168
00172 virtual void asynchronousCallback( CallbackFunc func, void *data ) = 0;
00173 };
00174
00177 class H3DAPI_API HapticThreadBase {
00178 public:
00180 HapticThreadBase();
00181
00183 virtual ~HapticThreadBase();
00184
00188 static void synchronousHapticCB( PeriodicThreadBase::CallbackFunc func,
00189 void *data );
00190
00193 static bool inHapticThread();
00194 protected:
00195
00196 static PeriodicThreadBase::CallbackCode sync_haptics( void * );
00197
00198
00199 static std::vector< HapticThreadBase * > threads;
00200
00201
00202
00203 static ConditionLock haptic_lock;
00204
00205
00206
00207 static ConditionLock sg_lock;
00208
00209
00210
00211 static int haptic_threads_left;
00212 };
00213
00216 class H3DAPI_API SimpleThread : public ThreadBase {
00217 public:
00221 SimpleThread( void *(func) (void *),
00222 void *args = NULL,
00223 int thread_priority = DEFAULT_THREAD_PRIORITY );
00224
00226 virtual ~SimpleThread();
00227 };
00228
00232 class H3DAPI_API PeriodicThread : public PeriodicThreadBase {
00233 public:
00238 PeriodicThread( int thread_priority = DEFAULT_THREAD_PRIORITY,
00239 int thread_frequency = -1 );
00240
00242 virtual ~PeriodicThread();
00243
00247 virtual void synchronousCallback( CallbackFunc func, void *data );
00248
00252 virtual void asynchronousCallback( CallbackFunc func, void *data );
00253 protected:
00254
00255
00256 static void *thread_func( void * );
00257
00258 typedef std::list< std::pair< CallbackFunc, void * > > CallbackList;
00259
00260 CallbackList callbacks;
00261
00262 ConditionLock callback_lock;
00263
00265 int priority;
00266
00268 int frequency;
00269
00270 };
00271
00275 class H3DAPI_API HapticThread : public HapticThreadBase,
00276 public PeriodicThread {
00277 public:
00279 HapticThread( int thread_priority = DEFAULT_THREAD_PRIORITY,
00280 int thread_frequency = -1 ):
00281 PeriodicThread( thread_priority, thread_frequency ) {
00282 }
00283 };
00284
00289 class H3DAPI_API HLThread : public HapticThreadBase,
00290 public PeriodicThreadBase {
00291
00292 private:
00293 HLThread():
00294 is_active( false ) {
00295
00296
00297 sg_lock.lock();
00298 threads.pop_back();
00299 sg_lock.unlock();
00300 }
00301 public:
00303 static HLThread *getInstance() {
00304 return singleton;
00305 }
00306
00308 inline bool isActive() { return is_active; }
00309
00312 void setActive( bool _active );
00313
00317 virtual void synchronousCallback( CallbackFunc func, void *data );
00318
00322 virtual void asynchronousCallback( CallbackFunc func, void *data );
00323 protected:
00324 static PeriodicThread::CallbackCode setThreadId( void * _data );
00325 static HLThread *singleton;
00326 bool is_active;
00327 };
00328
00329 }
00330
00331 #endif
00332
00333
00334