From 9442d3d0f31646c93083a9ca5707438b41068155 Mon Sep 17 00:00:00 2001 From: ThorstenB Date: Wed, 8 Jun 2011 23:39:24 +0200 Subject: [PATCH] Added guarded blocking deque class. So, what are we going to do with it... ;-) --- simgear/threads/SGQueue.hxx | 136 ++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/simgear/threads/SGQueue.hxx b/simgear/threads/SGQueue.hxx index 80877375..e7311e56 100644 --- a/simgear/threads/SGQueue.hxx +++ b/simgear/threads/SGQueue.hxx @@ -264,4 +264,140 @@ private: SGBlockingQueue& operator=( const SGBlockingQueue& ); }; + +/** + * A guarded deque blocks threads trying to retrieve items + * when none are available. + */ +template +class SGBlockingDeque +{ +public: + /** + * Create a new SGBlockingDequeue. + */ + SGBlockingDeque() {} + + /** + * Destroy this dequeue. + */ + ~SGBlockingDeque() {} + + /** + * + */ + virtual bool empty() { + OpenThreads::ScopedLock g(mutex); + return this->queue.empty(); + } + + /** + * Add an item to the front of the queue. + * + * @param T object to add. + */ + virtual void push_front( const T& item ) { + OpenThreads::ScopedLock g(mutex); + this->queue.push_front( item ); + not_empty.signal(); + } + + /** + * Add an item to the back of the queue. + * + * @param T object to add. + */ + virtual void push_back( const T& item ) { + OpenThreads::ScopedLock g(mutex); + this->queue.push_back( item ); + not_empty.signal(); + } + + /** + * View the item from the head of the queue. + * Calling thread is not suspended + * + * @return T next available object. + */ + virtual T front() { + OpenThreads::ScopedLock g(mutex); + + assert(this->queue.empty() != true); + //if (queue.empty()) throw ?? + + T item = this->queue.front(); + return item; + } + + /** + * Get an item from the head of the queue. + * If no items are available then the calling thread is suspended + * + * @return T next available object. + */ + virtual T pop_front() { + OpenThreads::ScopedLock g(mutex); + + while (this->queue.empty()) + not_empty.wait(&mutex); + + assert(this->queue.empty() != true); + //if (queue.empty()) throw ?? + + T item = this->queue.front(); + this->queue.pop_front(); + return item; + } + + /** + * Get an item from the tail of the queue. + * If no items are available then the calling thread is suspended + * + * @return T next available object. + */ + virtual T pop_back() { + OpenThreads::ScopedLock g(mutex); + + while (this->queue.empty()) + not_empty.wait(&mutex); + + assert(this->queue.empty() != true); + //if (queue.empty()) throw ?? + + T item = this->queue.back(); + this->queue.pop_back(); + return item; + } + + /** + * Query the size of the queue + * + * @return size_t size of queue. + */ + virtual size_t size() { + OpenThreads::ScopedLock g(mutex); + return this->queue.size(); + } + +private: + + /** + * Mutex to serialise access. + */ + OpenThreads::Mutex mutex; + + /** + * Condition to signal when queue not empty. + */ + OpenThreads::Condition not_empty; + +private: + // Prevent copying. + SGBlockingDeque( const SGBlockingDeque& ); + SGBlockingDeque& operator=( const SGBlockingDeque& ); + +protected: + std::deque queue; +}; + #endif // SGQUEUE_HXX_INCLUDED -- 2.39.5