Instrument Neutral Distributed Interface INDI  1.9.5
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](){ return queue.empty(); });
158 }
159 
160 template <typename T>
161 inline bool UniqueQueue<T>::waitForEmpty(uint32_t msecs) const
162 {
163  std::unique_lock<std::mutex> lock(mutex);
164  return decrease.wait_for(lock, std::chrono::milliseconds(msecs), [this](){ return queue.empty(); });
165 }
166 
167 template <typename T>
169 {
170  std::queue<T> empty;
171  std::unique_lock<std::mutex> lock(mutex);
172  std::swap(queue, empty);
173  increase.notify_all();
174  decrease.notify_all();
175 }
UniqueQueue::queue
std::queue< T > queue
Definition: uniquequeue.h:88
UniqueQueue::clear
void clear()
Clear queue.
Definition: uniquequeue.h:145
UniqueQueue::size
size_t size() const
Return the number of items in the queue.
Definition: uniquequeue.h:138
UniqueQueue::push
void push(T &&data)
Move data to queue.
Definition: uniquequeue.h:97
UniqueQueue::increase
std::condition_variable increase
Definition: uniquequeue.h:92
UniqueQueue
The UniqueQueue class is a thread-safe FIFO container adapter.
Definition: uniquequeue.h:35
UniqueQueue::waitForEmpty
void waitForEmpty() const
Wait for an empty queue.
Definition: uniquequeue.h:154
UniqueQueue::abort
void abort()
Clear queue and exit pop methods with false return.
Definition: uniquequeue.h:168
UniqueQueue::pop
bool pop(T &dest)
Pop data from queue.
Definition: uniquequeue.h:105
UniqueQueue::mutex
std::mutex mutex
Definition: uniquequeue.h:89
UniqueQueue::decrease
std::condition_variable decrease
Definition: uniquequeue.h:91