UTILLib 2.0
Common C++ library with utilities.
Loading...
Searching...
No Matches
threadsafequeue.h
Go to the documentation of this file.
1/*
2 * Copyright 2021 Ingemar Hedvall
3 * SPDX-License-Identifier: MIT
4 */
5
11#pragma once
12#include <condition_variable>
13#include <memory>
14#include <mutex>
15#include <queue>
16
17namespace util::log {
18
27template <typename T>
28class ThreadSafeQueue {
29 public:
30 ThreadSafeQueue() = default;
31 virtual ~ThreadSafeQueue();
32
33 ThreadSafeQueue(const ThreadSafeQueue&) = delete;
34 ThreadSafeQueue& operator=(const ThreadSafeQueue&) = delete;
35
41 void Put(std::unique_ptr<T>& value);
42
52 [[nodiscard]] bool Get(std::unique_ptr<T>& dest, bool block);
53
60 [[nodiscard]] bool Empty() const;
61
66 [[nodiscard]] size_t Size() const;
67
68 void Clear();
69 void Start();
70 void Stop();
71
72 private:
73 mutable std::mutex lock_;
74 std::queue<std::unique_ptr<T>> queue_;
75 std::atomic<bool> stop_ =
76 false;
77 std::condition_variable
78 queue_event_;
79};
80
81template <typename T>
82ThreadSafeQueue<T>::~ThreadSafeQueue() {
83 stop_ = true;
84 queue_event_.notify_one(); // Release any blocking Get()
85 std::lock_guard lock(lock_); // Waiting for Get() to release
86 while (!queue_.empty()) {
87 queue_.pop();
88 }
89}
90
91template <typename T>
92void ThreadSafeQueue<T>::Put(std::unique_ptr<T>& value) {
93 if (stop_) {
94 return;
95 }
96 std::lock_guard lock(lock_);
97 queue_.push(std::move(value));
98 queue_event_.notify_one();
99}
100
101template <typename T>
102bool ThreadSafeQueue<T>::Get(std::unique_ptr<T>& dest, bool block) {
103 if (stop_) {
104 return false;
105 }
106
107 if (block) {
108 std::unique_lock lock(lock_);
109 queue_event_.wait(lock, [&] { return !queue_.empty() || stop_.load(); });
110 if (queue_.empty() || stop_) {
111 return false;
112 }
113 dest = std::move(queue_.front());
114 queue_.pop();
115 } else {
116 std::lock_guard lock(lock_);
117 if (queue_.empty() || stop_) {
118 return false;
119 }
120 dest = std::move(queue_.front());
121 queue_.pop();
122 }
123 return true;
124}
125
126template <typename T>
128 std::lock_guard lock(lock_);
129 return queue_.empty();
130}
131
132template <typename T>
134 std::lock_guard lock(lock_);
135 return queue_.size();
136}
137template <typename T>
139 std::unique_ptr<T> temp;
140 while (Get(temp, false)) {
141 temp.reset();
142 }
143}
144
145template <typename T>
147 stop_ = false;
148 if (!Empty()) {
149 queue_event_.notify_one(); // Release any blocking Get()
150 }
151}
152template <typename T>
154 stop_ = true;
155 queue_event_.notify_one(); // Release any blocking Get()
156}
157
158} // namespace util::log
void Clear()
Clears the queue.
Definition threadsafequeue.h:138
void Start()
Restarts the queue.
Definition threadsafequeue.h:146
bool Get(std::unique_ptr< T > &dest, bool block)
Fetch the first object from the queue.
Definition threadsafequeue.h:102
void Stop()
Stops all blocking Get() calls.
Definition threadsafequeue.h:153
size_t Size() const
Returns number of items in the queue.
Definition threadsafequeue.h:133
bool Empty() const
Returns true if the queue is empty.
Definition threadsafequeue.h:127
void Put(std::unique_ptr< T > &value)
Adds a value at the end of the queue.
Definition threadsafequeue.h:92
The log namespace is used for log related classes and functions.
Definition idirectory.h:18