IBR-DTNSuite  0.8
ibrcommon/ibrcommon/thread/ThreadsafeState.h
Go to the documentation of this file.
00001 /*
00002  * ThreadsafeState.h
00003  *
00004  *  Created on: 13.05.2011
00005  *      Author: morgenro
00006  */
00007 
00008 #ifndef THREADSAFESTATE_H_
00009 #define THREADSAFESTATE_H_
00010 
00011 #include <ibrcommon/thread/MutexLock.h>
00012 #include <ibrcommon/thread/Conditional.h>
00013 
00014 namespace ibrcommon
00015 {
00016         template <class T>
00017         class ThreadsafeState : protected ibrcommon::Conditional
00018         {
00019         protected:
00020                 T _state;
00021                 T _final_state;
00022 
00023         public:
00024                 ThreadsafeState(T init, T final)
00025                  : _state(init), _final_state(final)
00026                 {
00027                 };
00028 
00029                 virtual ~ThreadsafeState()
00030                 {
00031                         ibrcommon::MutexLock l(*this);
00032                         _state = _final_state;
00033                         this->signal(true);
00034                 };
00035 
00036                 T get() const
00037                 {
00038                         return _state;
00039                 }
00040 
00041                 void wait(T st)
00042                 {
00043                         ibrcommon::MutexLock l(*this);
00044                         while (_state != st)
00045                         {
00046                                 if (_state == _final_state) return;
00047                                 this->wait();
00048                         }
00049                 }
00050 
00051                 T operator=(T st)
00052                 {
00053                         // return, if the final state is reached
00054                         if (_state == _final_state) return _state;
00055 
00056                         ibrcommon::MutexLock l(*this);
00057                         _state = st;
00058                         this->signal(true);
00059                         return _state;
00060                 }
00061 
00062                 bool operator==(T st) const
00063                 {
00064                         return (st == _state);
00065                 }
00066 
00067                 bool operator!=(T st) const
00068                 {
00069                         return (st != _state);
00070                 }
00071 
00072                 class Locked
00073                 {
00074                 private:
00075                         ThreadsafeState<T> &_tss;
00076                         MutexLock _lock;
00077 
00078                 public:
00079                         Locked(ThreadsafeState<T> &tss)
00080                          : _tss(tss), _lock(tss)
00081                         {
00082                         };
00083 
00084                         virtual ~Locked()
00085                         {
00086                                 _tss.signal(true);
00087                         };
00088 
00089                         T get() const
00090                         {
00091                                 return _tss._state;
00092                         }
00093 
00094                         T operator=(T st)
00095                         {
00096                                 // return, if the final state is reached
00097                                 if (_tss._state == _tss._final_state) return _tss._state;
00098 
00099                                 _tss._state = st;
00100                                 return _tss._state;
00101                         }
00102 
00103                         bool operator==(T st)
00104                         {
00105                                 return (_tss._state == st);
00106                         }
00107 
00108                         bool operator!=(T st)
00109                         {
00110                                 return (_tss._state != st);
00111                         }
00112 
00113                         void wait(size_t st)
00114                         {
00115                                 while (!(_tss._state & st))
00116                                 {
00117                                         if (_tss._state == _tss._final_state) return;
00118                                         ((Conditional&)_tss).wait();
00119                                 }
00120                         }
00121 
00122                         void wait(T st)
00123                         {
00124                                 while (_tss._state != st)
00125                                 {
00126                                         if (_tss._state == _tss._final_state) return;
00127                                         ((Conditional&)_tss).wait();
00128                                 }
00129                         }
00130                 };
00131 
00132                 Locked lock()
00133                 {
00134                         return *this;
00135                 }
00136         };
00137 }
00138 
00139 #endif /* THREADSAFESTATE_H_ */