m2etis  0.4
DoubleBufferQueue.h
Go to the documentation of this file.
1 /*
2  Copyright (2016) Michael Baer, Daniel Bonrath, All rights reserved.
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15  */
16 
22 #ifndef __M2ETIS_UTIL_DOUBLEBUFFERQUEUE_H__
23 #define __M2ETIS_UTIL_DOUBLEBUFFERQUEUE_H__
24 
25 #include <queue>
26 
27 #include "m2etis/util/Exceptions.h"
28 
29 #include "boost/thread/recursive_mutex.hpp"
30 
31 namespace m2etis {
32 namespace util {
33 
34  template<typename T, bool producer = true, bool consumer = true>
36  public:
40  DoubleBufferQueue() : _queueA(), _queueB(), _queueRead(&_queueA), _queueWrite(&_queueB), _lock() {
41  }
42 
46  void push(const T & value) {
47  boost::recursive_mutex::scoped_lock scopeLock(_lock);
48  _queueWrite->push(value);
49  assert(!empty());
50  }
51 
55  void pop() {
56  boost::recursive_mutex::scoped_lock scopeLock(_lock);
57  if (_queueRead->empty()) {
58  swap();
59  }
60 
61  if (_queueRead->empty()) {
62  M2ETIS_THROW_API("DoubleBufferQueue", "nothing to pop");
63  }
64 
65  _queueRead->pop();
66  }
67 
71  T front() {
72  boost::recursive_mutex::scoped_lock scopeLock(_lock);
73  if (_queueRead->empty()) {
74  swap();
75  }
76 
77  if (_queueRead->empty()) {
78  M2ETIS_THROW_API("DoubleBufferQueue", "nothing to get");
79  }
80 
81  return _queueRead->front();
82  }
83 
87  T poll() {
88  boost::recursive_mutex::scoped_lock scopeLock(_lock);
89  if (_queueRead->empty()) {
90  swap();
91  }
92 
93  if (_queueRead->empty()) {
94  M2ETIS_THROW_API("DoubleBufferQueue", "nothing to get");
95  }
96 
97  T ret = _queueRead->front();
98  _queueRead->pop();
99  return ret;
100  }
101 
105  bool empty() const {
106  return _queueRead->empty() && _queueWrite->empty();
107  }
108 
112  size_t size() const {
113  return _queueRead->size() + _queueWrite->size();
114  }
115 
119  void clear() {
120  boost::recursive_mutex::scoped_lock scopeLock(_lock);
121  while(!_queueRead->empty()) {
122  _queueRead->pop();
123  }
124  while(!_queueWrite->empty()) {
125  _queueWrite->pop();
126  }
127  }
128 
129  private:
130  std::queue<T> _queueA;
131  std::queue<T> _queueB;
132 
133  std::queue<T> * _queueRead;
134  std::queue<T> * _queueWrite;
135 
136  boost::recursive_mutex _lock;
137 
139 
143  void swap() {
144  boost::recursive_mutex::scoped_lock scopeLock(_lock);
145  if (_queueRead == &_queueA) {
146  _queueWrite = &_queueA;
147  _queueRead = &_queueB;
148  } else {
149  _queueWrite = &_queueB;
150  _queueRead = &_queueA;
151  }
152  }
153  };
154 
155 } /* namespace util */
156 } /* namespace m2etis */
157 
158 #endif /* __M2ETIS_UTIL_DOUBLEBUFFERQUEUE_H__ */
159 
bool empty() const
returns true if the queue is empty, otherwise false
T front()
returns first entry of the queue
void push(const T &value)
pushes the given value into the queue
DoubleBufferQueue()
default constructor
void clear()
removes all elements in the queue
T poll()
remoes first entry of the queue and returns its value
size_t size() const
returns size of the queue
#define M2ETIS_THROW_API(module, message)
throws on wrong API usage
Definition: Exceptions.h:40
void pop()
removes first entry of the queue