IBR-DTNSuite 0.6

ibrcommon/ibrcommon/thread/Thread.h

Go to the documentation of this file.
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_ */