1 #ifndef SGQUEUE_HXX_INCLUDED
2 #define SGQUEUE_HXX_INCLUDED 1
4 #include <simgear/compiler.h>
6 #if defined ( SG_HAVE_STD_INCLUDES )
13 #include "SGThread.hxx"
14 #include "SGGuard.hxx"
17 * SGQueue defines an interface for a FIFO.
18 * It can be implemented using different types of synchronization
27 * Create a new SGQueue object.
32 * Destroy this object.
37 * Returns whether this queue is empty (contains no elements).
39 * @return bool True if queue is empty, otherwisr false.
41 virtual bool empty() = 0;
44 * Add an item to the end of the queue.
46 * @param T object to add.
48 virtual void push( const T& item ) = 0;
51 * View the item from the head of the queue.
53 * @return T next available object.
55 virtual T front() = 0;
58 * Get an item from the head of the queue.
60 * @return T next available object.
72 * A simple thread safe queue. All access functions are guarded with a mutex.
74 template<class T, class SGLOCK=SGMutex>
75 class SGLockedQueue : public SGQueue<T>
80 * Create a new SGLockedQueue object.
85 * Destroy this object.
90 * Returns whether this queue is empty (contains no elements).
92 * @return bool True if queue is empty, otherwisr false.
94 virtual bool empty() {
95 SGGuard<SGLOCK> g(mutex);
96 return this->fifo.empty();
100 * Add an item to the end of the queue.
102 * @param T object to add.
104 virtual void push( const T& item ) {
105 SGGuard<SGLOCK> g(mutex);
106 this->fifo.push( item );
110 * View the item from the head of the queue.
112 * @return T next available object.
115 SGGuard<SGLOCK> g(mutex);
116 assert( ! this->fifo.empty() );
117 T item = this->fifo.front();
122 * Get an item from the head of the queue.
124 * @return T next available object.
127 SGGuard<SGLOCK> g(mutex);
128 //if (fifo.empty()) throw NoSuchElementException();
129 assert( ! this->fifo.empty() );
133 // pthread_exit( PTHREAD_CANCELED );
135 T item = this->fifo.front();
142 * Mutex to serialise access.
148 SGLockedQueue(const SGLockedQueue&);
149 SGLockedQueue& operator= (const SGLockedQueue&);
153 * A guarded queue blocks threads trying to retrieve items
154 * when none are available.
157 class SGBlockingQueue : public SGQueue<T>
161 * Create a new SGBlockingQueue.
166 * Destroy this queue.
168 ~SGBlockingQueue() { mutex.unlock(); }
173 virtual bool empty() {
174 SGGuard<SGMutex> g(mutex);
175 return this->fifo.empty();
179 * Add an item to the end of the queue.
181 * @param T object to add.
183 virtual void push( const T& item ) {
184 SGGuard<SGMutex> g(mutex);
185 this->fifo.push( item );
190 * View the item from the head of the queue.
191 * Calling thread is not suspended
193 * @return T next available object.
196 SGGuard<SGMutex> g(mutex);
198 assert(this->fifo.empty() != true);
199 //if (fifo.empty()) throw ??
201 T item = this->fifo.front();
206 * Get an item from the head of the queue.
207 * If no items are available then the calling thread is suspended
209 * @return T next available object.
212 SGGuard<SGMutex> g(mutex);
214 while (this->fifo.empty())
215 not_empty.wait(mutex);
217 assert(this->fifo.empty() != true);
218 //if (fifo.empty()) throw ??
220 T item = this->fifo.front();
228 * Mutex to serialise access.
233 * Condition to signal when queue not empty.
235 SGPthreadCond not_empty;
239 SGBlockingQueue( const SGBlockingQueue& );
240 SGBlockingQueue& operator=( const SGBlockingQueue& );
243 #endif // SGQUEUE_HXX_INCLUDED