]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/transaction: introduce TransactionConflictCondition interruptor
authorSamuel Just <sjust@redhat.com>
Thu, 3 Jun 2021 21:51:03 +0000 (14:51 -0700)
committerSamuel Just <sjust@redhat.com>
Wed, 23 Jun 2021 18:37:37 +0000 (11:37 -0700)
Signed-off-by: Samuel Just <sjust@redhat.com>
src/crimson/os/seastore/transaction.h

index a8a7998988d7eb3a30941235d672422459c01b1f..e9cd256494db325ee8f38aaf223b0daf6d776eca 100644 (file)
@@ -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 <typename Fut>
+  std::pair<bool, std::optional<Fut>> may_interrupt() {
+    if (t.conflicted) {
+      return {
+       true,
+       seastar::futurize<Fut>::make_exception_future(
+         transaction_conflict())};
+    } else {
+      return {false, std::optional<Fut>()};
+    }
+  }
+
+  template <typename T>
+  static constexpr bool is_interruption_v =
+    std::is_same_v<T, transaction_conflict>;
+
+
+  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 <typename E>
+using trans_iertr =
+  crimson::interruptible::interruptible_errorator<
+    TransactionConflictCondition,
+    E
+  >;
+
+template <typename F, typename... Args>
+auto with_trans_intr(Transaction &t, F &&f, Args&&... args) {
+  return trans_intr::with_interruption_to_error<crimson::ct_error::eagain>(
+    std::move(f),
+    TransactionConflictCondition(t),
+    t,
+    std::forward<Args>(args)...);
+}
+
+template <typename T>
+using with_trans_ertr = typename T::base_ertr::template extend<crimson::ct_error::eagain>;
+
 }