-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsafe_queue.h
69 lines (59 loc) · 1.55 KB
/
safe_queue.h
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
#pragma once
#include <queue>
#include <mutex>
#include <optional>
#include <condition_variable>
#include <cstdio>
namespace mavsdk {
/*
* Thread-safe queue taken from:
* http://stackoverflow.com/questions/15278343/c11-thread-safe-queue#answer-16075550
*/
template<class T> class SafeQueue {
public:
SafeQueue() = default;
~SafeQueue() = default;
void enqueue(T item)
{
std::lock_guard<std::mutex> lock(_mutex);
_queue.push(item);
_condition_var.notify_one();
}
std::optional<T> dequeue()
{
std::unique_lock<std::mutex> lock(_mutex);
while (_queue.empty()) {
if (_should_exit) {
return std::nullopt;
}
// Release lock during the wait and re-aquire it afterwards.
_condition_var.wait(lock);
}
if (_should_exit) {
return std::nullopt;
} else {
T item = _queue.front();
_queue.pop();
return {item};
}
}
void stop()
{
// This can be used if the wait needs to be interrupted, e.g.
// when trying to stop a worker thread.
std::lock_guard<std::mutex> lock(_mutex);
_should_exit = true;
_condition_var.notify_all();
}
std::size_t size() const
{
std::lock_guard<std::mutex> lock(_mutex);
return _queue.size();
}
private:
std::queue<T> _queue{};
mutable std::mutex _mutex{};
std::condition_variable _condition_var{};
bool _should_exit{false};
};
} // namespace mavsdk