Lightweight 0.20251202.0
Loading...
Searching...
No Matches
ThreadSafeQueue.hpp
1// SPDX-License-Identifier: Apache-2.0
2
3#pragma once
4
5#include <condition_variable>
6#include <deque>
7#include <mutex>
8
9namespace Lightweight
10{
11
12/// Thread-safe queue with blocking wait semantics.
13///
14/// This queue allows multiple producer and consumer threads to safely enqueue
15/// and dequeue items. Consumers block on WaitAndPop until an item is available
16/// or the queue is marked as finished.
17///
18/// @tparam T The type of items stored in the queue.
19template <typename T>
21{
22 public:
23 /// Pushes an item onto the queue and notifies one waiting consumer.
24 ///
25 /// @param item The item to push onto the queue.
26 void Push(T item)
27 {
28 {
29 std::scoped_lock lock(_mutex);
30 _queue.push_back(std::move(item));
31 }
32 _condition.notify_one();
33 }
34
35 /// Blocks until an item is available or the queue is finished.
36 ///
37 /// This method will block the calling thread until either:
38 /// - An item becomes available in the queue, or
39 /// - The queue has been marked as finished and is empty.
40 ///
41 /// @param item Output parameter to receive the popped item.
42 /// @return true if an item was successfully popped, false if the queue is finished and empty.
43 bool WaitAndPop(T& item)
44 {
45 std::unique_lock lock(_mutex);
46 _condition.wait(lock, [this] { return !_queue.empty() || _finished; });
47 if (_queue.empty())
48 return false;
49 item = std::move(_queue.front());
50 _queue.pop_front();
51 return true;
52 }
53
54 /// Signals that no more items will be added.
55 ///
56 /// After this call, WaitAndPop will return false once the queue is empty.
57 /// All waiting consumers will be notified.
59 {
60 {
61 std::scoped_lock lock(_mutex);
62 _finished = true;
63 }
64 _condition.notify_all();
65 }
66
67 /// Checks if the queue is empty.
68 ///
69 /// @return true if the queue is currently empty.
70 [[nodiscard]] bool Empty() const
71 {
72 std::scoped_lock lock(_mutex);
73 return _queue.empty();
74 }
75
76 /// Returns the current size of the queue.
77 ///
78 /// @return The number of items currently in the queue.
79 [[nodiscard]] size_t Size() const
80 {
81 std::scoped_lock lock(_mutex);
82 return _queue.size();
83 }
84
85 private:
86 std::deque<T> _queue;
87 mutable std::mutex _mutex;
88 std::condition_variable _condition;
89 bool _finished = false;
90};
91
92} // namespace Lightweight