diff options
Diffstat (limited to 'src/base/Queue.h')
-rw-r--r-- | src/base/Queue.h | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/src/base/Queue.h b/src/base/Queue.h new file mode 100644 index 0000000..36a0eba --- /dev/null +++ b/src/base/Queue.h @@ -0,0 +1,160 @@ +// +// libavg - Media Playback Engine. +// Copyright (C) 2003-2014 Ulrich von Zadow +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// Current versions can be found at www.libavg.de +// + +#ifndef _Queue_H_ +#define _Queue_H_ + +#include "../api.h" +#include "Exception.h" + +#include <boost/thread/mutex.hpp> +#include <boost/thread/condition.hpp> +#include <boost/shared_ptr.hpp> + +#include <deque> +#include <iostream> + +namespace avg { + +typedef boost::unique_lock<boost::mutex> unique_lock; + +template<class QElement> +class AVG_TEMPLATE_API Queue +{ +public: + typedef boost::shared_ptr<QElement> QElementPtr; + + Queue(int maxSize=-1); + virtual ~Queue(); + + bool empty() const; + QElementPtr pop(bool bBlock = true); + void clear(); + void push(const QElementPtr& pElem); + QElementPtr peek(bool bBlock = true) const; + int size() const; + int getMaxSize() const; + +private: + QElementPtr getFrontElement(bool bBlock, unique_lock& Lock) const; + + std::deque<QElementPtr> m_pElements; + mutable boost::mutex m_Mutex; + mutable boost::condition m_Cond; + int m_MaxSize; +}; + +template<class QElement> +Queue<QElement>::Queue(int maxSize) + : m_MaxSize(maxSize) +{ +} + +template<class QElement> +Queue<QElement>::~Queue() +{ +} + +template<class QElement> +bool Queue<QElement>::empty() const +{ + unique_lock Lock(m_Mutex); + return m_pElements.empty(); +} + +template<class QElement> +typename Queue<QElement>::QElementPtr Queue<QElement>::pop(bool bBlock) +{ + unique_lock lock(m_Mutex); + QElementPtr pElem = getFrontElement(bBlock, lock); + if (pElem) { + m_pElements.pop_front(); + m_Cond.notify_one(); + } + return pElem; +} + +template<class QElement> +void Queue<QElement>::clear() +{ + QElementPtr pElem; + do { + pElem = pop(false); + } while (pElem); +} + +template<class QElement> +typename Queue<QElement>::QElementPtr Queue<QElement>::peek(bool bBlock) const +{ + unique_lock lock(m_Mutex); + QElementPtr pElem = getFrontElement(bBlock, lock); + if (pElem) { + m_Cond.notify_one(); + } + return pElem; +} + +template<class QElement> +void Queue<QElement>::push(const QElementPtr& pElem) +{ + assert(pElem); + unique_lock lock(m_Mutex); + if (m_pElements.size() == (unsigned)m_MaxSize) { + while (m_pElements.size() == (unsigned)m_MaxSize) { + m_Cond.wait(lock); + } + } + m_pElements.push_back(pElem); + m_Cond.notify_one(); +} + +template<class QElement> +int Queue<QElement>::size() const +{ + unique_lock lock(m_Mutex); + return int(m_pElements.size()); +} + +template<class QElement> +int Queue<QElement>::getMaxSize() const +{ + unique_lock lock(m_Mutex); + return m_MaxSize; +} + +template<class QElement> +typename Queue<QElement>::QElementPtr + Queue<QElement>::getFrontElement(bool bBlock, unique_lock& lock) const +{ + if (m_pElements.empty()) { + if (bBlock) { + while (m_pElements.empty()) { + m_Cond.wait(lock); + } + } else { + return QElementPtr(); + } + } + return m_pElements.front(); +} + +} +#endif |