24#include <seastar/util/modules.hh>
25#include <seastar/util/noncopyable_function.hh>
26#include <seastar/util/optimized_optional.hh>
27#include <seastar/util/std-compat.hh>
30#include <boost/intrusive/list.hpp>
37namespace bi = boost::intrusive;
41SEASTAR_MODULE_EXPORT_BEGIN
50 virtual const char* what()
const noexcept override {
51 return "abort requested";
66 class subscription :
public bi::list_base_hook<bi::link_mode<bi::auto_unlink>> {
70 bool _aborted =
false;
73 : _target(std::move(target)) {
75 as._subscriptions.push_back(*
this);
79 struct naive_cb_tag {};
81 : _target([cb = std::move(naive_cb)] (
const std::optional<std::exception_ptr>&)
noexcept { cb(); }) {
83 as._subscriptions.push_back(*
this);
93 void on_abort(
const std::optional<std::exception_ptr>& ex)
noexcept {
95 if (!std::exchange(_aborted,
true)) {
104 : _target(std::move(other._target))
105 , _aborted(std::exchange(other._aborted,
true))
107 subscription_list_type::node_algorithms::swap_nodes(other.this_ptr(), this_ptr());
110 subscription& operator=(
subscription&& other)
noexcept(std::is_nothrow_move_assignable_v<subscription_callback_type>) {
111 if (
this != &other) {
112 _target = std::move(other._target);
113 _aborted = std::exchange(other._aborted,
true);
115 subscription_list_type::node_algorithms::swap_nodes(other.this_ptr(), this_ptr());
120 explicit operator bool() const noexcept {
126 using subscription_list_type = bi::list<subscription, bi::constant_time_size<false>>;
127 subscription_list_type _subscriptions;
128 std::exception_ptr _ex;
130 void do_request_abort(std::optional<std::exception_ptr> ex)
noexcept {
136 auto subs = std::move(_subscriptions);
137 while (!subs.empty()) {
138 subscription& s = subs.front();
144 abort_source() =
default;
145 virtual ~abort_source() =
default;
147 abort_source(abort_source&&) =
default;
148 abort_source& operator=(abort_source&&) =
default;
165 template <
typename Func>
166 requires (std::is_nothrow_invocable_r_v<void, Func, const std::optional<std::exception_ptr>&> ||
167 std::is_nothrow_invocable_r_v<void, Func>)
170 if constexpr (std::is_invocable_v<Func, std::exception_ptr>) {
173 return {
subscription(subscription::naive_cb_tag{}, *
this, std::forward<Func>(f)) };
181 do_request_abort(std::nullopt);
188 do_request_abort(std::make_optional(std::move(ex)));
194 template <
typename Exception>
196 do_request_abort(std::make_optional(std::make_exception_ptr(std::forward<Exception>(e))));
208 std::rethrow_exception(_ex);
226SEASTAR_MODULE_EXPORT_END
230#if FMT_VERSION < 100000
233struct fmt::formatter<
seastar::abort_requested_exception> : fmt::formatter<string_view> {
235 return fmt::format_to(ctx.out(),
"{}", e.what());
Definition: abort_source.hh:48
Definition: abort_source.hh:66
void on_abort(const std::optional< std::exception_ptr > &ex) noexcept
Definition: abort_source.hh:93
Definition: abort_source.hh:58
virtual std::exception_ptr get_default_exception() const noexcept
Definition: abort_source.hh:219
const std::exception_ptr & abort_requested_exception_ptr() const noexcept
Returns an exception with which an abort was requested.
Definition: abort_source.hh:213
void check() const
Throws a abort_requested_exception if cancellation has been requested.
Definition: abort_source.hh:206
void request_abort_ex(std::exception_ptr ex) noexcept
Definition: abort_source.hh:187
optimized_optional< subscription > subscribe(Func &&f)
Definition: abort_source.hh:169
void request_abort_ex(Exception &&e) noexcept
Definition: abort_source.hh:195
void request_abort() noexcept
Definition: abort_source.hh:180
bool abort_requested() const noexcept
Returns whether an abort has been requested.
Definition: abort_source.hh:200
Definition: optimized_optional.hh:48
Definition: stream.hh:127
Seastar API namespace.
Definition: abort_on_ebadf.hh:26
Definition: noncopyable_function.hh:37