From d18576de7784f563e576cea70be9aa8eca5d209a Mon Sep 17 00:00:00 2001 From: Samuel Just Date: Tue, 1 Jun 2021 20:06:44 -0700 Subject: [PATCH] crimson/common/interruptible_future: introduce with_interruption_to_error Signed-off-by: Samuel Just --- src/crimson/common/interruptible_future.h | 56 +++++++++++++++++++---- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/src/crimson/common/interruptible_future.h b/src/crimson/common/interruptible_future.h index 61d40d77047..9bc6bb900ba 100644 --- a/src/crimson/common/interruptible_future.h +++ b/src/crimson/common/interruptible_future.h @@ -549,6 +549,8 @@ public: using core_type::failed; using core_type::core_type; + using value_type = typename core_type::value_type; + interruptible_future_detail(seastar::future&& fut) : core_type(std::move(fut)) {} @@ -963,9 +965,10 @@ public: } template - static inline auto with_interruption( - OpFunc&& opfunc, OnInterrupt&& efunc, InterruptCondParams&&... params) { + typename... Params> + static inline auto with_interruption_cond( + OpFunc&& opfunc, OnInterrupt&& efunc, InterruptCond &&cond, Params&&... params) { + using result_type = decltype(opfunc(std::forward(params)...)); // there may case like: // with_interruption([] { // return ... @@ -978,17 +981,54 @@ public: // so we have to avoid this scenario. // // TODO: maybe some kind of interrupt_cond stack should be implemented? - bool created = enable_interruption( - std::forward(params)...); - auto fut = futurize>::apply( - std::move(opfunc), std::make_tuple()) - .template handle_interruption(std::move(efunc)); + bool created = enable_interruption(std::forward(cond)); + + auto fut = futurize::invoke( + std::move(opfunc), std::forward(params)... + ).template handle_interruption(std::move(efunc)); + if (__builtin_expect(created, true)) { disable_interruption(); } return fut; } + template + static inline auto with_interruption( + OpFunc&& opfunc, OnInterrupt&& efunc, InterruptCondParams&&... params) { + return with_interruption_cond( + std::forward(opfunc), + std::forward(efunc), + InterruptCond(std::forward(params)...)); + } + + template + static inline auto with_interruption_to_error( + Func &&f, InterruptCond &&cond, Params&&... params) { + using func_result_t = std::invoke_result_t; + using func_ertr_t = + typename seastar::template futurize::errorator_type; + using with_trans_ertr = + typename func_ertr_t::template extend_ertr>; + + using value_type = typename func_result_t::value_type; + using ftype = typename std::conditional_t< + std::is_same_v, + typename with_trans_ertr::template future<>, + typename with_trans_ertr::template future>; + + return with_interruption_cond( + std::forward(f), + [](auto e) -> ftype { + return Error::make(); + }, + std::forward(cond), + std::forward(params)...); + } + template [[gnu::always_inline]] static auto wrap_function(Func&& func) { -- 2.39.5