From 5a068cbf54639322eb9b13047cd0d37962b9869f Mon Sep 17 00:00:00 2001 From: Xuehan Xu Date: Sat, 2 Mar 2024 15:33:55 +0800 Subject: [PATCH] crimson/common/errorator: make assert_all() interfaces accept functors Signed-off-by: Xuehan Xu (cherry picked from commit a543db27108003fa4ace41a559efc5fb35555d23) --- src/crimson/common/errorator.h | 77 ++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/src/crimson/common/errorator.h b/src/crimson/common/errorator.h index 2eeb9e49bba..7113ccfa146 100644 --- a/src/crimson/common/errorator.h +++ b/src/crimson/common/errorator.h @@ -164,6 +164,9 @@ struct no_touch_error_marker {}; // AllowedErrorsV and also avoid the burden of throwing. template struct unthrowable_wrapper : error_t> { + + using error_type_t = ErrorT; + unthrowable_wrapper(const unthrowable_wrapper&) = delete; [[nodiscard]] static const auto& make() { static constexpr unthrowable_wrapper instance{}; @@ -206,14 +209,21 @@ struct unthrowable_wrapper : error_t> { class assert_failure { const char* const msg = nullptr; + std::function pre_assert; public: template assert_failure(const char (&msg)[N]) : msg(msg) { } assert_failure() = default; + template + assert_failure(Func&& f) + : pre_assert(std::forward(f)) {} no_touch_error_marker operator()(const unthrowable_wrapper&) { + if (pre_assert) { + pre_assert(); + } if (msg) { ceph_abort(msg); } else { @@ -258,6 +268,9 @@ std::exception_ptr unthrowable_wrapper::carrier_instance = \ template struct stateful_error_t : error_t> { + + using error_type_t = ErrorT; + template explicit stateful_error_t(Args&&... args) : ep(std::make_exception_ptr(std::forward(args)...)) { @@ -284,6 +297,36 @@ struct stateful_error_t : error_t> { }; } + class assert_failure { + const char* const msg = nullptr; + std::function pre_assert; + public: + template + assert_failure(const char (&msg)[N]) + : msg(msg) { + } + assert_failure() = default; + template + assert_failure(Func&& f) + : pre_assert(std::forward(f)) {} + + no_touch_error_marker operator()(stateful_error_t&& e) { + if (pre_assert) { + try { + std::rethrow_exception(e.ep); + } catch (const ErrorT& err) { + pre_assert(err); + } + } + if (msg) { + ceph_abort(msg); + } else { + ceph_abort(); + } + return no_touch_error_marker{}; + } + }; + private: std::exception_ptr ep; @@ -926,6 +969,34 @@ public: } }; + template + class assert_all_func_t { + public: + assert_all_func_t(Func &&f) + : f(std::forward(f)) {} + + template ...> + no_touch_error_marker operator()(ErrorT&& e) { + static_assert(contains_once_v>, + "discarding disallowed ErrorT"); + try { + std::rethrow_exception(e.ep); + } catch(const typename ErrorT::error_type_t& err) { + f(err); + } + ceph_abort(); + return no_touch_error_marker{}; + } + + private: + Func f; + }; + + template + static auto assert_all_func(Func &&f) { + return assert_all_func_t{std::forward(f)}; + } + template static decltype(auto) all_same_way(ErrorFunc&& error_func) { return all_same_way_t{std::forward(error_func)}; @@ -1252,15 +1323,21 @@ namespace ct_error { class assert_all { const char* const msg = nullptr; + std::function pre_assert; public: template assert_all(const char (&msg)[N]) : msg(msg) { } assert_all() = default; + assert_all(std::function &&f) + : pre_assert(std::move(f)) {} template no_touch_error_marker operator()(ErrorT&&) { + if (pre_assert) { + pre_assert(); + } if (msg) { ceph_abort(msg); } else { -- 2.39.5