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.
65 * Query the size of the queue
67 * @return size_t size of queue.
69 virtual size_t size() = 0;
79 * A simple thread safe queue. All access functions are guarded with a mutex.
81 template<class T, class SGLOCK=SGMutex>
82 class SGLockedQueue : public SGQueue<T>
87 * Create a new SGLockedQueue object.
92 * Destroy this object.
97 * Returns whether this queue is empty (contains no elements).
99 * @return bool True if queue is empty, otherwisr false.
101 virtual bool empty() {
102 SGGuard<SGLOCK> g(mutex);
103 return this->fifo.empty();
107 * Add an item to the end of the queue.
109 * @param T object to add.
111 virtual void push( const T& item ) {
112 SGGuard<SGLOCK> g(mutex);
113 this->fifo.push( item );
117 * View the item from the head of the queue.
119 * @return T next available object.
122 SGGuard<SGLOCK> g(mutex);
123 assert( ! this->fifo.empty() );
124 T item = this->fifo.front();
129 * Get an item from the head of the queue.
131 * @return T next available object.
134 SGGuard<SGLOCK> g(mutex);
135 //if (fifo.empty()) throw NoSuchElementException();
136 assert( ! this->fifo.empty() );
140 // pthread_exit( PTHREAD_CANCELED );
142 T item = this->fifo.front();
148 * Query the size of the queue
150 * @return size_t size of queue.
152 virtual size_t size() {
153 SGGuard<SGLOCK> g(mutex);
154 return this->fifo.size();
160 * Mutex to serialise access.
166 SGLockedQueue(const SGLockedQueue&);
167 SGLockedQueue& operator= (const SGLockedQueue&);
171 * A guarded queue blocks threads trying to retrieve items
172 * when none are available.
175 class SGBlockingQueue : public SGQueue<T>
179 * Create a new SGBlockingQueue.
184 * Destroy this queue.
186 ~SGBlockingQueue() {}
191 virtual bool empty() {
192 SGGuard<SGMutex> g(mutex);
193 return this->fifo.empty();
197 * Add an item to the end of the queue.
199 * @param T object to add.
201 virtual void push( const T& item ) {
202 SGGuard<SGMutex> g(mutex);
203 this->fifo.push( item );
208 * View the item from the head of the queue.
209 * Calling thread is not suspended
211 * @return T next available object.
214 SGGuard<SGMutex> g(mutex);
216 assert(this->fifo.empty() != true);
217 //if (fifo.empty()) throw ??
219 T item = this->fifo.front();
224 * Get an item from the head of the queue.
225 * If no items are available then the calling thread is suspended
227 * @return T next available object.
230 SGGuard<SGMutex> g(mutex);
232 while (this->fifo.empty())
233 not_empty.wait(mutex);
235 assert(this->fifo.empty() != true);
236 //if (fifo.empty()) throw ??
238 T item = this->fifo.front();
244 * Query the size of the queue
246 * @return size_t size of queue.
248 virtual size_t size() {
249 SGGuard<SGMutex> g(mutex);
250 return this->fifo.size();
256 * Mutex to serialise access.
261 * Condition to signal when queue not empty.
263 SGPthreadCond not_empty;
267 SGBlockingQueue( const SGBlockingQueue& );
268 SGBlockingQueue& operator=( const SGBlockingQueue& );
271 #endif // SGQUEUE_HXX_INCLUDED