yat/utility/Queue.h

Code
Comments
Other
Rev Date Author Line
3057 01 Jul 13 peter 1 #ifndef theplu_yat_utility_queue
3057 01 Jul 13 peter 2 #define theplu_yat_utility_queue
3057 01 Jul 13 peter 3
3057 01 Jul 13 peter 4 // $Id$
3057 01 Jul 13 peter 5
4346 24 Apr 23 peter 6 /*
4346 24 Apr 23 peter 7   Copyright (C) 2013, 2014, 2016, 2017, 2018, 2020, 2023 Peter Johansson
4346 24 Apr 23 peter 8
4346 24 Apr 23 peter 9   This file is part of the yat library, https://dev.thep.lu.se/yat
4346 24 Apr 23 peter 10
4346 24 Apr 23 peter 11   The yat library is free software; you can redistribute it and/or
4346 24 Apr 23 peter 12   modify it under the terms of the GNU General Public License as
4346 24 Apr 23 peter 13   published by the Free Software Foundation; either version 3 of the
4346 24 Apr 23 peter 14   License, or (at your option) any later version.
4346 24 Apr 23 peter 15
4346 24 Apr 23 peter 16   The yat library is distributed in the hope that it will be useful,
4346 24 Apr 23 peter 17   but WITHOUT ANY WARRANTY; without even the implied warranty of
4346 24 Apr 23 peter 18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4346 24 Apr 23 peter 19   General Public License for more details.
4346 24 Apr 23 peter 20
4346 24 Apr 23 peter 21   You should have received a copy of the GNU General Public License
4346 24 Apr 23 peter 22   along with yat. If not, see <https://www.gnu.org/licenses/>.
4346 24 Apr 23 peter 23 */
4346 24 Apr 23 peter 24
3717 20 Nov 17 peter 25 #include "BasicQueue.h"
3722 21 Nov 17 peter 26 #include "utility.h"
3717 20 Nov 17 peter 27 #include "yat_assert.h"
3717 20 Nov 17 peter 28
3057 01 Jul 13 peter 29 #include <deque>
3947 20 Jul 20 peter 30 #include <mutex>
3062 02 Jul 13 peter 31 #include <utility>
3057 01 Jul 13 peter 32
3057 01 Jul 13 peter 33 namespace theplu {
3057 01 Jul 13 peter 34 namespace yat {
3057 01 Jul 13 peter 35 namespace utility {
3057 01 Jul 13 peter 36
3057 01 Jul 13 peter 37   /**
3057 01 Jul 13 peter 38      \brief Multi-thread safe queue
3057 01 Jul 13 peter 39
3057 01 Jul 13 peter 40      This class provides a multi-thread safe queue. The Queue is
3057 01 Jul 13 peter 41      typically shared by multiple threads such that some threads push
3057 01 Jul 13 peter 42      elements and some pop elements. The Queue is a "first in first
3058 01 Jul 13 peter 43      out" container and holds the same functionality as the similar
3058 01 Jul 13 peter 44      <a href="http://www.sgi.com/tech/stl/queue.html">std::queue</a>. The
3057 01 Jul 13 peter 45      difference is that Queue is multi-thread safe, in other words,
3057 01 Jul 13 peter 46      when one thread access the Queue, other threads are locked out
3057 01 Jul 13 peter 47      from access so that only one thread touches the Queue at a time
3057 01 Jul 13 peter 48      and its behaviour is well defined. In a single-thread application
3057 01 Jul 13 peter 49      there is no point in using the class as std::queue should be
3057 01 Jul 13 peter 50      prefereble.
3057 01 Jul 13 peter 51
3061 02 Jul 13 peter 52      \note Copy constructor and assignment are available but they are
3061 02 Jul 13 peter 53      not thread safe in the current implementation.
3061 02 Jul 13 peter 54
3057 01 Jul 13 peter 55      \since New in yat 0.11
3223 10 May 14 peter 56
3223 10 May 14 peter 57      \see Boost Library provides a
3223 10 May 14 peter 58      <a href="http://www.boost.org/doc/libs/1_55_0/doc/html/lockfree.html">
3223 10 May 14 peter 59      lock-free queue</a>
3057 01 Jul 13 peter 60    */
3057 01 Jul 13 peter 61   template<typename T>
3717 20 Nov 17 peter 62   class Queue :
3717 20 Nov 17 peter 63     public detail::BasicQueue<Queue<T>, T, std::deque<T> >
3057 01 Jul 13 peter 64   {
3718 21 Nov 17 peter 65     friend class detail::BasicQueue<Queue<T>, T, std::deque<T> >;
3717 20 Nov 17 peter 66     typedef detail::BasicQueue<Queue<T>, T, std::deque<T> > Base;
3057 01 Jul 13 peter 67   public:
3057 01 Jul 13 peter 68     /**
3062 02 Jul 13 peter 69        \brief Create a Queue with no elements
3062 02 Jul 13 peter 70     */
3062 02 Jul 13 peter 71     Queue(void) {}
3062 02 Jul 13 peter 72
3062 02 Jul 13 peter 73     /**
3188 25 Mar 14 peter 74        \brief Copy constructor
3062 02 Jul 13 peter 75     */
3717 20 Nov 17 peter 76     Queue(const Queue& other)
3718 21 Nov 17 peter 77       : Base(other) {}
3062 02 Jul 13 peter 78
3062 02 Jul 13 peter 79     /**
3717 20 Nov 17 peter 80        \brief assignment operator
3689 12 Sep 17 peter 81      */
3717 20 Nov 17 peter 82     Queue& operator=(const Queue& lhs)
3689 12 Sep 17 peter 83     {
3717 20 Nov 17 peter 84       this->assign(lhs);
3717 20 Nov 17 peter 85       return *this;
3719 21 Nov 17 peter 86     }
3057 01 Jul 13 peter 87
3717 20 Nov 17 peter 88   private:
3946 20 Jul 20 peter 89     void pop_impl(T& value, std::unique_lock<std::mutex>& lock)
3057 01 Jul 13 peter 90     {
3717 20 Nov 17 peter 91       YAT_ASSERT(this->q_.size());
3955 23 Jul 20 peter 92       value = std::move_if_noexcept(this->q_.front());
3717 20 Nov 17 peter 93       this->q_.pop_front();
3717 20 Nov 17 peter 94     }
3057 01 Jul 13 peter 95
3057 01 Jul 13 peter 96
3946 20 Jul 20 peter 97     void push_impl(const T& value, std::unique_lock<std::mutex>& lock)
3057 01 Jul 13 peter 98     {
3717 20 Nov 17 peter 99       this->q_.push_back(value);
3057 01 Jul 13 peter 100     }
3057 01 Jul 13 peter 101
3057 01 Jul 13 peter 102
3946 20 Jul 20 peter 103     void push_impl(T&& value, std::unique_lock<std::mutex>& lock)
3689 12 Sep 17 peter 104     {
3717 20 Nov 17 peter 105       this->q_.push_back(std::move(value));
3689 12 Sep 17 peter 106     }
3057 01 Jul 13 peter 107   };
3057 01 Jul 13 peter 108
3057 01 Jul 13 peter 109 }}}
3057 01 Jul 13 peter 110 #endif