]> git.mxchange.org Git - simgear.git/blobdiff - simgear/threads/SGQueue.hxx
Merge branch 'next' of git://gitorious.org/fg/simgear into next
[simgear.git] / simgear / threads / SGQueue.hxx
index 80877375e96fa391c57c449e54aa1d670d73ad4e..bcdda1d35fad5f52650671908c392ea62144f119 100644 (file)
@@ -264,4 +264,148 @@ 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 void clear() {
+    OpenThreads::ScopedLock<OpenThreads::Mutex> g(mutex);
+    this->queue.clear();
+    }
+    
+    /**
+     * 
+     */
+    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