yat  0.14.5pre
Queue.h
1 #ifndef theplu_yat_utility_queue
2 #define theplu_yat_utility_queue
3 
4 // $Id: Queue.h 3550 2017-01-03 05:41:02Z peter $
5 //
6 // Copyright (C) 2013, 2014, 2016 Peter Johansson
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 3 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 
21 #include <boost/thread.hpp>
22 
23 #include <deque>
24 #include <utility>
25 
26 namespace theplu {
27 namespace yat {
28 namespace utility {
29 
54  template<typename T>
55  class Queue
56  {
57  public:
59  typedef T value_type;
60 
64  typedef typename std::deque<T>::size_type size_type;
65 
69  Queue(void) {}
70 
76  Queue(const Queue& other) : q_(other.q_) {}
77 
81  bool empty(void) const
82  {
83  boost::unique_lock<boost::mutex> lock(mutex_);
84  return q_.empty();
85  } // lock is released here
86 
87 
95  void pop(T& value)
96  {
97  boost::unique_lock<boost::mutex> lock(mutex_);
98  while (q_.empty())
99  condition_.wait(lock);
100  // The obvious choice would be to create a temp copy of front,
101  // pop the queue and then return by-value. This is, however,
102  // dangerous becasue if the copy constructor throws, the queue
103  // has been popped and the element is lost. Instead we choose to
104  // pass via passed reference.
105  value = q_.front();
106  q_.pop_front();
107  } // lock is released here
108 
109 
113  void push(const T& t)
114  {
115  boost::unique_lock<boost::mutex> lock(mutex_);
116  q_.push_back(t);
117  lock.unlock(); // unlock the mutex
118 
119  // Notify others that data is ready after we have unlocked
120  condition_.notify_one();
121  }
122 
123 
127  size_type size(void) const
128  {
129  boost::unique_lock<boost::mutex> lock(mutex_);
130  return q_.size();
131  } // lock is released here
132 
133 
138  bool try_pop(T& value)
139  {
140  boost::unique_lock<boost::mutex> lock(mutex_);
141  if (q_.empty())
142  return false;
143  value = q_.front();
144  q_.pop_front();
145  return true;
146  } // lock is released here
147 
148 
152  Queue& operator=(const Queue& lhs)
153  {
154  boost::unique_lock<boost::mutex> lock(mutex_);
155  q_ = lhs.q_;
156  return *this;
157  } // lock is released here
158 
159  private:
160  std::deque<T> q_;
161  mutable boost::mutex mutex_;
162  boost::condition_variable condition_;
163 
164  // thread safe way to access nderlying data
165  const std::deque<T>& q(void) const
166  {
167  boost::unique_lock<boost::mutex> lock(mutex_);
168  return q_;
169  } // lock is released here
170  };
171 
172 }}}
173 #endif
std::deque< T >::size_type size_type
Definition: Queue.h:64
bool empty(void) const
Definition: Queue.h:81
bool try_pop(T &value)
Definition: Queue.h:138
Queue(void)
Create a Queue with no elements.
Definition: Queue.h:69
Multi-thread safe queue.
Definition: Queue.h:55
Queue(const Queue &other)
Copy constructor.
Definition: Queue.h:76
T value_type
Type of object stored in Queue.
Definition: Queue.h:59
void pop(T &value)
access next element in queue
Definition: Queue.h:95
void push(const T &t)
insert an element into container
Definition: Queue.h:113
size_type size(void) const
Definition: Queue.h:127
Queue & operator=(const Queue &lhs)
assignment operator
Definition: Queue.h:152

Generated on Tue Sep 26 2017 02:33:29 for yat by  doxygen 1.8.5