From: Samuel Just Date: Thu, 3 Jun 2021 21:51:03 +0000 (-0700) Subject: crimson/os/seastore/transaction: introduce TransactionConflictCondition interruptor X-Git-Tag: v17.1.0~1567^2~6 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=4eec23ba80e40ee47600c2488505b62057a552da;p=ceph.git crimson/os/seastore/transaction: introduce TransactionConflictCondition interruptor Signed-off-by: Samuel Just --- diff --git a/src/crimson/os/seastore/transaction.h b/src/crimson/os/seastore/transaction.h index a8a7998988d7e..e9cd256494db3 100644 --- a/src/crimson/os/seastore/transaction.h +++ b/src/crimson/os/seastore/transaction.h @@ -167,6 +167,7 @@ public: } friend class crimson::os::seastore::SeaStore; + friend class TransactionConflictCondition; }; using TransactionRef = Transaction::Ref; @@ -179,4 +180,63 @@ inline TransactionRef make_test_transaction() { ); } +struct TransactionConflictCondition { + class transaction_conflict final : public std::exception { + public: + const char* what() const noexcept final { + return "transaction conflict detected"; + } + }; + +public: + TransactionConflictCondition(Transaction &t) : t(t) {} + + template + std::pair> may_interrupt() { + if (t.conflicted) { + return { + true, + seastar::futurize::make_exception_future( + transaction_conflict())}; + } else { + return {false, std::optional()}; + } + } + + template + static constexpr bool is_interruption_v = + std::is_same_v; + + + static bool is_interruption(std::exception_ptr& eptr) { + return *eptr.__cxa_exception_type() == typeid(transaction_conflict); + } + +private: + Transaction &t; +}; + +using trans_intr = crimson::interruptible::interruptor< + TransactionConflictCondition + >; + +template +using trans_iertr = + crimson::interruptible::interruptible_errorator< + TransactionConflictCondition, + E + >; + +template +auto with_trans_intr(Transaction &t, F &&f, Args&&... args) { + return trans_intr::with_interruption_to_error( + std::move(f), + TransactionConflictCondition(t), + t, + std::forward(args)...); +} + +template +using with_trans_ertr = typename T::base_ertr::template extend; + }