IRSOL
C++ code implementing socket server for interacting with Baumer camera.
queue.hpp
Go to the documentation of this file.
1
11#pragma once
12
13#include "irsol/assert.hpp"
14
15#include <condition_variable>
16#include <mutex>
17#include <optional>
18#include <queue>
19
20namespace irsol {
21namespace utils {
22
64template<typename T>
66{
67public:
73 explicit SafeQueue(size_t max_size = 0): m_maxSize(max_size), m_done(false) {}
74
76 SafeQueue(const SafeQueue&) = delete;
77
79 SafeQueue& operator=(const SafeQueue&) = delete;
80
92 void push(T&& item)
93 {
94 std::unique_lock<std::mutex> lock(m_mutex);
95
96 IRSOL_ASSERT_ERROR(!m_done, "SafeQueue::push() called on an already done queue");
97
99 lock, [&]() { return m_done || m_maxSize == 0 || m_queue.size() < m_maxSize; });
100
101 if(m_done)
102 return;
103
104 m_queue.push(std::move(item));
105 m_consumerConditionVariable.notify_one();
106 }
107
122 bool pop(T& out)
123 {
124 std::unique_lock<std::mutex> lock(m_mutex);
125
126 IRSOL_ASSERT_ERROR(!m_done, "SafeQueue::pop() called on an already done queue");
127
128 m_consumerConditionVariable.wait(lock, [&]() { return m_done || !m_queue.empty(); });
129
130 if(m_queue.empty())
131 return false; // done() was called
132
133 out = std::move(m_queue.front());
134 m_queue.pop();
135 m_producerConditionVariable.notify_one();
136 return true;
137 }
138
148 {
149 std::scoped_lock<std::mutex> lock(m_mutex);
150
151 IRSOL_ASSERT_ERROR(!m_done, "SafeQueue::producerFinished() called on an already done queue");
152
153 m_done = true;
154 m_consumerConditionVariable.notify_all();
155 m_producerConditionVariable.notify_all();
156 }
157
162 size_t size() const
163 {
164 std::scoped_lock<std::mutex> lock(m_mutex);
165 return m_queue.size();
166 }
167
173 bool full() const
174 {
175 if(m_maxSize == 0) {
176 return false;
177 }
178 return m_queue.size() >= m_maxSize;
179 }
180
185 bool empty() const
186 {
187 std::scoped_lock<std::mutex> lock(m_mutex);
188 return m_queue.empty();
189 }
190
195 bool done() const
196 {
197 return m_done;
198 }
199
200private:
201 mutable std::mutex m_mutex;
202 std::condition_variable
204 std::condition_variable
206 std::queue<T> m_queue;
207 size_t m_maxSize;
208 bool m_done;
209};
210
211} // namespace utils
212} // namespace irsol
Assertion macros and utilities based on the PPK_ASSERT library.
A thread-safe, optionally bounded queue with blocking push and pop operations.
Definition queue.hpp:66
std::queue< T > m_queue
Underlying queue holding the data.
Definition queue.hpp:206
std::condition_variable m_consumerConditionVariable
Condition variable for consumer blocking.
Definition queue.hpp:205
bool done() const
Returns whether the queue is marked done.
Definition queue.hpp:195
bool full() const
Checks if the queue is full.
Definition queue.hpp:173
SafeQueue(const SafeQueue &)=delete
Deleted copy constructor to prevent copying.
void push(T &&item)
Push an item into the queue.
Definition queue.hpp:92
size_t size() const
Returns the current size of the queue.
Definition queue.hpp:162
void producerFinished()
Signals that the producer has finished producing items.
Definition queue.hpp:147
std::condition_variable m_producerConditionVariable
Condition variable for producer blocking.
Definition queue.hpp:203
bool empty() const
Checks if the queue is empty.
Definition queue.hpp:185
std::mutex m_mutex
Mutex protecting the queue and state.
Definition queue.hpp:201
bool m_done
Flag indicating the queue is done.
Definition queue.hpp:208
SafeQueue(size_t max_size=0)
Constructs a SafeQueue with an optional maximum size.
Definition queue.hpp:73
bool pop(T &out)
Pop an item from the queue.
Definition queue.hpp:122
SafeQueue & operator=(const SafeQueue &)=delete
Deleted copy assignment operator to prevent copying.
size_t m_maxSize
Maximum queue size (0 means unbounded).
Definition queue.hpp:207
#define IRSOL_ASSERT_ERROR
Error-level assertion macro.
Definition assert.hpp:134