Taskolib  1.4.4
LockedQueue.h
Go to the documentation of this file.
1 
23 // SPDX-License-Identifier: LGPL-2.1-or-later
24 
25 #ifndef TASKOLIB_LOCKEDQUEUE_H_
26 #define TASKOLIB_LOCKEDQUEUE_H_
27 
28 #include <condition_variable>
29 #include <mutex>
30 #include <optional>
31 
32 #include <gul17/SlidingBuffer.h>
33 
34 namespace task {
35 
65 template <typename MessageT>
67 {
68 public:
69  using MessageType = MessageT;
70  using message_type = MessageT;
71  using SizeType = std::uint32_t;
73 
76  : queue_(capacity)
77  { }
78 
81  {
82  std::lock_guard<std::mutex> lock(mutex_);
83  return queue_.capacity();
84  }
85 
87  bool empty() const
88  {
89  std::lock_guard<std::mutex> lock(mutex_);
90  return queue_.empty();
91  }
92 
101  {
102  std::unique_lock<std::mutex> lock(mutex_);
103 
104  if (queue_.empty())
105  cv_message_available_.wait(lock, [this] { return not queue_.empty(); });
106 
107  auto msg = std::move(queue_.front());
108  queue_.pop_front();
109  lock.unlock();
110  cv_slot_available_.notify_one();
111  return msg;
112  }
113 
121  {
122  std::unique_lock<std::mutex> lock(mutex_);
123 
124  if (queue_.empty())
125  cv_message_available_.wait(lock, [this] { return not queue_.empty(); });
126 
127  auto msg = queue_.back();
128  lock.unlock();
129  return msg;
130  }
131 
137  template <typename MsgT,
138  std::enable_if_t<std::is_convertible_v<MsgT, MessageType>, bool> = true>
139  void push(MsgT&& msg)
140  {
141  std::unique_lock<std::mutex> lock(mutex_);
142 
143  if (queue_.filled())
144  cv_slot_available_.wait(lock, [this] { return not queue_.filled(); });
145 
146  queue_.push_back(std::forward<MsgT>(msg));
147  lock.unlock();
148  cv_message_available_.notify_one();
149  }
150 
152  SizeType size() const
153  {
154  std::lock_guard<std::mutex> lock(mutex_);
155  return queue_.size();
156  }
157 
165  std::optional<MessageType> try_pop()
166  {
167  std::unique_lock<std::mutex> lock(mutex_);
168 
169  if (queue_.empty())
170  return std::nullopt;
171 
172  auto msg = std::move(queue_.front());
173  queue_.pop_front();
174  lock.unlock();
175  cv_slot_available_.notify_one();
176  return msg;
177  }
178 
188  template <typename MsgT,
189  std::enable_if_t<std::is_convertible_v<MsgT, MessageType>, bool> = true>
190  bool try_push(MsgT&& msg)
191  {
192  std::unique_lock<std::mutex> lock(mutex_);
193 
194  if (queue_.filled())
195  return false;
196 
197  queue_.push_back(std::forward<MsgT>(msg));
198  lock.unlock();
199  cv_message_available_.notify_one();
200  return true;
201  }
202 
203 private:
205  mutable std::mutex mutex_;
206 
208  mutable std::condition_variable cv_message_available_;
209 
211  mutable std::condition_variable cv_slot_available_;
212 
213  gul17::SlidingBuffer<MessageType> queue_;
214 };
215 
216 } // namespace task
217 
218 #endif
A thread-safe locking message queue.
Definition: LockedQueue.h:67
SizeType size() const
Return the number of messages in the queue.
Definition: LockedQueue.h:152
SizeType size_type
Definition: LockedQueue.h:72
SizeType capacity() const
Return the maximal number of entries in the queue.
Definition: LockedQueue.h:80
gul17::SlidingBuffer< MessageType > queue_
Definition: LockedQueue.h:213
std::uint32_t SizeType
Definition: LockedQueue.h:71
std::optional< MessageType > try_pop()
Remove a message from the front of the queue and return it.
Definition: LockedQueue.h:165
MessageT MessageType
Definition: LockedQueue.h:69
std::mutex mutex_
Mutex protecting all member variables.
Definition: LockedQueue.h:205
MessageT message_type
Definition: LockedQueue.h:70
LockedQueue(SizeType capacity)
Construct a queue that is able to hold a given maximum number of entries.
Definition: LockedQueue.h:75
bool empty() const
Determine whether the queue is empty.
Definition: LockedQueue.h:87
std::condition_variable cv_message_available_
Condition variable, triggered when at least one message has been added to the queue.
Definition: LockedQueue.h:208
MessageType pop()
Remove a message from the front of the queue and return it.
Definition: LockedQueue.h:100
void push(MsgT &&msg)
Insert a message at the end of the queue.
Definition: LockedQueue.h:139
MessageType back() const
Fetch the last message pushed to the queue and returns a copy of it.
Definition: LockedQueue.h:120
std::condition_variable cv_slot_available_
Condition variable, triggered when at least one slot in the queue has been freed.
Definition: LockedQueue.h:211
bool try_push(MsgT &&msg)
Try to insert a message at the end of the queue.
Definition: LockedQueue.h:190
Namespace task contains all Taskolib functions and classes.
Definition: CommChannel.h:33