libosmscout 1.1.1
Loading...
Searching...
No Matches
CancelableFuture.h
Go to the documentation of this file.
1#ifndef LIBOSMSCOUT_CANCELABLEFUTURE_H
2#define LIBOSMSCOUT_CANCELABLEFUTURE_H
3
4/*
5 This source is part of the libosmscout library
6 Copyright (C) 2023 Lukas Karas
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
24#include <osmscout/log/Logger.h>
25
26#include <future>
27#include <functional>
28#include <optional>
29#include <vector>
30
31namespace osmscout {
32
39 template<typename T>
40 class CancelableFuture
41 {
42 public:
43 using DoneCallback = std::function<void(T const&)>;
44 using CancelCallback = std::function<void()>;
45
46 struct State
47 {
48 std::mutex mutex;
49 std::optional<T> value;
50 bool canceled=false;
51 std::vector<DoneCallback> callbacks;
52 std::vector<CancelCallback> cancelCallbacks;
53
54 void Cancel()
55 {
56 std::unique_lock lock(mutex);
57 if (canceled || value) {
58 return;
59 }
60 canceled=true;
61 for (const auto &callback: cancelCallbacks) {
62 callback();
63 }
64 }
65 };
66
67 class Promise;
68
69 class FutureBreaker: public Breaker
70 {
71 private:
72 std::shared_ptr<State> state=std::make_shared<State>();
73
74 private:
75 friend class Promise;
76
77 FutureBreaker(const std::shared_ptr<State> &state): state(state)
78 {
79 // no code
80 };
81
82 public:
83 virtual ~FutureBreaker() = default;
84
85 FutureBreaker(const FutureBreaker&) = default;
86 FutureBreaker(FutureBreaker&&) = default;
87
88 FutureBreaker& operator=(const FutureBreaker&) = default;
89 FutureBreaker& operator=(FutureBreaker&&) = default;
90
91 void Break() override
92 {
93 state->Cancel();
94 }
95
96 bool IsAborted() const override
97 {
98 std::unique_lock lock(state->mutex);
99 return state->canceled;
100 }
101
102 void Reset() override
103 {
104 log.Warn() << "Future breaker doesn't support reset.";
105 }
106 };
107
109 {
110 private:
111 std::shared_ptr<State> state=std::make_shared<State>();
112 public:
113 Promise() = default;
114
115 virtual ~Promise() = default;
116
117 Promise(const Promise&) = default;
118 Promise(Promise&&) = default;
119
120 Promise& operator=(const Promise&) = default;
121 Promise& operator=(Promise&&) = default;
122
123 CancelableFuture<T> Future() const {
124 return CancelableFuture<T>(state);
125 }
126
127 void Cancel()
128 {
129 state->Cancel();
130 }
131
132 bool IsCanceled() const
133 {
134 std::unique_lock lock(state->mutex);
135 return state->canceled;
136 }
137
138 void SetValue(const T &value)
139 {
140 std::unique_lock lock(state->mutex);
141 if (state->canceled || state->value) {
142 return;
143 }
144 state->value=value;
145 for (const auto &callback: state->callbacks) {
146 callback(value);
147 }
148 }
149
151 {
152 return FutureBreaker(state);
153 }
154 };
155
156 private:
157 std::shared_ptr<State> state;
158
159 CancelableFuture(const std::shared_ptr<State> &state): state(state)
160 {
161 // no code
162 };
163
164 public:
165 CancelableFuture(const CancelableFuture &) = default;
166 CancelableFuture(CancelableFuture &&) = default;
167
168 virtual ~CancelableFuture() = default;
169
170 CancelableFuture& operator=(const CancelableFuture &) = default;
171 CancelableFuture& operator=(CancelableFuture &&) = default;
172
176 void Cancel()
177 {
178 state->Cancel();
179 }
180
189 void OnComplete(const DoneCallback &callback)
190 {
191 std::unique_lock lock(state->mutex);
192 if (state->value) {
193 callback(state->value.value());
194 } else if (!state->canceled) {
195 state->callbacks.push_back(std::move(callback));
196 }
197 }
198
206 void OnCancel(const CancelCallback &callback)
207 {
208 std::unique_lock lock(state->mutex);
209 if (state->canceled) {
210 callback();
211 } else if (!state->value) {
212 state->cancelCallbacks.push_back(std::move(callback));
213 }
214 };
215
216 std::optional<T> Value()
217 {
218 std::unique_lock lock(state->mutex);
219 return state->value;
220 }
221
223 {
224 std::unique_lock lock(state->mutex);
225 return state->canceled;
226 }
227
228 std::future<T> StdFuture()
229 {
230 auto promisePtr=std::make_shared<std::promise<T>>();
231
232 OnComplete([promisePtr](const T &value) {
233 promisePtr->set_value(value);
234 });
235
236 OnCancel([promisePtr]() {
237 promisePtr->set_exception(std::make_exception_ptr(std::runtime_error("Canceled")));
238 });
239
240 return promisePtr->get_future();
241 }
242 };
243
244}
245
246#endif //LIBOSMSCOUT_CANCELABLEFUTURE_H
Definition Breaker.h:37
Definition CancelableFuture.h:70
FutureBreaker(FutureBreaker &&)=default
FutureBreaker & operator=(FutureBreaker &&)=default
bool IsAborted() const override
Definition CancelableFuture.h:96
FutureBreaker & operator=(const FutureBreaker &)=default
void Break() override
Definition CancelableFuture.h:91
void Reset() override
Definition CancelableFuture.h:102
friend class Promise
Definition CancelableFuture.h:75
FutureBreaker(const FutureBreaker &)=default
void SetValue(const T &value)
Definition CancelableFuture.h:138
bool IsCanceled() const
Definition CancelableFuture.h:132
Promise & operator=(Promise &&)=default
Promise(const Promise &)=default
FutureBreaker Breaker() const
Definition CancelableFuture.h:150
Promise & operator=(const Promise &)=default
void Cancel()
Definition CancelableFuture.h:127
CancelableFuture< T > Future() const
Definition CancelableFuture.h:123
Definition CancelableFuture.h:41
void OnCancel(const CancelCallback &callback)
Definition CancelableFuture.h:206
std::function< void(T const &)> DoneCallback
Definition CancelableFuture.h:43
bool IsCanceled()
Definition CancelableFuture.h:222
virtual ~CancelableFuture()=default
std::future< T > StdFuture()
Definition CancelableFuture.h:228
std::optional< T > Value()
Definition CancelableFuture.h:216
CancelableFuture & operator=(const CancelableFuture &)=default
CancelableFuture & operator=(CancelableFuture &&)=default
std::function< void()> CancelCallback
Definition CancelableFuture.h:44
void OnComplete(const DoneCallback &callback)
Definition CancelableFuture.h:189
CancelableFuture(const CancelableFuture &)=default
void Cancel()
Definition CancelableFuture.h:176
CancelableFuture(CancelableFuture &&)=default
OSMSCOUT_API Log log
Definition LoggerImpl.h:95
Definition Area.h:39
Definition CancelableFuture.h:47
bool canceled
Definition CancelableFuture.h:50
std::vector< DoneCallback > callbacks
Definition CancelableFuture.h:51
std::mutex mutex
Definition CancelableFuture.h:48
std::optional< T > value
Definition CancelableFuture.h:49
void Cancel()
Definition CancelableFuture.h:54
std::vector< CancelCallback > cancelCallbacks
Definition CancelableFuture.h:52