IBR-DTNSuite
0.8
|
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: 00144 int kill(int sig); 00145 00149 void cancel() throw (ThreadException); 00150 virtual void __cancellation() = 0; 00151 00158 static bool equal(pthread_t thread1, pthread_t thread2); 00159 00163 static void* exec_thread(void *obj); 00164 00169 static void finalize_thread(void *obj); 00170 00171 private: 00175 const bool __delete_on_exit; 00176 00180 sigset_t mask, orig_mask; 00181 }; 00182 00193 class JoinableThread : protected Thread 00194 { 00195 protected: 00200 JoinableThread(size_t size = DEFAULT_STACKSIZE); 00201 00202 public: 00207 virtual ~JoinableThread() = 0; 00208 00214 void join(void); 00215 00220 inline bool isRunning(void) 00221 { return _state == THREAD_RUNNING; }; 00222 00231 void start(int priority = 0) throw (ThreadException); 00232 00236 void stop() throw (ThreadException); 00237 }; 00238 00246 class DetachedThread : protected Thread 00247 { 00248 protected: 00253 DetachedThread(size_t size = DEFAULT_STACKSIZE); 00254 00255 public: 00261 virtual ~DetachedThread() = 0; 00262 00269 void start(int priority = 0) throw (ThreadException); 00270 00274 void stop() throw (ThreadException); 00275 }; 00276 } 00277 00278 #endif /* THREAD_H_ */