25 #ifndef SEASTAR_MODULE
26 #include <seastar/core/future.hh>
27 #include <seastar/core/abortable_fifo.hh>
28 #include <seastar/core/abort_on_expiry.hh>
29 #include <seastar/core/timed_out_error.hh>
30 #include <seastar/util/modules.hh>
41 template<
typename Clock>
46 template <
typename... T>
47 struct future_option_traits;
49 template <
typename Clock,
typename T>
50 struct future_option_traits<
with_clock<Clock>, T> {
51 using clock_type = Clock;
57 template <
typename Clock>
58 struct future_option_traits<with_clock<Clock>> {
59 using clock_type = Clock;
66 struct future_option_traits<T> :
public future_option_traits<with_clock<lowres_clock>, T> {
70 struct future_option_traits<> : future_option_traits<void> {
107 template<
typename... T>
110 using options = future_option_traits<T...>;
112 using clock =
typename options::clock_type;
113 using time_point =
typename clock::time_point;
114 using future_type =
typename future_option_traits<T...>::future_type;
115 using promise_type =
typename future_option_traits<T...>::promise_type;
116 using value_tuple_type =
typename future_type::tuple_type;
120 future_type _original_future;
125 std::optional<abort_on_expiry<clock>>
timer;
128 struct entry_expiry {
129 void operator()(entry& e) noexcept {
138 internal::abortable_fifo<entry, entry_expiry> _peers;
145 if (_original_future.failed()) {
146 _original_future.ignore_ready_future();
149 explicit shared_state(future_type f) noexcept
150 :
task(default_scheduling_group())
151 , _original_future(std::move(f)) {
153 void run_and_dispose() noexcept
override {
154 auto& state = _original_future._state;
155 if (_original_future.failed()) {
157 _peers.front().pr.set_exception(state.get_exception());
162 auto& p = _peers.front().pr;
164 p.set_value(state.get_value());
166 p.set_exception(std::current_exception());
171 _keepaliver.release();
174 task* waiting_task() noexcept
override {
178 future_type
get_future(time_point timeout = time_point::max()) noexcept {
186 if (!_original_future.available()) {
187 entry& e = _peers.emplace_back();
189 auto f = e.pr.get_future();
190 if (timeout != time_point::max()) {
191 e.timer.emplace(timeout);
193 _peers.make_back_abortable(as);
197 _original_future.set_task(*
this);
198 _keepaliver = this->shared_from_this();
201 }
else if (_original_future.failed()) {
216 if (!_original_future.available()) {
217 entry& e = _peers.emplace_back();
219 auto f = e.pr.get_future();
220 _peers.make_back_abortable(as);
223 _original_future.set_task(*
this);
224 _keepaliver = this->shared_from_this();
227 }
else if (_original_future.failed()) {
235 return _original_future.available();
238 bool failed()
const noexcept {
239 return _original_future.failed();
243 bool has_scheduled_task()
const noexcept {
244 return _keepaliver !=
nullptr;
252 : _state(make_lw_shared<shared_state>(std::move(f))) { }
266 future_type
get_future(time_point timeout = time_point::max()) const noexcept {
267 return _state->get_future(timeout);
277 return _state->get_future(as);
284 return _state->available();
291 return _state->failed();
295 operator future_type() const noexcept {
305 friend class shared_future_tester;
314 SEASTAR_MODULE_EXPORT
315 template <
typename... T>
319 using future_type =
typename shared_future_type::future_type;
320 using promise_type =
typename shared_future_type::promise_type;
321 using clock =
typename shared_future_type::clock;
322 using time_point =
typename shared_future_type::time_point;
323 using value_tuple_type =
typename shared_future_type::value_tuple_type;
325 promise_type _promise;
327 static constexpr
bool copy_noexcept = future_type::copy_noexcept;
332 shared_promise() : _promise(), _shared_future(_promise.get_future()) {
351 void set_value(
const value_tuple_type& result) noexcept(copy_noexcept) {
352 _promise.set_value(result);
357 _promise.set_value(std::move(result));
361 template <
typename... A>
363 _promise.set_value(std::forward<A>(a)...);
368 _promise.set_exception(std::move(ex));
372 template<
typename Exception>
374 set_exception(make_exception_ptr(std::forward<Exception>(e)));
384 return _shared_future.
failed();
Definition: abort_source.hh:49
Definition: abort_source.hh:59
Definition: shared_ptr.hh:150
A representation of a possibly not-yet-computed value.
Definition: future.hh:1238
promise - allows a future value to be made available at a later time.
Definition: future.hh:926
Like future except the result can be waited for by many fibers.
Definition: shared_future.hh:108
bool available() const noexcept
Returns true if the future is available (ready or failed)
Definition: shared_future.hh:283
shared_future(future_type f)
Forwards the result of future f into this shared_future.
Definition: shared_future.hh:251
future_type get_future(abort_source &as) const noexcept
Creates a new future which will resolve with the result of this shared_future.
Definition: shared_future.hh:276
bool failed() const noexcept
Returns true if the future is failed.
Definition: shared_future.hh:290
bool valid() const noexcept
Returns true if the instance is in valid state.
Definition: shared_future.hh:300
future_type get_future(time_point timeout=time_point::max()) const noexcept
Creates a new future which will resolve with the result of this shared_future.
Definition: shared_future.hh:266
Like promise except that its counterpart is shared_future instead of future.
Definition: shared_future.hh:316
void set_exception(Exception &&e) noexcept
Marks the shared_promise as failed, same as normal promise.
Definition: shared_future.hh:373
void set_value(value_tuple_type &&result) noexcept
Sets the shared_promise's value (as tuple; by moving), same as normal promise.
Definition: shared_future.hh:356
bool failed() const noexcept
Returns true if the underlying future is failed.
Definition: shared_future.hh:383
void set_exception(std::exception_ptr ex) noexcept
Marks the shared_promise as failed, same as normal promise.
Definition: shared_future.hh:367
void set_value(const value_tuple_type &result) noexcept(copy_noexcept)
Sets the shared_promise's value (as tuple; by copying), same as normal promise.
Definition: shared_future.hh:351
future_type get_shared_future(time_point timeout=time_point::max()) const noexcept
Gets new future associated with this promise. If the promise is not resolved before timeout the retur...
Definition: shared_future.hh:338
future_type get_shared_future(abort_source &as) const noexcept
Gets new future associated with this promise. If the promise is not resolved before abort source is t...
Definition: shared_future.hh:346
void set_value(A &&... a) noexcept
Sets the shared_promise's value (variadic), same as normal promise.
Definition: shared_future.hh:362
bool available() const noexcept
Returns true if the underlying future is available (ready or failed)
Definition: shared_future.hh:378
Definition: timed_out_error.hh:33
Definition: future.hh:558
Definition: future.hh:557
Changes the clock used by shared_future<> and shared_promise<> when passed as the first template para...
Definition: shared_future.hh:42
Definition: critical_alloc_section.hh:80
Seastar API namespace.
Definition: abort_on_ebadf.hh:26
scheduling_group current_scheduling_group() noexcept
Returns the current scheduling group.
Definition: scheduling.hh:400