25#include <seastar/core/future.hh>
26#include <seastar/util/modules.hh>
39template <
typename HeldState,
typename Future>
40class do_with_state final :
public continuation_base_from_future<Future>::type {
42 typename Future::promise_type _pr;
44 template<
typename... T>
45 explicit do_with_state(T&&... args) : _held(
std::forward<T>(args)...) {}
46 virtual void run_and_dispose() noexcept
override {
47 _pr.set_urgent_state(std::move(this->_state));
50 task* waiting_task() noexcept
override {
51 return _pr.waiting_task();
57 return _pr.get_future();
65template <
typename Tuple,
size_t... Idx>
68cherry_pick_tuple(std::index_sequence<Idx...>, Tuple&& tuple) {
69 return std::forward_as_tuple(std::get<Idx>(std::forward<Tuple>(tuple))...);
72template <
typename Tuple,
typename Seq>
75template <
typename Tuple,
size_t... Idx>
76struct subtuple<Tuple,
std::index_sequence<Idx...>> {
77 using type = std::tuple<std::decay_t<std::tuple_element_t<Idx, Tuple>>...>;
80template <
typename T1,
typename T2,
typename... More>
83do_with_impl(T1&& rv1, T2&& rv2, More&&... more) {
84 auto all = std::forward_as_tuple(
85 std::forward<T1>(rv1),
86 std::forward<T2>(rv2),
87 std::forward<More>(more)...);
88 constexpr size_t nr = std::tuple_size<
decltype(all)>::value - 1;
89 using idx = std::make_index_sequence<nr>;
90 auto&& just_values = cherry_pick_tuple(idx(), std::move(all));
91 auto&& just_func = std::move(std::get<nr>(std::move(all)));
92 using value_tuple =
typename subtuple<
decltype(all), idx>::type;
93 using ret_type =
decltype(std::apply(just_func, std::declval<value_tuple&>()));
94 auto task = std::apply(
96 return std::make_unique<internal::do_with_state<value_tuple, ret_type>>(std::forward<decltype(x)>(x)...);
98 std::move(just_values));
99 auto fut = std::apply(just_func, task->data());
100 if (fut.available()) {
103 auto ret = task->get_future();
104 internal::set_callback(std::move(fut), task.release());
110SEASTAR_MODULE_EXPORT_BEGIN
132template <
typename T1,
typename T2,
typename... More>
135do_with(T1&& rv1, T2&& rv2, More&&... more)
noexcept {
136 auto func = internal::do_with_impl<T1, T2, More...>;
137 return futurize_invoke(func, std::forward<T1>(rv1), std::forward<T2>(rv2), std::forward<More>(more)...);
147template<
typename Lock,
typename Func>
150 return lock.lock().then([&lock, func = std::forward<Func>(func)] ()
mutable {
151 return futurize_invoke(func).finally([&lock] {
159SEASTAR_MODULE_EXPORT_END
auto do_with(T1 &&rv1, T2 &&rv2, More &&... more) noexcept
Definition: do_with.hh:135
auto with_lock(Lock &lock, Func &&func)
Definition: do_with.hh:149
Seastar API namespace.
Definition: abort_on_ebadf.hh:26