Instrument Neutral Distributed Interface INDI  2.0.2
uniquequeue.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2020 by Pawel Soja <kernel32.pl@gmail.com>
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 
34 template <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
96 template <typename T>
97 inline 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 
104 template <typename T>
105 inline 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 
120 template <typename T>
121 inline 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 
137 template <typename T>
138 inline size_t UniqueQueue<T>::size() const
139 {
140  std::unique_lock<std::mutex> lock(mutex);
141  return queue.size();
142 }
143 
144 template <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 
153 template <typename T>
154 inline void UniqueQueue<T>::waitForEmpty() const
155 {
156  std::unique_lock<std::mutex> lock(mutex);
157  decrease.wait(lock, [this]()
158  {
159  return queue.empty();
160  });
161 }
162 
163 template <typename T>
164 inline 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 
173 template <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.
Definition: uniquequeue.h:145
bool pop(T &dest, uint32_t msecs)
Pop data from queue.
Definition: uniquequeue.h:121
void push(T &&data)
Move data to queue.
Definition: uniquequeue.h:97
bool pop(T &dest)
Pop data from queue.
Definition: uniquequeue.h:105
std::condition_variable increase
Definition: uniquequeue.h:92
std::condition_variable decrease
Definition: uniquequeue.h:91
void waitForEmpty() const
Wait for an empty queue.
Definition: uniquequeue.h:154
std::queue< T > queue
Definition: uniquequeue.h:88
void abort()
Clear queue and exit pop methods with false return.
Definition: uniquequeue.h:174
std::mutex mutex
Definition: uniquequeue.h:89
size_t size() const
Return the number of items in the queue.
Definition: uniquequeue.h:138
bool waitForEmpty(uint32_t msecs) const
Wait for an empty queue.
Definition: uniquequeue.h:164
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
Definition: json.h:23663