|
IBR-DTNSuite 0.6
|
00001 /* 00002 * Thread.h 00003 * 00004 * Created on: 30.07.2009 00005 * Author: morgenro 00006 */ 00007 00008 #ifndef IBRCOMMON_THREAD_H_ 00009 #define IBRCOMMON_THREAD_H_ 00010 00011 #include <pthread.h> 00012 #include <sys/types.h> 00013 #include "ibrcommon/thread/Mutex.h" 00014 #include "ibrcommon/thread/Conditional.h" 00015 #include "ibrcommon/thread/ThreadsafeState.h" 00016 00017 //2 MB is a sensible default, we set this since system defaults vary widely: https://computing.llnl.gov/tutorials/pthreads/#Stack 00018 #define DEFAULT_STACKSIZE 2*1024*1024 00019 00020 namespace ibrcommon 00021 { 00022 class ThreadException : public ibrcommon::Exception 00023 { 00024 public: 00025 ThreadException(int err = 0, string what = "An error occured during a thread operation.") throw() : ibrcommon::Exception(what), error(err) 00026 { 00027 }; 00028 00029 const int error; 00030 }; 00031 00042 class Thread 00043 { 00044 protected: 00045 enum THREAD_STATE 00046 { 00047 THREAD_INITIALIZED = 1 << 0, 00048 THREAD_PREPARE = 1 << 1, 00049 THREAD_SETUP = 1 << 2, 00050 THREAD_RUNNING = 1 << 3, 00051 THREAD_CANCELLED = 1 << 4, 00052 THREAD_FINALIZING = 1 << 5, 00053 THREAD_FINALIZED = 1 << 6, 00054 THREAD_JOINED = 1 << 7, 00055 THREAD_ERROR = 1 << 8 00056 }; 00057 00058 ibrcommon::ThreadsafeState<THREAD_STATE> _state; 00059 00060 // thread's id 00061 pthread_t tid; 00062 00063 // thread's stack size 00064 size_t stack; 00065 00066 // thread's priority 00067 int priority; 00068 00069 // thread's attributes 00070 pthread_attr_t attr; 00071 00077 Thread(size_t stack = DEFAULT_STACKSIZE, bool delete_on_exit = false); 00078 00079 public: 00083 virtual ~Thread() = 0; 00084 00089 static void yield(void); 00090 00095 static void sleep(size_t timeout); 00096 00100 virtual void setup(void) { }; 00101 00105 virtual void run(void) = 0; 00106 00110 virtual void finally(void) { }; 00111 00115 static void exit(void); 00116 00120 void detach(void); 00121 00126 static void concurrency(int level); 00127 00133 bool operator==(const ibrcommon::Thread &other) 00134 { 00135 return (equal(other.tid, tid) != 0); 00136 } 00137 00138 protected: 00139 class CancelProtector 00140 { 00141 public: 00142 CancelProtector(bool enable = false); 00143 virtual ~CancelProtector(); 00144 00145 private: 00146 int _oldstate; 00147 }; 00148 00154 int kill(int sig); 00155 00160 void cancellation_point(); 00161 00165 void cancel() throw (ThreadException); 00166 virtual bool __cancellation() { return false; }; 00167 00174 static bool equal(pthread_t thread1, pthread_t thread2); 00175 00179 static void* exec_thread(void *obj); 00180 00185 static void finalize_thread(void *obj); 00186 00187 private: 00191 const bool __delete_on_exit; 00192 00196 sigset_t mask, orig_mask; 00197 }; 00198 00209 class JoinableThread : protected Thread 00210 { 00211 protected: 00216 JoinableThread(size_t size = DEFAULT_STACKSIZE); 00217 00218 public: 00223 virtual ~JoinableThread() = 0; 00224 00230 void join(void); 00231 00236 inline bool isRunning(void) 00237 { return _state == THREAD_RUNNING; }; 00238 00247 void start(int priority = 0) throw (ThreadException); 00248 00252 void stop() throw (ThreadException); 00253 }; 00254 00262 class DetachedThread : protected Thread 00263 { 00264 protected: 00269 DetachedThread(size_t size = DEFAULT_STACKSIZE); 00270 00271 public: 00277 virtual ~DetachedThread() = 0; 00278 00285 void start(int priority = 0) throw (ThreadException); 00286 00290 void stop() throw (ThreadException); 00291 }; 00292 } 00293 00294 #endif /* THREAD_H_ */