00001 // 00002 // SickThread.hpp 00003 // 00004 00005 #ifndef SICKTHREAD_HPP 00006 #define SICKTHREAD_HPP 00007 00008 #include "sick_scan/tcp/BasicDatatypes.hpp" 00009 #include <pthread.h> 00010 #include <unistd.h> 00011 00012 00013 extern "C" void* wrapper_prerun(void*); 00014 class ThreadWrapperBase 00015 { 00016 pthread_t t_id; 00017 friend void* wrapper_prerun(void*); 00018 virtual void thread_entry() = 0; 00019 protected: 00020 void* pthis; 00021 public: 00022 00023 ThreadWrapperBase() {pthis = NULL;}; 00024 virtual ~ThreadWrapperBase() {}; 00025 00026 void run(void* classptr) 00027 { 00028 if (pthis == NULL) 00029 { 00030 pthis = classptr; 00031 pthread_create(&t_id, NULL, wrapper_prerun, this); 00032 } 00033 } 00034 00035 bool isRunning() 00036 { 00037 if (pthis == NULL) 00038 { 00039 return false; 00040 } 00041 00042 return true; 00043 } 00044 00045 void join() 00046 { 00047 pthread_join(t_id, NULL); 00048 pthis = NULL; 00049 } 00050 00051 pthread_t* get_thread_id() 00052 { 00053 return &t_id; 00054 } 00055 }; 00056 00057 00059 00079 template <typename T, void (T::*M)(bool&, UINT16&)> 00080 class SickThread : public ThreadWrapperBase 00081 { 00082 void thread_entry() 00083 { 00084 T* pt = static_cast<T*>(pthis); 00085 00086 m_threadShouldRun = true; 00087 bool endThread = false; 00088 UINT16 sleepTimeMs = 0; 00089 00090 while ((m_threadShouldRun == true) && (endThread == false)) 00091 { 00092 usleep(((UINT32)sleepTimeMs) * 1000); 00093 (pt->*M)(endThread, sleepTimeMs); 00094 } 00095 } 00096 00097 00098 public: 00099 void join() 00100 { 00101 m_threadShouldRun = false; 00102 ThreadWrapperBase::join(); 00103 } 00104 00105 SickThread(){m_threadShouldRun = true;} 00106 virtual ~SickThread(){}; 00107 bool m_threadShouldRun; 00108 }; 00109 00110 /* 00111 template <typename T, void (T::*M)()> 00112 class SickThread : public ThreadWrapperBase 00113 { 00114 void thread_entry() 00115 { 00116 T* pt = static_cast<T*>(pthis); 00117 00118 00119 (pt->*M)(); 00120 } 00121 public: 00122 SickThread(){} 00123 virtual ~SickThread(){}; 00124 }; 00125 */ 00126 00127 00128 00129 // class SickThread 00130 // { 00131 // public: 00132 // /** 00133 // * The thread callback function. 00134 // * 00135 // * \param endThisThread A bool flag that may be set by the callback function 00136 // * to "false" in case the thread function decides this thread 00137 // * needs to end. 00138 // * 00139 // * \param sleepTimeMs The sleep time, in ms, that will be spent between 00140 // * subsequent calls to the callback function. Default is 10 ms, but 00141 // * other times may be set. Note that not all operating systems may be 00142 // * able to schedule very short sleep times. 00143 // */ 00144 // // int (*comp)(const void *, const void *) 00145 // typedef void (*ThreadFunction) (bool& endThisThread, UINT16& sleepTimeMs); 00146 // 00147 // /** 00148 // * The thread callback function (simpler version). 00149 // * 00150 // * \return True if the thread should continue to run and 00151 // * continuously call this function (after potentially some waiting 00152 // * time). False if this thread should end now. 00153 // */ 00154 // // typedef boost::function < bool (void) > ThreadFunctionSimple; 00155 // 00156 // /// Default constructor. 00157 // SickThread(); 00158 // 00159 // /// Destructor. Will call stop() if thread is not yet stopped, and 00160 // /// wait for its completion before destructing this object. 00161 // ~SickThread(); 00162 // 00163 // /// Start the thread. 00164 // bool start(); 00165 // 00166 // /// Start the thread and also set the thread function. \sa start() 00167 // bool start(ThreadFunction function); 00168 // 00169 // /// Returns true if this thread was started and is running. 00170 // bool isRunning() const; 00171 // 00172 // /// Stops this thread and waits for its completion. 00173 // void stop(); 00174 // 00175 // /// Set whether we want verbose debug output 00176 // void setVerboseDebugOutput(bool enableVerboseDebugOutput); 00177 // 00178 // /// Set the thread's "run" function 00179 // void setFunction(ThreadFunction threadFunction); 00180 // 00181 // /// Set the thread's "run" function, simpler version 00182 // // void setFunctionSimple(ThreadFunctionSimple threadFunctionSimple); 00183 // 00184 // /// Set the sleep time between subsequent ThreadFunctionSimple calls in [milliseconds] 00185 // void setSleepTimeMilliseconds(unsigned v); 00186 // 00187 // /// Returns the sleep time between subsequent ThreadFunctionSimple 00188 // /// calls in [milliseconds]. (Default value is zero.) 00189 // unsigned getSleepTimeMilliseconds() const { return m_sleepTimeMilliseconds; } 00190 // 00191 // private: 00192 // static void* thread(void* ptr); // The thread function 00193 // void thread2(); // The member thread function 00194 // 00195 // // typedef boost::mutex Mutex; 00196 // 00197 // pthread_mutex_t m_mutex; // = PTHREAD_MUTEX_INITIALIZER; 00198 // // mutable Mutex m_threadMutex; 00199 // // boost::condition m_threadCondition; 00200 // ThreadFunction m_function; 00201 // // ThreadFunctionSimple m_functionSimple; 00202 // 00203 // // boost::scoped_ptr<boost::thread> m_threadPtr; 00204 // bool m_threadShouldRun; 00205 // bool m_threadIsRunning; 00206 // bool m_beVerbose; 00207 // unsigned m_sleepTimeMilliseconds; 00208 // 00209 // // The thread 00210 // pthread_t m_thread; 00211 // 00212 // }; 00213 00214 /* 00215 #include <pthread.h> 00216 #include <stdio.h> 00217 #include <stdlib.h> 00218 #include <assert.h> 00219 00220 #define NUM_THREADS 5 00221 00222 void *TaskCode(void *argument) 00223 { 00224 int tid; 00225 00226 tid = *((int *) argument); 00227 printf("Hello World! It's me, thread %d!\n", tid); 00228 00229 // optionally: insert more useful stuff here 00230 00231 return NULL; 00232 } 00233 00234 int main(void) 00235 { 00236 pthread_t threads[NUM_THREADS]; 00237 int thread_args[NUM_THREADS]; 00238 int rc, i; 00239 00240 // create all threads 00241 for (i=0; i<NUM_THREADS; ++i) { 00242 thread_args[i] = i; 00243 printf("In main: creating thread %d\n", i); 00244 rc = pthread_create(&threads[i], NULL, TaskCode, (void *) &thread_args[i]); 00245 assert(0 == rc); 00246 } 00247 00248 // wait for all threads to complete 00249 for (i=0; i<NUM_THREADS; ++i) { 00250 rc = pthread_join(threads[i], NULL); 00251 assert(0 == rc); 00252 } 00253 00254 exit(EXIT_SUCCESS); 00255 } 00256 */ 00257 00258 #endif // SICKTHREAD_HPP