LCOV - code coverage report
Current view: top level - lunchbox - mtQueue.h (source / functions) Hit Total Coverage
Test: Lunchbox Lines: 5 5 100.0 %
Date: 2018-10-03 05:33:11 Functions: 5 5 100.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2005-2017, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *                          Daniel Nachbaur <danielnachbaur@gmail.com>
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or modify it under
       6             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       7             :  * by the Free Software Foundation.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      10             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      11             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      12             :  * details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public License
      15             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      16             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      17             :  */
      18             : 
      19             : #ifndef LUNCHBOX_MTQUEUE_H
      20             : #define LUNCHBOX_MTQUEUE_H
      21             : 
      22             : #include <lunchbox/debug.h>
      23             : 
      24             : #include <algorithm>
      25             : #include <condition_variable>
      26             : #include <limits.h>
      27             : #include <mutex>
      28             : #include <queue>
      29             : #include <string.h>
      30             : 
      31             : namespace lunchbox
      32             : {
      33             : /**
      34             :  * A thread-safe queue with a blocking read access.
      35             :  *
      36             :  * Typically used to communicate between two execution threads.
      37             :  *
      38             :  * S is deprecated by the ctor param maxSize, and defines the initial maximum
      39             :  * capacity of the Queue<T>.  When the capacity is reached, pushing new values
      40             :  * blocks until items have been consumed.
      41             :  *
      42             :  * Example: @include tests/mtQueue.cpp
      43             :  */
      44             : template <typename T, size_t S = ULONG_MAX>
      45             : class MTQueue
      46             : // S = std::numeric_limits< size_t >::max() does not work:
      47             : //   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=6424
      48             : {
      49             : public:
      50             :     class Group;
      51             :     typedef T value_type;
      52             : 
      53             :     /** Construct a new queue. @version 1.0 */
      54           2 :     explicit MTQueue(const size_t maxSize = S)
      55           2 :         : _maxSize(maxSize)
      56             :     {
      57           2 :     }
      58             : 
      59             :     /** Construct a copy of a queue. @version 1.0 */
      60             :     MTQueue(const MTQueue<T, S>& from) { *this = from; }
      61             :     /** Destruct this Queue. @version 1.0 */
      62           2 :     ~MTQueue() {}
      63             :     /** Assign the values of another queue. @version 1.0 */
      64             :     MTQueue<T, S>& operator=(const MTQueue<T, S>& from);
      65             : 
      66             :     /**
      67             :      * Retrieve the requested element from the queue, may block.
      68             :      * @version 1.3.2
      69             :      */
      70             :     const T& operator[](const size_t index) const;
      71             : 
      72             :     /** @return true if the queue is empty, false otherwise. @version 1.0 */
      73           5 :     bool isEmpty() const { return _queue.empty(); }
      74             :     /** @return the number of items currently in the queue. @version 1.0 */
      75             :     size_t getSize() const { return _queue.size(); }
      76             :     /**
      77             :      * Set the new maximum size of the queue.
      78             :      *
      79             :      * If the new maximum size is less the current size of the queue, this
      80             :      * call will block until the queue reaches the new maximum size.
      81             :      *
      82             :      * @version 1.3.2
      83             :      */
      84             :     void setMaxSize(const size_t maxSize);
      85             : 
      86             :     /** @return the current maximum size of the queue. @version 1.3.2 */
      87             :     size_t getMaxSize() const { return _maxSize; }
      88             :     /**
      89             :      * Wait for the size to be at least the number of given elements.
      90             :      *
      91             :      * @return the current size when the condition was fulfilled.
      92             :      * @version 1.0
      93             :      */
      94             :     size_t waitSize(const size_t minSize) const;
      95             : 
      96             :     /** Reset (empty) the queue. @version 1.0 */
      97             :     void clear();
      98             : 
      99             :     /**
     100             :      * Retrieve and pop the front element from the queue, may block.
     101             :      * @version 1.0
     102             :      */
     103             :     T pop();
     104             : 
     105             :     /**
     106             :      * Retrieve and pop the front element from the queue.
     107             :      *
     108             :      * @param timeout the timeout
     109             :      * @param element the element returned
     110             :      * @return true if an element was popped
     111             :      * @version 1.1
     112             :      */
     113             :     bool timedPop(const unsigned timeout, T& element);
     114             : 
     115             :     /**
     116             :      * Retrieve a number of items from the front of the queue.
     117             :      *
     118             :      * Between minimum and maximum number of items are returned in a vector. If
     119             :      * the queue has less than minimum number of elements on timeout, the result
     120             :      * vector is empty. The method returns as soon as there are at least minimum
     121             :      * elements available, i.e., it does not wait for the maximum to be reached.
     122             :      *
     123             :      * Note that this method might block up to 'minimum * timeout' milliseconds,
     124             :      * that is, the timeout defines the time to wait for an update on the queue.
     125             :      *
     126             :      * @param timeout the timeout to wait for an update
     127             :      * @param minimum the minimum number of items to retrieve
     128             :      * @param maximum the maximum number of items to retrieve
     129             :      * @return an empty vector on timeout, otherwise the result vector
     130             :      *         containing between minimum and maximum elements.
     131             :      * @version 1.7.0
     132             :      */
     133             :     std::vector<T> timedPopRange(const unsigned timeout,
     134             :                                  const size_t minimum = 1,
     135             :                                  const size_t maximum = S);
     136             : 
     137             :     /**
     138             :      * Retrieve and pop the front element from the queue if it is not empty.
     139             :      *
     140             :      * @param result the front value or unmodified.
     141             :      * @return true if an element was placed in result, false if the queue
     142             :      *         is empty.
     143             :      * @version 1.0
     144             :      */
     145             :     bool tryPop(T& result);
     146             : 
     147             :     /**
     148             :      * Try to retrieve a number of items from the front of the queue.
     149             :      *
     150             :      * Between zero and the given number of items are appended to the vector.
     151             :      *
     152             :      * @param num the maximum number of items to retrieve
     153             :      * @param result the front value or unmodified.
     154             :      * @return true if an element was placed in result, false if the queue
     155             :      *         is empty.
     156             :      * @version 1.1.6
     157             :      */
     158             :     void tryPop(const size_t num, std::vector<T>& result);
     159             : 
     160             :     /**
     161             :      * Retrieve the front element, or abort if the barrier is reached
     162             :      *
     163             :      * Used for worker threads recursively processing data, pushing it back the
     164             :      * queue. Either returns an item from the queue, or aborts if num
     165             :      * participants are waiting in the queue.
     166             :      *
     167             :      * @param result the result element, unmodified on false return value.
     168             :      * @param barrier the group's barrier handle.
     169             :      * @return true if an element was retrieved, false if the barrier height
     170             :      *         was reached.
     171             :      * @version 1.7.1
     172             :      */
     173             :     bool popBarrier(T& result, Group& barrier);
     174             : 
     175             :     /**
     176             :      * @param result the front value or unmodified.
     177             :      * @return true if an element was placed in result, false if the queue
     178             :      *         is empty.
     179             :      * @version 1.0
     180             :      */
     181             :     bool getFront(T& result) const;
     182             : 
     183             :     /**
     184             :      * @param result the last value or unmodified.
     185             :      * @return true if an element was placed in result, false if the queue
     186             :      *         is empty.
     187             :      * @version 1.0
     188             :      */
     189             :     bool getBack(T& result) const;
     190             : 
     191             :     /** Push a new element to the back of the queue. @version 1.0 */
     192             :     void push(const T& element);
     193             : 
     194             :     /** Push a vector of elements to the back of the queue. @version 1.0 */
     195             :     void push(const std::vector<T>& elements);
     196             : 
     197             :     /** Push a new element to the front of the queue. @version 1.0 */
     198             :     void pushFront(const T& element);
     199             : 
     200             :     /** Push a vector of elements to the front of the queue. @version 1.0 */
     201             :     void pushFront(const std::vector<T>& elements);
     202             : 
     203             :     /** @name STL compatibility. @version 1.7.1 */
     204             :     //@{
     205             :     void push_back(const T& element) { push(element); }
     206             :     bool empty() const { return isEmpty(); }
     207             :     //@}
     208             : 
     209             : private:
     210             :     MTQueue(MTQueue<T, S>&&) = delete;
     211             :     MTQueue<T, S>& operator=(MTQueue<T, S>&&) = delete;
     212             : 
     213             :     std::deque<T> _queue;
     214             :     mutable std::mutex _mutex;
     215             :     mutable std::condition_variable _condition;
     216             :     size_t _maxSize;
     217             : };
     218             : }
     219             : 
     220             : #include "mtQueue.ipp" // template implementation
     221             : 
     222             : #endif // LUNCHBOX_MTQUEUE_H

Generated by: LCOV version 1.11