IBR-DTNSuite  0.8
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:
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_ */