queue.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010 Tommi Maekitalo
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * As a special exception, you may use this file as part of a free
10  * software library without restriction. Specifically, if other files
11  * instantiate templates or use macros or inline functions from this
12  * file, or you compile this file and link it with other files to
13  * produce an executable, this file does not by itself cause the
14  * resulting executable to be covered by the GNU General Public
15  * License. This exception does not however invalidate any other
16  * reasons why the executable file might be covered by the GNU Library
17  * General Public License.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27  */
28 
29 #ifndef CXXTOOLS_QUEUE_H
30 #define CXXTOOLS_QUEUE_H
31 
32 #include <queue>
33 #include <cxxtools/mutex.h>
34 #include <cxxtools/condition.h>
35 
36 namespace cxxtools
37 {
46  template <typename T>
47  class Queue
48  {
49  public:
50  typedef T value_type;
51  typedef typename std::deque<T>::size_type size_type;
52  typedef typename std::deque<T>::const_reference const_reference;
53 
54  private:
55  mutable Mutex _mutex;
56  Condition _notEmpty;
57  Condition _notFull;
58  std::deque<value_type> _queue;
59  size_type _maxSize;
60  size_type _numWaiting;
61 
62  public:
65  : _maxSize(0),
66  _numWaiting(0)
67  { }
68 
74  value_type get();
75 
81  std::pair<value_type, bool> tryGet();
82 
89  void put(const_reference element, bool force = false);
90 
92  bool empty() const
93  {
94  MutexLock lock(_mutex);
95  return _queue.empty();
96  }
97 
99  size_type size() const
100  {
101  MutexLock lock(_mutex);
102  return _queue.size();
103  }
104 
111  void maxSize(size_type m);
112 
115  {
116  MutexLock lock(_mutex);
117  return _maxSize;
118  }
119 
122  {
123  MutexLock lock(_mutex);
124  return _numWaiting;
125  }
126  };
127 
128  template <typename T>
130  {
131  MutexLock lock(_mutex);
132 
133  ++_numWaiting;
134  while (_queue.empty())
135  _notEmpty.wait(lock);
136  --_numWaiting;
137 
138  value_type element = _queue.front();
139  _queue.pop_front();
140 
141  if (!_queue.empty())
142  _notEmpty.signal();
143 
144  _notFull.signal();
145 
146  return element;
147  }
148 
149  template <typename T>
150  std::pair<typename Queue<T>::value_type, bool> Queue<T>::tryGet()
151  {
152  typedef typename Queue<T>::value_type value_type;
153  typedef typename std::pair<value_type, bool> return_type;
154 
155  MutexLock lock(_mutex);
156 
157  if (_queue.empty())
158  return return_type(value_type(), false);
159 
160  value_type element = _queue.front();
161  _queue.pop_front();
162 
163  if (!_queue.empty())
164  _notEmpty.signal();
165 
166  _notFull.signal();
167 
168  return return_type(element, true);
169  }
170 
171  template <typename T>
172  void Queue<T>::put(typename Queue<T>::const_reference element, bool force)
173  {
174  MutexLock lock(_mutex);
175 
176  if (!force)
177  while (_maxSize > 0 && _queue.size() >= _maxSize)
178  _notFull.wait(lock);
179 
180  _queue.push_back(element);
181  _notEmpty.signal();
182 
183  if (_maxSize > 0 && _queue.size() < _maxSize)
184  _notFull.signal();
185  }
186 
187  template <typename T>
189  {
190  _maxSize = m;
191  MutexLock lock(_mutex);
192  if (_queue.size() < _maxSize)
193  _notFull.signal();
194  }
195 }
196 
197 #endif // CXXTOOLS_QUEUE_H
198