IBR-DTNSuite
0.8
|
00001 #ifndef IBRCOMMON_CONDITIONAL_H_ 00002 #define IBRCOMMON_CONDITIONAL_H_ 00003 00004 #include <stdlib.h> 00005 #include <errno.h> 00006 #include <pthread.h> 00007 #include "ibrcommon/thread/Mutex.h" 00008 #include "ibrcommon/Exceptions.h" 00009 00010 namespace ibrcommon 00011 { 00012 class Conditional : public Mutex 00013 { 00014 public: 00015 class ConditionalAbortException : public ibrcommon::Exception 00016 { 00017 public: 00018 enum abort_t 00019 { 00020 COND_TIMEOUT = 0, 00021 COND_ABORT = 1, 00022 COND_ERROR = 2 00023 }; 00024 00025 ConditionalAbortException(abort_t abort, string what = "Conditional has been unblocked.") throw() : ibrcommon::Exception(what), reason(abort) 00026 { 00027 }; 00028 00029 const abort_t reason; 00030 }; 00031 00032 Conditional(); 00033 virtual ~Conditional(); 00034 00035 void signal(bool broadcast = false); 00036 00037 /* 00038 * Wait until signal() is called or the timeout exceeds. 00039 * @param timeout A timeout in milliseconds. 00040 * @throw ConditionalAbortException If a timeout occur or the Conditional is aborted by abort() the ConditionalAbortException is thrown. 00041 */ 00042 void wait(size_t timeout = 0) throw (ConditionalAbortException); 00043 void wait(struct timespec *ts) throw (ConditionalAbortException); 00044 00048 void abort(); 00049 00053 void reset(); 00054 00061 static void gettimeout(size_t timeout, struct timespec *hires); 00062 00063 private: 00064 bool isLocked(); 00065 00066 class attribute 00067 { 00068 public: 00069 pthread_condattr_t attr; 00070 attribute(); 00071 }; 00072 00073 pthread_cond_t cond; 00074 00075 static attribute attr; 00076 00077 bool _abort; 00078 }; 00079 00080 template<class T, T block> 00081 class StatefulConditional : public Conditional 00082 { 00083 public: 00084 StatefulConditional(T state) : _state(state) {}; 00085 virtual ~StatefulConditional() {}; 00086 00087 void setState(T state) 00088 { 00089 if (ifState(block)) return; 00090 _state = state; 00091 this->signal(true); 00092 } 00093 00094 bool waitState(T state) 00095 { 00096 while (!ifState(state)) 00097 { 00098 if (ifState(block)) return false; 00099 wait(); 00100 } 00101 00102 return true; 00103 } 00104 00105 T getState() 00106 { 00107 return _state; 00108 } 00109 00110 bool ifState(T state) 00111 { 00112 return (state == _state); 00113 } 00114 00115 private: 00116 T _state; 00117 }; 00118 } 00119 00120 #endif /*CONDITIONAL_H_*/