-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathThreadSafeQueue.hpp
More file actions
158 lines (147 loc) · 4.51 KB
/
ThreadSafeQueue.hpp
File metadata and controls
158 lines (147 loc) · 4.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
* Copyright 2025 TierOne Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef THREAD_SAFE_QUEUE_HPP
#define THREAD_SAFE_QUEUE_HPP
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <queue>
#include <thread>
/**
* @brief A thread-safe queue implementation using unique_ptr for element storage
*
* This class provides a thread-safe wrapper around std::queue that stores
* std::unique_ptr<T> objects. It uses mutex and condition variables to ensure
* safe concurrent access from multiple threads. The queue supports both
* blocking and non-blocking operations.
*
* @tparam T The type of objects stored in the queue
*
* Features:
* - Thread-safe push and pop operations
* - Non-blocking try_pop operation
* - Blocking wait_and_pop operation
* - Timed wait operation with timeout
* - Move semantics for efficient memory management
* - Copy operations are disabled to prevent resource conflicts
*/
template <typename T>
class ThreadSafeQueue {
std::queue<std::unique_ptr<T>> queue;
mutable std::mutex mutex;
std::condition_variable condVar;
public:
ThreadSafeQueue() = default;
ThreadSafeQueue(const ThreadSafeQueue& other) = delete;
ThreadSafeQueue& operator=(const ThreadSafeQueue& other) = delete;
/**
* @brief Push a new element onto the queue
*
* This operation is thread-safe and will notify one waiting thread
* that an element is available.
*
* @param value Unique pointer to the element to be added
*/
void push(std::unique_ptr<T> value)
{
std::lock_guard lock(mutex);
queue.push(std::move(value));
condVar.notify_one();
}
/**
* @brief Try to pop an element from the queue without blocking
*
* Attempts to remove and return the front element from the queue.
* Returns immediately if the queue is empty.
*
* @param value Output parameter that will receive the popped element
* @return true if an element was successfully popped, false if queue was empty
*/
bool try_pop(std::unique_ptr<T>& value)
{
std::lock_guard lock(mutex);
if (queue.empty()) {
return false;
}
value = std::move(queue.front());
queue.pop();
return true;
}
/**
* @brief Pop an element from the queue, blocking until one is available
*
* This method will block the calling thread until an element becomes
* available in the queue. Use with caution to avoid deadlocks.
*
* @param value Output parameter that will receive the popped element
*/
void wait_and_pop(std::unique_ptr<T>& value)
{
std::unique_lock lock(mutex);
condVar.wait(lock, [this] { return !queue.empty(); });
value = std::move(queue.front());
queue.pop();
}
/**
* @brief Try to pop an element with a timeout
*
* Waits for up to the specified duration for an element to become available.
* Returns false if the timeout expires before an element is available.
*
* @tparam Rep Arithmetic type representing the number of ticks
* @tparam Period A std::ratio representing the tick period
* @param value Output parameter that will receive the popped element
* @param timeout Maximum time to wait for an element
* @return true if an element was popped, false if timeout expired
*/
template <typename Rep, typename Period>
bool try_wait_and_pop(std::unique_ptr<T>& value,
const std::chrono::duration<Rep, Period>& timeout)
{
std::unique_lock lock(mutex);
if (!condVar.wait_for(lock, timeout, [this] { return !queue.empty(); })) {
return false;
}
value = std::move(queue.front());
queue.pop();
return true;
}
/**
* @brief Check if the queue is empty
*
* Thread-safe check for queue emptiness.
*
* @return true if the queue contains no elements, false otherwise
*/
bool empty() const
{
std::lock_guard lock(mutex);
return queue.empty();
}
/**
* @brief Get the current size of the queue
*
* Thread-safe retrieval of the number of elements in the queue.
*
* @return Number of elements currently in the queue
*/
size_t size() const
{
std::lock_guard lock(mutex);
return queue.size();
}
};
#endif // THREAD_SAFE_QUEUE_HPP