00001 #ifndef SGQUEUE_HXX_INCLUDED
00002 #define SGQUEUE_HXX_INCLUDED 1
00003
00004 #include <simgear/compiler.h>
00005
00006 #include <cassert>
00007 #include <queue>
00008 #include <OpenThreads/Mutex>
00009 #include <OpenThreads/ScopedLock>
00010 #include <OpenThreads/Condition>
00011
00017 template<class T>
00018 class SGQueue
00019 {
00020 public:
00021
00025 SGQueue() {}
00026
00030 virtual ~SGQueue() {}
00031
00037 virtual bool empty() = 0;
00038
00044 virtual void push( const T& item ) = 0;
00045
00051 virtual T front() = 0;
00052
00058 virtual T pop() = 0;
00059
00065 virtual size_t size() = 0;
00066
00067 protected:
00071 std::queue<T> fifo;
00072 };
00073
00077 template<class T, class SGLOCK=OpenThreads::Mutex>
00078 class SGLockedQueue : public SGQueue<T>
00079 {
00080 public:
00081
00085 SGLockedQueue() {}
00086
00090 ~SGLockedQueue() {}
00091
00097 virtual bool empty() {
00098 OpenThreads::ScopedLock<SGLOCK> g(mutex);
00099 return this->fifo.empty();
00100 }
00101
00107 virtual void push( const T& item ) {
00108 OpenThreads::ScopedLock<SGLOCK> g(mutex);
00109 this->fifo.push( item );
00110 }
00111
00117 virtual T front() {
00118 OpenThreads::ScopedLock<SGLOCK> g(mutex);
00119 assert( ! this->fifo.empty() );
00120 T item = this->fifo.front();
00121 return item;
00122 }
00123
00129 virtual T pop() {
00130 OpenThreads::ScopedLock<SGLOCK> g(mutex);
00131
00132 assert( ! this->fifo.empty() );
00133
00134
00135
00136
00137
00138 T item = this->fifo.front();
00139 this->fifo.pop();
00140 return item;
00141 }
00142
00148 virtual size_t size() {
00149 OpenThreads::ScopedLock<SGLOCK> g(mutex);
00150 return this->fifo.size();
00151 }
00152
00153 private:
00154
00158 SGLOCK mutex;
00159
00160 private:
00161
00162 SGLockedQueue(const SGLockedQueue&);
00163 SGLockedQueue& operator= (const SGLockedQueue&);
00164 };
00165
00170 template<class T>
00171 class SGBlockingQueue : public SGQueue<T>
00172 {
00173 public:
00177 SGBlockingQueue() {}
00178
00182 ~SGBlockingQueue() {}
00183
00187 virtual bool empty() {
00188 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
00189 return this->fifo.empty();
00190 }
00191
00197 virtual void push( const T& item ) {
00198 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
00199 this->fifo.push( item );
00200 not_empty.signal();
00201 }
00202
00209 virtual T front() {
00210 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
00211
00212 assert(this->fifo.empty() != true);
00213
00214
00215 T item = this->fifo.front();
00216 return item;
00217 }
00218
00225 virtual T pop() {
00226 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
00227
00228 while (this->fifo.empty())
00229 not_empty.wait(&mutex);
00230
00231 assert(this->fifo.empty() != true);
00232
00233
00234 T item = this->fifo.front();
00235 this->fifo.pop();
00236 return item;
00237 }
00238
00244 virtual size_t size() {
00245 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
00246 return this->fifo.size();
00247 }
00248
00249 private:
00250
00254 OpenThreads::Mutex mutex;
00255
00259 OpenThreads::Condition not_empty;
00260
00261 private:
00262
00263 SGBlockingQueue( const SGBlockingQueue& );
00264 SGBlockingQueue& operator=( const SGBlockingQueue& );
00265 };
00266
00267 #endif // SGQUEUE_HXX_INCLUDED