Threads.h

Go to the documentation of this file.
00001 
00002 //    Copyright 2004, SenseGraphics AB
00003 //
00004 //    This file is part of H3D API.
00005 //
00006 //    H3D API is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    H3D API is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with H3D API; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 //
00020 //    A commercial license is also available. Please contact us at 
00021 //    www.sensegraphics.com for more information.
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     // Callback function for synchronising all haptic threads.
00196     static PeriodicThreadBase::CallbackCode sync_haptics( void * );
00197 
00198     // The haptic threads that have been created.
00199     static std::vector< HapticThreadBase * > threads;
00200 
00201     // Lock used to get the haptic threads to wait for the callback 
00202     // function to finish.
00203     static ConditionLock haptic_lock; 
00204 
00205     // Lock used to get the thread calling the synchronousHapticCB
00206     // function to wait for all the haptic threads to synchronize.
00207     static ConditionLock sg_lock; 
00208 
00209     // Counter used when synchronizing haptic threads. It tells how
00210     // many more haptic threads that are left to synchronize.
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     // The function that handles callbacks. Is also the main function that
00255     // is run in the thread.
00256     static void *thread_func( void * );
00257 
00258     typedef std::list< std::pair< CallbackFunc, void * > > CallbackList;
00259     // A list of the callback functions to run.
00260     CallbackList callbacks;
00261     // A lock for synchronizing changes to the callbacks member.
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       // the hl thread should not be added unless the hd scheduler
00296       // has started.
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 

Generated on Thu Aug 24 12:38:34 2006 for H3D API by  doxygen 1.4.5