Added guarded blocking deque class.
So, what are we going to do with it... ;-)
This commit is contained in:
@@ -264,4 +264,140 @@ private:
|
||||
SGBlockingQueue& operator=( const SGBlockingQueue& );
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A guarded deque blocks threads trying to retrieve items
|
||||
* when none are available.
|
||||
*/
|
||||
template<class T>
|
||||
class SGBlockingDeque
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a new SGBlockingDequeue.
|
||||
*/
|
||||
SGBlockingDeque() {}
|
||||
|
||||
/**
|
||||
* Destroy this dequeue.
|
||||
*/
|
||||
~SGBlockingDeque() {}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
virtual bool empty() {
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> 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<OpenThreads::Mutex> 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<OpenThreads::Mutex> 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<OpenThreads::Mutex> 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<OpenThreads::Mutex> 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<OpenThreads::Mutex> 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<OpenThreads::Mutex> 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<T> queue;
|
||||
};
|
||||
|
||||
#endif // SGQUEUE_HXX_INCLUDED
|
||||
|
||||
Reference in New Issue
Block a user