diff --git a/src/crimson/common/errorator.h b/src/crimson/common/errorator.h index cee3e43db20..55710106341 100644 --- a/src/crimson/common/errorator.h +++ b/src/crimson/common/errorator.h @@ -73,12 +73,19 @@ private: // implement the errorable interface struct throwable_carrier{}; + static std::exception_ptr carrier_instance; static constexpr const std::type_info& exception_ptr_type_info() { return typeid(throwable_carrier); } auto to_exception_ptr() const { - return std::make_exception_ptr({}); + // error codes don't need to instantiate `std::exception_ptr` each + // time as the code is actually a part of the type itself. + // `std::make_exception_ptr()` on modern enough GCCs is quite cheap + // (see the Gleb Natapov's patch eradicating throw/catch there), + // but using one instance per type boils down the overhead to just + // ref-counting. + return carrier_instance; } static const auto& from_exception_ptr(std::exception_ptr) { return instance; @@ -87,6 +94,11 @@ private: friend class error_t>; }; +template +std::exception_ptr unthrowable_wrapper::carrier_instance = \ + std::make_exception_ptr< + unthrowable_wrapper::throwable_carrier>({}); + namespace _impl { template struct always_false : std::false_type {}; };