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