]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/common: instantiate interrupt_cond in .cc
authorKefu Chai <kchai@redhat.com>
Sun, 8 Aug 2021 17:21:38 +0000 (01:21 +0800)
committerKefu Chai <kchai@redhat.com>
Mon, 9 Aug 2021 03:22:07 +0000 (11:22 +0800)
so we can explicitly instantiate it.

this should address the segfault when accessing interrupt_cond when
it is defined as a plain thread local storage template variable in the
header file.

it seems Clang is not able to identify the access to TLS variable and
the value of %fs segment register of the main thread is always zero if
interrupt_cond is defined as a plain global variable stored in
thread local storage.

Signed-off-by: Kefu Chai <kchai@redhat.com>
src/crimson/common/interruptible_future.h
src/crimson/os/seastore/CMakeLists.txt
src/crimson/os/seastore/transaction.cc [new file with mode: 0644]
src/test/crimson/test_interruptible_future.cc

index 51b50f04ebb6029c7fc0c2e4d3bfd3d907df75cf..8fdbd03cf2e681a3f36aebbfc8146fafa2d0f276 100644 (file)
 // interruptor::with_interruption() and helpers can be used by users to wrap a future in
 // the interruption machinery.
 
+namespace crimson::os::seastore {
+  class TransactionConflictCondition;
+}
+
+// GCC tries to instantiate
+// seastar::lw_shared_ptr<crimson::os::seastore::TransactionConflictCondition>.
+// but we *may* not have the definition of TransactionConflictCondition at this moment,
+// a full specialization for lw_shared_ptr_accessors helps to bypass the default
+// lw_shared_ptr_accessors implementation, where std::is_base_of<.., T> is used.
+namespace seastar::internal {
+  template<>
+  struct lw_shared_ptr_accessors<::crimson::os::seastore::TransactionConflictCondition, void>
+    : lw_shared_ptr_accessors_no_esft<::crimson::os::seastore::TransactionConflictCondition>
+  {};
+}
+
 namespace crimson::interruptible {
 
 struct ready_future_marker {};
@@ -58,6 +74,8 @@ using InterruptCondRef = seastar::lw_shared_ptr<InterruptCond>;
 
 template <typename InterruptCond>
 thread_local InterruptCondRef<InterruptCond> interrupt_cond;
+extern template thread_local InterruptCondRef<crimson::os::seastore::TransactionConflictCondition>
+interrupt_cond<crimson::os::seastore::TransactionConflictCondition>;
 
 template <typename InterruptCond, typename FutureType>
 class [[nodiscard]] interruptible_future_detail {};
@@ -439,7 +457,7 @@ public:
     using ex_type = typename trait::template arg<0>::type;
     return core_type::then_wrapped(
       [func=std::forward<Func>(func),
-      interrupt_condition=interrupt_cond<InterruptCond>](auto&& fut) mutable 
+      interrupt_condition=interrupt_cond<InterruptCond>](auto&& fut) mutable
       -> Result {
       if (!fut.failed()) {
        return seastar::make_ready_future<T>(fut.get());
index 08d7605528c7add6b95fe8046009654e571e9f5b..71050d099e0e121d736a2a11f94ac4e9171b47e0 100644 (file)
@@ -4,6 +4,7 @@ add_library(crimson-seastore STATIC
   segment_manager/ephemeral.cc
   segment_manager/block.cc
   transaction_manager.cc
+  transaction.cc
   journal.cc
   cache.cc
   lba_manager.cc
diff --git a/src/crimson/os/seastore/transaction.cc b/src/crimson/os/seastore/transaction.cc
new file mode 100644 (file)
index 0000000..ce02a95
--- /dev/null
@@ -0,0 +1,8 @@
+#include "transaction.h"
+#include "crimson/common/interruptible_future.h"
+
+namespace crimson::interruptible {
+template
+thread_local InterruptCondRef<::crimson::os::seastore::TransactionConflictCondition>
+interrupt_cond<::crimson::os::seastore::TransactionConflictCondition>;
+}
index bc59119f91767eda3f5d2bc2f97262888059ec27..c6af5f4957e98eb10b4c91fa8ee9055dde0ad383 100644 (file)
@@ -39,6 +39,12 @@ private:
   bool interrupt = false;
 };
 
+namespace crimson::interruptible {
+template
+thread_local InterruptCondRef<TestInterruptCondition>
+interrupt_cond<TestInterruptCondition>;
+}
+
 TEST_F(seastar_test_suite_t, basic)
 {
   using interruptor =