From: <sv...@ww...> - 2004-06-27 08:14:28
|
Author: mkrose Date: 2004-06-27 01:14:22 -0700 (Sun, 27 Jun 2004) New Revision: 1075 Modified: trunk/CSP/SimData/CHANGES.current trunk/CSP/SimData/Include/SimData/ThreadQueue.h Log: Added doxygen comments to ThreadQueue.h, and generalized ThreadSafePriorityQueue to support all the template parameters of std::priority_queue. Browse at: https://www.zerobar.net/viewcvs/viewcvs.cgi?view=rev&rev=1075 Modified: trunk/CSP/SimData/CHANGES.current =================================================================== --- trunk/CSP/SimData/CHANGES.current 2004-06-27 07:56:34 UTC (rev 1074) +++ trunk/CSP/SimData/CHANGES.current 2004-06-27 08:14:22 UTC (rev 1075) @@ -26,6 +26,10 @@ * Add doxygen comments to ThreadLog.h + * Added doxygen comments to ThreadQueue.h, and generalized + ThreadSafePriorityQueue to support all the template parameters + of std::priority_queue. + 2004-06-22: onsight * Added a ScopedUnlock (trivial reversal of ScopedLock) Modified: trunk/CSP/SimData/Include/SimData/ThreadQueue.h =================================================================== --- trunk/CSP/SimData/Include/SimData/ThreadQueue.h 2004-06-27 07:56:34 UTC (rev 1074) +++ trunk/CSP/SimData/Include/SimData/ThreadQueue.h 2004-06-27 08:14:22 UTC (rev 1075) @@ -47,11 +47,29 @@ class ThreadSafeQueueBase: public NonCopyable { public: typedef TYPE ValueType; + + /** Exception class used to signal that the queue is full. + */ class Full: public std::exception { }; + + /** Exception class used to signal that the queue is empty. + */ class Empty: public std::exception { }; + + /** Return the number of elements in the queue. + */ virtual int size() const = 0; + + /** Test if the queue is empty. + */ bool empty() const { return size() == 0; } + + /** Test if the queue is full. + */ bool full() const { return m_maxsize > 0 && size() >= m_maxsize; } + + /** Put an element into the queue. + */ void put(TYPE item, bool block = true) { m_notFull.lock(); while (full()) { @@ -65,6 +83,14 @@ m_notFull.unlock(); m_notEmpty.signal(); } + + /** Retrieve (and remove) the element at the front of the queue. + * + * @param item (output) item retrieved from the queue. + * @param block if true, this method will wait until an element is + * available; otherwise it will return immediately. + * @return true if an item was retrieved, false otherwise. + */ bool get(TYPE &item, bool block = true) { m_notEmpty.lock(); while (empty()) { @@ -79,6 +105,14 @@ m_notFull.signal(); return true; } + + /** Retrieve (and remove) the element at the front of the queue. + * + * @param item (output) item retrieved from the queue. + * @param timeout the maximum time (in seconds) to wait for an item to + * retrieve. + * @return true if an item was retrieved, false otherwise. + */ bool get(TYPE &item, double timeout) { m_notEmpty.lock(); while (empty()) { @@ -92,12 +126,27 @@ m_notFull.signal(); return true; } + protected: + /** Construtor. + * + * @param maxsize the upper limit on the size of the queue; or zero for no limit. + */ ThreadSafeQueueBase(int maxsize) : m_mutex(), m_notEmpty(m_mutex), m_notFull(m_mutex), m_maxsize(maxsize) {} + + /** Destructor. + */ virtual ~ThreadSafeQueueBase() { } + + /** Add an item to the queue. + */ virtual void pushItem(TYPE &item) = 0; + + /** Retrieve and remove an item from the queue. + */ virtual TYPE popItem() = 0; + private: ThreadMutex m_mutex; ThreadCondition m_notEmpty; @@ -111,18 +160,32 @@ template <typename TYPE> class ThreadSafeQueue: public ThreadSafeQueueBase<TYPE> { public: + /** Create a new thread-safe queue. + * + * @param maxsize the upper limit on the size of the queue; or zero for no limit. + */ ThreadSafeQueue(int maxsize = 0): ThreadSafeQueueBase<TYPE>(maxsize) {} + + /** Return the number of elements in the queue. + */ virtual int size() const { return m_queue.size(); } + protected: + /** Add an item to the bottom of the queue. + */ virtual void pushItem(TYPE &item) { m_queue.push(item); } + + /** Retrieve and remove an item from the top of the queue. + */ virtual TYPE popItem() { assert(size() > 0); TYPE item = m_queue.front(); m_queue.pop(); return item; } + private: std::queue<TYPE> m_queue; }; @@ -130,23 +193,38 @@ /** A thread-safe priority queue that supports multiple producers and consumers. */ -template <typename TYPE> +template <typename TYPE, typename SEQUENCE = std::vector<TYPE>, + typename COMPARE = std::less<typename SEQUENCE::value_type> > class ThreadSafePriorityQueue: public ThreadSafeQueueBase<TYPE> { public: + /** Create a new thread-safe priority queue. + * + * @param maxsize the upper limit on the size of the queue; or zero for no limit. + */ ThreadSafePriorityQueue(int maxsize = 0): ThreadSafeQueueBase<TYPE>(maxsize) {} + + /** Return the number of elements in the queue. + */ virtual int size() const { return m_queue.size(); } + protected: + /** Add an item to the bottom of the queue. + */ virtual void pushItem(TYPE &item) { m_queue.push(item); } + + /** Retrieve and remove an item from the top of the queue. + */ virtual TYPE popItem() { assert(size() > 0); TYPE item = m_queue.front(); m_queue.pop(); return item; } + private: - std::priority_queue<TYPE> m_queue; + std::priority_queue<TYPE, SEQUENCE, COMPARE> m_queue; }; |