monitor.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef EQBASE_MONITOR_H
00019 #define EQBASE_MONITOR_H
00020
00021 #include <eq/base/nonCopyable.h>
00022
00023 #include <errno.h>
00024 #include <string.h>
00025 #include <iostream>
00026 #include <typeinfo>
00027
00028
00029 namespace eq
00030 {
00031 namespace base
00032 {
00033 class MonitorPrivate;
00034
00043 template< typename T > class Monitor : public NonCopyable
00044 {
00045 public:
00047 Monitor() : _value( static_cast<T>( 0 )) { _construct(); }
00049 Monitor( const T& value ) : _value( value ) { _construct(); }
00050
00052 ~Monitor();
00053
00057 Monitor& operator++ ();
00059 Monitor& operator-- ();
00060
00062 Monitor& operator = ( const T& value )
00063 {
00064 set( value );
00065 return *this;
00066 }
00067
00069 void set( const T& value );
00071
00078 const T& waitEQ( const T& value ) const;
00079
00084 const T& waitNE( const T& value ) const;
00085
00091 const T& waitGE( const T& value ) const;
00092
00098 const T& waitLE( const T& value ) const;
00100
00103 bool operator == ( const T& value ) const { return _value == value; }
00104 bool operator != ( const T& value ) const { return _value != value; }
00105 bool operator < ( const T& value ) const { return _value < value; }
00106 bool operator > ( const T& value ) const { return _value > value; }
00107 bool operator <= ( const T& value ) const { return _value <= value; }
00108 bool operator >= ( const T& value ) const { return _value >= value; }
00109
00110 bool operator == ( const Monitor<T>& rhs ) const
00111 { return _value == rhs._value; }
00112 bool operator != ( const Monitor<T>& rhs ) const
00113 { return _value != rhs._value; }
00114 bool operator < ( const Monitor<T>& rhs ) const
00115 { return _value < rhs._value; }
00116 bool operator > ( const Monitor<T>& rhs ) const
00117 { return _value > rhs._value; }
00118 bool operator <= ( const Monitor<T>& rhs ) const
00119 { return _value <= rhs._value; }
00120 bool operator >= ( const Monitor<T>& rhs ) const
00121 { return _value >= rhs._value; }
00123
00127 const T& get() const { return _value; }
00128
00130 T operator + ( const T& value ) const { return _value + value; }
00132
00133 private:
00134 T _value;
00135 MonitorPrivate* _data;
00136
00137 void _construct();
00138 };
00139
00140 typedef Monitor< bool > Monitorb;
00141 typedef Monitor< uint32_t > Monitoru;
00142
00144 template< typename T >
00145 std::ostream& operator << ( std::ostream& os, const Monitor<T>& monitor );
00146 }
00147 }
00148
00149
00150
00151
00152
00153
00154 #ifdef PTHREAD_MUTEX_INITIALIZER
00155 # ifndef HAVE_PTHREAD_H
00156 # define HAVE_PTHREAD_H
00157 # endif
00158 #endif
00159
00160
00161
00162
00163
00164
00165
00166
00167 #ifdef HAVE_PTHREAD_H
00168
00169 #include <eq/base/debug.h>
00170 #include <eq/base/log.h>
00171
00172 namespace eq
00173 {
00174 namespace base
00175 {
00176 class MonitorPrivate
00177 {
00178 public:
00179 pthread_cond_t cond;
00180 pthread_mutex_t mutex;
00181 };
00182
00183 template< typename T >
00184 inline void Monitor<T>::_construct()
00185 {
00186 _data = new MonitorPrivate;
00187
00188 int error = pthread_cond_init( &_data->cond, 0 );
00189 if( error )
00190 {
00191 EQERROR << "Error creating pthread condition: "
00192 << strerror( error ) << std::endl;
00193 return;
00194 }
00195
00196 error = pthread_mutex_init( &_data->mutex, 0 );
00197 if( error )
00198 {
00199 EQERROR << "Error creating pthread mutex: "
00200 << strerror( error ) << std::endl;
00201 return;
00202 }
00203 }
00204
00205 template< typename T >
00206 inline Monitor<T>::~Monitor()
00207 {
00208 pthread_cond_destroy( &_data->cond );
00209 pthread_mutex_destroy( &_data->mutex );
00210 delete _data;
00211 _data = 0;
00212 }
00213
00214 template< typename T >
00215 inline Monitor<T>& Monitor<T>::operator++ ()
00216 {
00217 pthread_mutex_lock( &_data->mutex );
00218 ++_value;
00219 pthread_cond_broadcast( &_data->cond );
00220 pthread_mutex_unlock( &_data->mutex );
00221 return *this;
00222 }
00223
00224 template<>
00225 inline Monitor< bool >& Monitor< bool >::operator++ ()
00226 {
00227 pthread_mutex_lock( &_data->mutex );
00228 assert( !_value );
00229 _value = !_value;
00230 pthread_cond_broadcast( &_data->cond );
00231 pthread_mutex_unlock( &_data->mutex );
00232 return *this;
00233 }
00234
00235 template< typename T >
00236 inline Monitor<T>& Monitor<T>::operator-- ()
00237 {
00238 pthread_mutex_lock( &_data->mutex );
00239 --_value;
00240 pthread_cond_broadcast( &_data->cond );
00241 pthread_mutex_unlock( &_data->mutex );
00242 return *this;
00243 }
00244
00245 template<>
00246 inline Monitor< bool >& Monitor< bool >::operator-- ()
00247 {
00248 EQUNIMPLEMENTED;
00249 return *this;
00250 }
00251
00252 template< typename T >
00253 inline void Monitor<T>::set( const T& value )
00254 {
00255 pthread_mutex_lock( &_data->mutex );
00256 _value = value;
00257 pthread_cond_broadcast( &_data->cond );
00258 pthread_mutex_unlock( &_data->mutex );
00259 }
00260
00261 template< typename T >
00262 inline const T& Monitor<T>::waitEQ( const T& value ) const
00263 {
00264 pthread_mutex_lock( &_data->mutex );
00265 while( _value != value )
00266 pthread_cond_wait( &_data->cond, &_data->mutex);
00267 pthread_mutex_unlock( &_data->mutex );
00268 return value;
00269 }
00270
00271 template< typename T >
00272 inline const T& Monitor<T>::waitNE( const T& value ) const
00273 {
00274 pthread_mutex_lock( &_data->mutex );
00275 while( _value == value )
00276 pthread_cond_wait( &_data->cond, &_data->mutex);
00277 const T& newValue = _value;
00278 pthread_mutex_unlock( &_data->mutex );
00279 return newValue;
00280 }
00281
00282 template< typename T >
00283 inline const T& Monitor<T>::waitGE( const T& value ) const
00284 {
00285 pthread_mutex_lock( &_data->mutex );
00286 while( _value < value )
00287 pthread_cond_wait( &_data->cond, &_data->mutex);
00288 const T& newValue = _value;
00289 pthread_mutex_unlock( &_data->mutex );
00290 return newValue;
00291 }
00292
00293 template< typename T >
00294 inline const T& Monitor<T>::waitLE( const T& value ) const
00295 {
00296 pthread_mutex_lock( &_data->mutex );
00297 while( _value > value )
00298 pthread_cond_wait( &_data->cond, &_data->mutex);
00299 const T& newValue = _value;
00300 pthread_mutex_unlock( &_data->mutex );
00301 return newValue;
00302 }
00303
00304 template< typename T >
00305 std::ostream& operator << ( std::ostream& os, const Monitor<T>& monitor )
00306 {
00307 os << "Monitor< " << monitor.get() << " >";
00308 return os;
00309 }
00310 }
00311 }
00312 #endif // HAVE_PTHREAD_H
00313 #endif //EQBASE_MONITOR_H