GDAL

notifyqueue.h
1/******************************************************************************
2 * (c) 2024 info@hobu.co
3 *
4 * SPDX-License-Identifier: MIT
5 ****************************************************************************/
6
7#ifndef VIEWSHED_NOTIFYQUEUE_H_INCLUDED
8#define VIEWSHED_NOTIFYQUEUE_H_INCLUDED
9
10#include "cpl_port.h"
11
12#include <condition_variable>
13#include <mutex>
14#include <queue>
15
16 namespace gdal
17{
18 namespace viewshed
19{
20
25 template <class T> class NotifyQueue
26{
27 public:
29 ~NotifyQueue()
30 {
31 done();
32 }
33
36 void push(T &&t)
37 {
38 {
39 std::lock_guard<std::mutex> lock(m_mutex);
40 m_queue.push(std::move(t));
41 }
42 m_cv.notify_all();
43 }
44
49 bool pop(T &t)
50 {
51 std::unique_lock<std::mutex> lock(m_mutex);
52 m_cv.wait(lock,
53 [this] { return !m_queue.empty() || m_done || m_stop; });
54
55 if (m_stop)
56 return false;
57
58 if (m_queue.size())
59 {
60 t = std::move(m_queue.front());
61 m_queue.pop();
62 return true;
63 }
64
65 // m_done must be true and the queue is empty.
66 return false;
67 }
68
70 void done()
71 {
72 {
73 std::lock_guard<std::mutex> lock(m_mutex);
74 m_done = !m_stop; // If we're already stopped, we can't be done.
75 }
76 m_cv.notify_all();
77 }
78
80 void stop()
81 {
82 {
83 std::lock_guard<std::mutex> lock(m_mutex);
84 m_stop = !m_done; // If we're already done, we can't be stopped.
85 }
86 m_cv.notify_all();
87 }
88
92 bool isDone()
93 {
94 std::lock_guard<std::mutex> lock(m_mutex);
95 return m_done;
96 }
97
101 bool isStopped()
102 {
103 std::lock_guard<std::mutex> lock(m_mutex);
104 return m_stop;
105 }
106
109 size_t size() const
110 {
111 std::lock_guard<std::mutex> lock(m_mutex);
112 return m_queue.size();
113 }
114
115 private:
116 std::queue<T> m_queue{};
117 mutable std::mutex m_mutex{};
118 std::condition_variable m_cv{};
119 bool m_done{false};
120 bool m_stop{false};
121};
122
123} // namespace viewshed
124} // namespace gdal
125
126#endif
gdal::viewshed::NotifyQueue
This is a thread-safe queue.
Definition: notifyqueue.h:26
gdal::viewshed::NotifyQueue::isStopped
bool isStopped()
Determine if the queue was stopped.
Definition: notifyqueue.h:101
gdal::viewshed::NotifyQueue::size
size_t size() const
Get the current size of the queue.
Definition: notifyqueue.h:109
gdal::viewshed::NotifyQueue::stop
void stop()
Unblock all readers regardless of queue state.
Definition: notifyqueue.h:80
gdal::viewshed::NotifyQueue::~NotifyQueue
~NotifyQueue()
Destructor.
Definition: notifyqueue.h:29
gdal::viewshed::NotifyQueue::done
void done()
When we're done putting things in the queue, set the end condition.
Definition: notifyqueue.h:70
gdal::viewshed::NotifyQueue::push
void push(T &&t)
Push an object on the queue and notify readers.
Definition: notifyqueue.h:36
gdal::viewshed::NotifyQueue::pop
bool pop(T &t)
Get an item from the queue.
Definition: notifyqueue.h:49
gdal::viewshed::NotifyQueue::isDone
bool isDone()
Determine if the queue was emptied completely.
Definition: notifyqueue.h:92
cpl_port.h
Core portability definitions for CPL.