libosmscout 1.1.1
Loading...
Searching...
No Matches
ProcessingQueue.h
Go to the documentation of this file.
1#ifndef OSMSCOUT_UTIL_PROCESSINGQUEUE_H
2#define OSMSCOUT_UTIL_PROCESSINGQUEUE_H
3
4/*
5 This source is part of the libosmscout library
6 Copyright (C) 2020 Tim Teulings
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/
22
23#include <condition_variable>
24#include <deque>
25#include <limits>
26#include <memory>
27#include <mutex>
28#include <optional>
29
31
32namespace osmscout {
33
54 template<typename T>
56 {
57 private:
58 std::mutex mutex;
59 std::condition_variable pushCondition;
60 std::condition_variable popCondition;
61 std::deque<T> tasks;
62 size_t queueLimit=std::numeric_limits<size_t>::max();
63 bool running{true};
64
65 public:
67 explicit ProcessingQueue(size_t queueLimit);
68
71
72 virtual ~ProcessingQueue() = default;
73
74 void PushTask(const T& task);
75 void PushTask(T&& task);
76 std::optional<T> PopTask();
77
78 void Stop();
79 };
80
86 template<class T>
88
97 template<class T>
99 : queueLimit(queueLimit)
100 {
101 // no code
102 }
103
111 template<class T>
113 {
114 std::unique_lock lock(mutex);
115
116 pushCondition.wait(lock,[this]{return tasks.size()<queueLimit;});
117
118 tasks.push_back(task);
119
120 lock.unlock();
121
122 popCondition.notify_one();
123 }
124
132 template<class T>
134 {
135 std::unique_lock lock(mutex);
136
137 pushCondition.wait(lock,[this]{return tasks.size()<queueLimit;});
138
139 tasks.push_back(std::forward<T>(task));
140
141 lock.unlock();
142
143 popCondition.notify_one();
144 }
145
153 template<class T>
155 {
156 std::unique_lock lock(mutex);
157
158 popCondition.wait(lock,[this]{return !tasks.empty() || !running;});
159
160 if (!running &&
161 tasks.empty()) {
162 return std::nullopt;
163 }
164
165 std::optional<T> task=std::move(tasks.front());
166 tasks.pop_front();
167
168 lock.unlock();
169
170 pushCondition.notify_one();
171
172 return task;
173 }
174
180
181 template<class R>
183 {
184 std::unique_lock lock(mutex);
185
186 running=false;
187
188 lock.unlock();
189
190 popCondition.notify_all();
191 }
192}
193
194#endif
void PushTask(const T &task)
Definition ProcessingQueue.h:112
ProcessingQueue & operator=(const ProcessingQueue &)=delete
void Stop()
Definition ProcessingQueue.h:182
ProcessingQueue(const ProcessingQueue &)=delete
virtual ~ProcessingQueue()=default
std::optional< T > PopTask()
Definition ProcessingQueue.h:154
Definition Area.h:39