Instrument Neutral Distributed Interface INDI 2.2.5
uniquequeue.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2020 by Pawel Soja <[email protected]>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Lesser General Public License for more details.
12 You should have received a copy of the GNU Lesser General Public
13 License along with this library; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15*/
16#pragma once
17
18#include <queue>
19#include <mutex>
20#include <condition_variable>
21#include <chrono>
22#include <cstdint>
23
34template <typename T>
36{
37 public:
42 void push(T &&data);
43
49 bool pop(T &dest);
50
57 bool pop(T &dest, uint32_t msecs);
58
62 void waitForEmpty() const;
63
69 bool waitForEmpty(uint32_t msecs) const;
70
74 void clear();
75
79 void abort();
80
85 size_t size() const;
86
87 protected:
88 std::queue<T> queue;
89 mutable std::mutex mutex;
90
91 mutable std::condition_variable decrease;
92 mutable std::condition_variable increase;
93};
94
95// implementation
96template <typename T>
97inline void UniqueQueue<T>::push(T &&data)
98{
99 std::lock_guard<std::mutex> lock(mutex);
100 queue.push(std::move(data));
101 increase.notify_all();
102}
103
104template <typename T>
105inline bool UniqueQueue<T>::pop(T &dest)
106{
107 std::unique_lock<std::mutex> lock(mutex);
108 if (queue.empty())
109 increase.wait(lock);
110
111 if (queue.empty())
112 return false; // abort
113
114 std::swap(dest, queue.front());
115 queue.pop();
116 decrease.notify_all();
117 return true;
118}
119
120template <typename T>
121inline bool UniqueQueue<T>::pop(T &dest, uint32_t msecs)
122{
123 std::unique_lock<std::mutex> lock(mutex);
124
125 if (queue.empty() && increase.wait_for(lock, std::chrono::milliseconds(msecs)) == std::cv_status::timeout)
126 return false; // timeout
127
128 if (queue.empty())
129 return false; // abort
130
131 std::swap(dest, queue.front());
132 queue.pop();
133 decrease.notify_all();
134 return true;
135}
136
137template <typename T>
138inline size_t UniqueQueue<T>::size() const
139{
140 std::unique_lock<std::mutex> lock(mutex);
141 return queue.size();
142}
143
144template <typename T>
146{
147 std::queue<T> empty;
148 std::unique_lock<std::mutex> lock(mutex);
149 std::swap(queue, empty);
150 decrease.notify_all();
151}
152
153template <typename T>
155{
156 std::unique_lock<std::mutex> lock(mutex);
157 decrease.wait(lock, [this]()
158 {
159 return queue.empty();
160 });
161}
162
163template <typename T>
164inline bool UniqueQueue<T>::waitForEmpty(uint32_t msecs) const
165{
166 std::unique_lock<std::mutex> lock(mutex);
167 return decrease.wait_for(lock, std::chrono::milliseconds(msecs), [this]()
168 {
169 return queue.empty();
170 });
171}
172
173template <typename T>
175{
176 std::queue<T> empty;
177 std::unique_lock<std::mutex> lock(mutex);
178 std::swap(queue, empty);
179 increase.notify_all();
180 decrease.notify_all();
181}
The UniqueQueue class is a thread-safe FIFO container adapter.
Definition uniquequeue.h:36
void clear()
Clear queue.
bool pop(T &dest, uint32_t msecs)
Pop data from queue.
void push(T &&data)
Move data to queue.
Definition uniquequeue.h:97
bool pop(T &dest)
Pop data from queue.
std::condition_variable increase
Definition uniquequeue.h:92
std::condition_variable decrease
Definition uniquequeue.h:91
void waitForEmpty() const
Wait for an empty queue.
std::queue< T > queue
Definition uniquequeue.h:88
void abort()
Clear queue and exit pop methods with false return.
std::mutex mutex
Definition uniquequeue.h:89
size_t size() const
Return the number of items in the queue.
bool waitForEmpty(uint32_t msecs) const
Wait for an empty queue.
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects