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 bool empty() {
290 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
291 return this->queue.empty();
295 * Add an item to the front of the queue.
297 * @param T object to add.
299 virtual void push_front( const T& item ) {
300 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
301 this->queue.push_front( item );
306 * Add an item to the back of the queue.
308 * @param T object to add.
310 virtual void push_back( const T& item ) {
311 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
312 this->queue.push_back( item );
317 * View the item from the head of the queue.
318 * Calling thread is not suspended
320 * @return T next available object.
323 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
325 assert(this->queue.empty() != true);
326 //if (queue.empty()) throw ??
328 T item = this->queue.front();
333 * Get an item from the head of the queue.
334 * If no items are available then the calling thread is suspended
336 * @return T next available object.
338 virtual T pop_front() {
339 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
341 while (this->queue.empty())
342 not_empty.wait(&mutex);
344 assert(this->queue.empty() != true);
345 //if (queue.empty()) throw ??
347 T item = this->queue.front();
348 this->queue.pop_front();
353 * Get an item from the tail of the queue.
354 * If no items are available then the calling thread is suspended
356 * @return T next available object.
358 virtual T pop_back() {
359 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
361 while (this->queue.empty())
362 not_empty.wait(&mutex);
364 assert(this->queue.empty() != true);
365 //if (queue.empty()) throw ??
367 T item = this->queue.back();
368 this->queue.pop_back();
373 * Query the size of the queue
375 * @return size_t size of queue.
377 virtual size_t size() {
378 OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
379 return this->queue.size();
385 * Mutex to serialise access.
387 OpenThreads::Mutex mutex;
390 * Condition to signal when queue not empty.
392 OpenThreads::Condition not_empty;
396 SGBlockingDeque( const SGBlockingDeque& );
397 SGBlockingDeque& operator=( const SGBlockingDeque& );
403 #endif // SGQUEUE_HXX_INCLUDED