mtQueue.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef EQBASE_MTQUEUE_H
00019 #define EQBASE_MTQUEUE_H
00020
00021 #include <eq/base/base.h>
00022 #include <eq/base/debug.h>
00023 #include <queue>
00024
00025 #include <string.h>
00026
00027 namespace eq
00028 {
00029 namespace base
00030 {
00031 class MTQueuePrivate;
00032
00037 template< typename T > class MTQueue
00038 {
00039 public:
00041 MTQueue();
00042
00044 MTQueue( const MTQueue< T >& from );
00045
00047 ~MTQueue();
00048
00050 MTQueue< T >& operator = ( const MTQueue< T >& from );
00051
00053 bool isEmpty() const { return _queue.empty(); }
00054
00056 size_t getSize() const { return _queue.size(); }
00057
00059 T pop();
00060
00065 T tryPop();
00066
00071 T back() const;
00072
00074 void push( const T& element );
00075
00077 void pushFront( const T& element );
00078
00080 static const T NONE;
00081
00082 private:
00083 std::deque< T > _queue;
00084 MTQueuePrivate* _data;
00085
00086 void _init();
00087 };
00088
00089
00090
00091
00092
00093
00094 #ifdef PTHREAD_MUTEX_INITIALIZER
00095 # ifndef HAVE_PTHREAD_H
00096 # define HAVE_PTHREAD_H
00097 # endif
00098 #endif
00099
00100
00101
00102
00103
00104 #ifdef HAVE_PTHREAD_H
00105
00106 class MTQueuePrivate
00107 {
00108 public:
00109 pthread_mutex_t mutex;
00110 pthread_cond_t cond;
00111 };
00112
00113 template< typename T > const T MTQueue<T>::NONE = 0;
00114
00115 template< typename T >
00116 MTQueue<T>::MTQueue()
00117 : _data( new MTQueuePrivate )
00118 {
00119 _init();
00120 }
00121
00122 template< typename T >
00123 MTQueue< T >::MTQueue( const MTQueue< T >& from )
00124 : _queue( from._queue )
00125 , _data( new MTQueuePrivate )
00126 {
00127 _init();
00128 }
00129
00130 template< typename T >
00131 void MTQueue< T >::_init()
00132 {
00133
00134 int error = pthread_mutex_init( &_data->mutex, 0 );
00135 if( error )
00136 {
00137 EQERROR << "Error creating pthread mutex: "
00138 << strerror( error ) << std::endl;
00139 return;
00140 }
00141
00142 error = pthread_cond_init( &_data->cond, 0 );
00143 if( error )
00144 {
00145 EQERROR << "Error creating pthread condition: "
00146 << strerror( error ) << std::endl;
00147 return;
00148 }
00149 }
00150
00151 template< typename T >
00152 MTQueue< T >& MTQueue< T >::operator = ( const MTQueue< T >& from )
00153 {
00154 pthread_mutex_lock( &_data->mutex );
00155 _queue = from._queue;
00156 pthread_cond_signal( &_data->cond );
00157 pthread_mutex_unlock( &_data->mutex );
00158 return *this;
00159 }
00160
00161
00162 template< typename T >
00163 MTQueue<T>::~MTQueue()
00164 {
00165 pthread_mutex_destroy( &_data->mutex );
00166 pthread_cond_destroy( &_data->cond );
00167 delete _data;
00168 _data = 0;
00169 }
00170
00171 template< typename T >
00172 T MTQueue<T>::pop()
00173 {
00174 pthread_mutex_lock( &_data->mutex );
00175 while( _queue.empty( ))
00176 pthread_cond_wait( &_data->cond, &_data->mutex );
00177
00178 EQASSERT( !_queue.empty( ));
00179 T element = _queue.front();
00180 _queue.pop_front();
00181 pthread_mutex_unlock( &_data->mutex );
00182 return element;
00183 }
00184
00185 template< typename T >
00186 T MTQueue<T>::tryPop()
00187 {
00188 if( _queue.empty( ))
00189 return NONE;
00190
00191 pthread_mutex_lock( &_data->mutex );
00192 if( _queue.empty( ))
00193 {
00194 pthread_mutex_unlock( &_data->mutex );
00195 return NONE;
00196 }
00197
00198 T element = _queue.front();
00199 _queue.pop_front();
00200 pthread_mutex_unlock( &_data->mutex );
00201 return element;
00202 }
00203
00204 template< typename T >
00205 T MTQueue<T>::back() const
00206 {
00207 pthread_mutex_lock( &_data->mutex );
00208 if( _queue.empty( ))
00209 {
00210 pthread_mutex_unlock( &_data->mutex );
00211 return NONE;
00212 }
00213
00214 T element = _queue.back();
00215 pthread_mutex_unlock( &_data->mutex );
00216 return element;
00217 }
00218
00219 template< typename T >
00220 void MTQueue<T>::push( const T& element )
00221 {
00222 pthread_mutex_lock( &_data->mutex );
00223 _queue.push_back( element );
00224 pthread_cond_signal( &_data->cond );
00225 pthread_mutex_unlock( &_data->mutex );
00226 }
00227
00228 template< typename T >
00229 void MTQueue<T>::pushFront( const T& element )
00230 {
00231 pthread_mutex_lock( &_data->mutex );
00232 _queue.push_front( element );
00233 pthread_cond_signal( &_data->cond );
00234 pthread_mutex_unlock( &_data->mutex );
00235 }
00236 #endif //HAVE_PTHREAD_H
00237 }
00238
00239 }
00240 #endif //EQBASE_MTQUEUE_H