Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef NETFT_ETHERCAT_HARDWARE__THREAD_SAFE_DOUBLE_BUFFER
00036 #define NETFT_ETHERCAT_HARDWARE__THREAD_SAFE_DOUBLE_BUFFER
00037
00038 #include <boost/thread/mutex.hpp>
00039
00040 namespace netft_ethercat_hardware
00041 {
00042
00043 template<class T>
00044 class ThreadSafeDoubleBuffer
00045 {
00046 public:
00047 ThreadSafeDoubleBuffer();
00048 ThreadSafeDoubleBuffer(const T &initial_value);
00049
00050 void put(const T &value);
00051 void get(T &value);
00052
00053 protected:
00054 T v1_, v2_;
00055 boost::mutex mutex1_;
00056 boost::mutex mutex2_;
00057 unsigned blocked_counter_;
00058 };
00059
00060
00061 template<class T>
00062 ThreadSafeDoubleBuffer<T>::ThreadSafeDoubleBuffer() : blocked_counter_(0)
00063 {
00064
00065 }
00066
00067 template<class T>
00068 ThreadSafeDoubleBuffer<T>::ThreadSafeDoubleBuffer(const T &initial_value) :
00069 blocked_counter_(0), v1_(initial_value), v2_(initial_value)
00070 {
00071
00072 }
00073
00074 template<class T>
00075 void ThreadSafeDoubleBuffer<T>::put(const T &value)
00076 {
00077
00078 { boost::unique_lock<boost::mutex> lock(mutex1_);
00079 v1_ = value;
00080 }
00081 { boost::unique_lock<boost::mutex> lock(mutex2_);
00082 v2_ = value;
00083 }
00084 }
00085
00086 template<class T>
00087 void ThreadSafeDoubleBuffer<T>::get(T &value)
00088 {
00089
00090 if (mutex1_.try_lock())
00091 {
00092 value = v1_;
00093 mutex1_.unlock();
00094 return;
00095 }
00096 if (mutex2_.try_lock())
00097 {
00098 value = v2_;
00099 mutex2_.unlock();
00100 return;
00101 }
00102
00103 { boost::unique_lock<boost::mutex> lock(mutex1_);
00104 v1_ = value;
00105 ++blocked_counter_;
00106 }
00107 }
00108
00109 }
00110
00111
00112 #endif // NETFT_ETHERCAT_HARDWARE__THREAD_SAFE_DOUBLE_BUFFER