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& );
267 #endif // SGQUEUE_HXX_INCLUDED