1 #ifndef SGQUEUE_HXX_INCLUDED
2 #define SGQUEUE_HXX_INCLUDED 1
4 #include <simgear/compiler.h>
8 #include <OpenThreads/Mutex>
9 #include <OpenThreads/ScopedLock>
10 #include <OpenThreads/Condition>
13 * SGQueue defines an interface for a FIFO.
14 * It can be implemented using different types of synchronization
23 * Create a new SGQueue object.
28 * Destroy this object.
33 * Returns whether this queue is empty (contains no elements).
35 * @return bool True if queue is empty, otherwisr false.
37 virtual bool empty() = 0;
40 * Add an item to the end of the queue.
42 * @param T object to add.
44 virtual void push( const T& item ) = 0;
47 * View the item from the head of the queue.
49 * @return T next available object.
51 virtual T front() = 0;
54 * Get an item from the head of the queue.
56 * @return T next available object.
61 * Query the size of the queue
63 * @return size_t size of queue.
65 virtual size_t size() = 0;
75 * A simple thread safe queue. All access functions are guarded with a mutex.
77 template<class T, class SGLOCK=OpenThreads::Mutex>
78 class SGLockedQueue : public SGQueue<T>
83 * Create a new SGLockedQueue object.
88 * Destroy this object.
93 * Returns whether this queue is empty (contains no elements).
95 * @return bool True if queue is empty, otherwisr false.
97 virtual bool empty() {
98 OpenThreads::ScopedLock<SGLOCK> g(mutex);
99 return this->fifo.empty();
103 * Add an item to the end of the queue.
105 * @param T object to add.
107 virtual void push( const T& item ) {
108 OpenThreads::ScopedLock<SGLOCK> g(mutex);
109 this->fifo.push( item );
113 * View the item from the head of the queue.
115 * @return T next available object.
118 OpenThreads::ScopedLock<SGLOCK> g(mutex);
119 assert( ! this->fifo.empty() );
120 T item = this->fifo.front();
125 * Get an item from the head of the queue.
127 * @return T next available object.
130 OpenThreads::ScopedLock<SGLOCK> g(mutex);
131 //if (fifo.empty()) throw NoSuchElementException();
132 assert( ! this->fifo.empty() );
136 // pthread_exit( PTHREAD_CANCELED );
138 T item = this->fifo.front();
144 * Query the size of the queue
146 * @return size_t size of queue.
148 virtual size_t size() {
149 OpenThreads::ScopedLock<SGLOCK> g(mutex);
150 return this->fifo.size();
156 * Mutex to serialise access.
162 SGLockedQueue(const SGLockedQueue&);
163 SGLockedQueue& operator= (const SGLockedQueue&);
167 * A guarded queue blocks threads trying to retrieve items
168 * when none are available.
171 class SGBlockingQueue : public SGQueue<T>
175 * Create a new SGBlockingQueue.
180 * Destroy this queue.
182 ~SGBlockingQueue() {}
187 virtual bool empty() {
188 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
189 return this->fifo.empty();
193 * Add an item to the end of the queue.
195 * @param T object to add.
197 virtual void push( const T& item ) {
198 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
199 this->fifo.push( item );
204 * View the item from the head of the queue.
205 * Calling thread is not suspended
207 * @return T next available object.
210 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
212 assert(this->fifo.empty() != true);
213 //if (fifo.empty()) throw ??
215 T item = this->fifo.front();
220 * Get an item from the head of the queue.
221 * If no items are available then the calling thread is suspended
223 * @return T next available object.
226 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
228 while (this->fifo.empty())
229 not_empty.wait(&mutex);
231 assert(this->fifo.empty() != true);
232 //if (fifo.empty()) throw ??
234 T item = this->fifo.front();
240 * Query the size of the queue
242 * @return size_t size of queue.
244 virtual size_t size() {
245 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
246 return this->fifo.size();
252 * Mutex to serialise access.
254 OpenThreads::Mutex mutex;
257 * Condition to signal when queue not empty.
259 OpenThreads::Condition not_empty;
263 SGBlockingQueue( const SGBlockingQueue& );
264 SGBlockingQueue& operator=( const SGBlockingQueue& );
269 * A guarded deque blocks threads trying to retrieve items
270 * when none are available.
273 class SGBlockingDeque
277 * Create a new SGBlockingDequeue.
282 * Destroy this dequeue.
284 ~SGBlockingDeque() {}
289 virtual void clear() {
290 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
297 virtual bool empty() {
298 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
299 return this->queue.empty();
303 * Add an item to the front of the queue.
305 * @param T object to add.
307 virtual void push_front( const T& item ) {
308 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
309 this->queue.push_front( item );
314 * Add an item to the back of the queue.
316 * @param T object to add.
318 virtual void push_back( const T& item ) {
319 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
320 this->queue.push_back( item );
325 * View the item from the head of the queue.
326 * Calling thread is not suspended
328 * @return T next available object.
331 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
333 assert(this->queue.empty() != true);
334 //if (queue.empty()) throw ??
336 T item = this->queue.front();
341 * Get an item from the head of the queue.
342 * If no items are available then the calling thread is suspended
344 * @return T next available object.
346 virtual T pop_front() {
347 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
349 while (this->queue.empty())
350 not_empty.wait(&mutex);
352 assert(this->queue.empty() != true);
353 //if (queue.empty()) throw ??
355 T item = this->queue.front();
356 this->queue.pop_front();
361 * Get an item from the tail of the queue.
362 * If no items are available then the calling thread is suspended
364 * @return T next available object.
366 virtual T pop_back() {
367 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
369 while (this->queue.empty())
370 not_empty.wait(&mutex);
372 assert(this->queue.empty() != true);
373 //if (queue.empty()) throw ??
375 T item = this->queue.back();
376 this->queue.pop_back();
381 * Query the size of the queue
383 * @return size_t size of queue.
385 virtual size_t size() {
386 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
387 return this->queue.size();
393 * Mutex to serialise access.
395 OpenThreads::Mutex mutex;
398 * Condition to signal when queue not empty.
400 OpenThreads::Condition not_empty;
404 SGBlockingDeque( const SGBlockingDeque& );
405 SGBlockingDeque& operator=( const SGBlockingDeque& );
411 #endif // SGQUEUE_HXX_INCLUDED