From 9b6a2040b727599ef41a4f9a765a2cb1dfee1f98 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Fri, 10 Jul 2020 12:46:27 -0400 Subject: [PATCH] librbd: allocate the asio strands directly on the heap This will assist with potential race condition debugging since the stand pointer will be invalidated by the time the strand has been destructed and shut down. Signed-off-by: Jason Dillaman --- src/librbd/AsioEngine.cc | 4 +++- src/librbd/AsioEngine.h | 4 ++-- src/librbd/asio/ContextWQ.cc | 6 ++++-- src/librbd/asio/ContextWQ.h | 5 +++-- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/librbd/AsioEngine.cc b/src/librbd/AsioEngine.cc index d8cf48d3969..1a46b590479 100644 --- a/src/librbd/AsioEngine.cc +++ b/src/librbd/AsioEngine.cc @@ -21,7 +21,8 @@ AsioEngine::AsioEngine(std::shared_ptr rados) neorados::RADOS::make_with_librados(*rados))), m_cct(m_rados_api->cct()), m_io_context(m_rados_api->get_io_context()), - m_api_strand(m_io_context), + m_api_strand(std::make_unique( + m_io_context)), m_context_wq(std::make_unique(m_cct, m_io_context)) { ldout(m_cct, 20) << dendl; @@ -40,6 +41,7 @@ AsioEngine::AsioEngine(librados::IoCtx& io_ctx) AsioEngine::~AsioEngine() { ldout(m_cct, 20) << dendl; + m_api_strand.reset(); } void AsioEngine::dispatch(Context* ctx, int r) { diff --git a/src/librbd/AsioEngine.h b/src/librbd/AsioEngine.h index 00cb7f7f8a1..d2730fd9880 100644 --- a/src/librbd/AsioEngine.h +++ b/src/librbd/AsioEngine.h @@ -45,7 +45,7 @@ public: inline boost::asio::io_context::strand& get_api_strand() { // API client callbacks should never fire concurrently - return m_api_strand; + return *m_api_strand; } inline asio::ContextWQ* get_work_queue() { @@ -69,7 +69,7 @@ private: CephContext* m_cct; boost::asio::io_context& m_io_context; - boost::asio::io_context::strand m_api_strand; + std::unique_ptr m_api_strand; std::unique_ptr m_context_wq; }; diff --git a/src/librbd/asio/ContextWQ.cc b/src/librbd/asio/ContextWQ.cc index 2d12d5080fd..4f6c7277080 100644 --- a/src/librbd/asio/ContextWQ.cc +++ b/src/librbd/asio/ContextWQ.cc @@ -15,7 +15,8 @@ namespace librbd { namespace asio { ContextWQ::ContextWQ(CephContext* cct, boost::asio::io_context& io_context) - : m_cct(cct), m_io_context(io_context), m_strand(io_context), + : m_cct(cct), m_io_context(io_context), + m_strand(std::make_unique(io_context)), m_queued_ops(0) { ldout(m_cct, 20) << dendl; } @@ -23,6 +24,7 @@ ContextWQ::ContextWQ(CephContext* cct, boost::asio::io_context& io_context) ContextWQ::~ContextWQ() { ldout(m_cct, 20) << dendl; drain(); + m_strand.reset(); } void ContextWQ::drain() { @@ -40,7 +42,7 @@ void ContextWQ::drain_handler(Context* ctx) { // new items might be queued while we are trying to drain, so we // might need to post the handler multiple times - boost::asio::post(m_strand, [this, ctx]() { drain_handler(ctx); }); + boost::asio::post(*m_strand, [this, ctx]() { drain_handler(ctx); }); } } // namespace asio diff --git a/src/librbd/asio/ContextWQ.h b/src/librbd/asio/ContextWQ.h index 3197756205d..85c25416121 100644 --- a/src/librbd/asio/ContextWQ.h +++ b/src/librbd/asio/ContextWQ.h @@ -7,6 +7,7 @@ #include "include/common_fwd.h" #include "include/Context.h" #include +#include #include #include #include @@ -26,7 +27,7 @@ public: // ensure all legacy ContextWQ users are dispatched sequentially for // backwards compatibility (i.e. might not be concurrent thread-safe) - boost::asio::post(m_strand, [this, ctx, r]() { + boost::asio::post(*m_strand, [this, ctx, r]() { ctx->complete(r); ceph_assert(m_queued_ops > 0); @@ -37,7 +38,7 @@ public: private: CephContext* m_cct; boost::asio::io_context& m_io_context; - boost::asio::io_context::strand m_strand; + std::unique_ptr m_strand; std::atomic m_queued_ops; -- 2.39.5