From f0c2dcae588fedf5441978f9043d2aa8108da64f Mon Sep 17 00:00:00 2001 From: "Adam C. Emerson" Date: Tue, 8 Mar 2022 19:14:59 -0500 Subject: [PATCH] neorados: Switch to async_initiate This form of completion handling is compatible with C++20 Completions and generally more flexible stuff. Signed-off-by: Adam C. Emerson --- src/include/neorados/RADOS.hpp | 304 ++++++++++++++++++--------------- 1 file changed, 165 insertions(+), 139 deletions(-) diff --git a/src/include/neorados/RADOS.hpp b/src/include/neorados/RADOS.hpp index 9a54464216f61..04547335b09bd 100644 --- a/src/include/neorados/RADOS.hpp +++ b/src/include/neorados/RADOS.hpp @@ -477,6 +477,13 @@ private: std::aligned_storage_t impl; }; +// Clang reports a spurious warning that a captured `this` is unused +// in the public 'wrapper' functions that construct the completion +// handler and pass it to the actual worker member functions. The `this` is +// used to call the member functions, and even doing so explicitly +// (e.g. `this->execute`) doesn't silence it. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-lambda-capture" class RADOS final { public: @@ -520,11 +527,11 @@ public: template auto build(boost::asio::io_context& ioctx, CompletionToken&& token) { - boost::asio::async_completion init(token); - build(ioctx, - BuildComp::create(ioctx.get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + build(ioctx, BuildComp::create(ioctx.get_executor(), + std::move(handler))); + }, token); } private: @@ -537,11 +544,12 @@ public: static auto make_with_cct(CephContext* cct, boost::asio::io_context& ioctx, CompletionToken&& token) { - boost::asio::async_completion init(token); - make_with_cct(cct, ioctx, - BuildComp::create(ioctx.get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&](auto&& handler) { + make_with_cct(cct, ioctx, + BuildComp::create(ioctx.get_executor(), + std::move(handler))); + }, token); } static RADOS make_with_librados(librados::Rados& rados); @@ -565,24 +573,26 @@ public: ceph::buffer::list* bl, CompletionToken&& token, uint64_t* objver = nullptr, const blkin_trace_info* trace_info = nullptr) { - boost::asio::async_completion init(token); - execute(o, ioc, std::move(op), bl, - ReadOp::Completion::create(get_executor(), - std::move(init.completion_handler)), - objver, trace_info); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + execute(o, ioc, std::move(op), bl, + ReadOp::Completion::create(get_executor(), + std::move(handler)), + objver, trace_info); + }, token); } template auto execute(const Object& o, const IOContext& ioc, WriteOp&& op, CompletionToken&& token, uint64_t* objver = nullptr, const blkin_trace_info* trace_info = nullptr) { - boost::asio::async_completion init(token); - execute(o, ioc, std::move(op), - Op::Completion::create(get_executor(), - std::move(init.completion_handler)), - objver, trace_info); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + execute(o, ioc, std::move(op), + WriteOp::Completion::create(get_executor(), + std::move(handler)), + objver, trace_info); + }, token); } boost::uuids::uuid get_fsid() const noexcept; @@ -593,11 +603,11 @@ public: template auto lookup_pool(std::string_view name, CompletionToken&& token) { - boost::asio::async_completion init(token); - lookup_pool(name, - LookupPoolComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + lookup_pool(name, LookupPoolComp::create(get_executor(), + std::move(handler))); + }, token); } std::optional get_pool_alignment(int64_t pool_id); @@ -606,24 +616,24 @@ public: using LSPoolsComp = ceph::async::Completion; template auto list_pools(CompletionToken&& token) { - boost::asio::async_completion init(token); - list_pools(LSPoolsComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [this](auto&& handler) { + list_pools(LSPoolsComp::create(get_executor(), + std::move(handler))); + }, token); } - - using SimpleOpSig = void(boost::system::error_code); using SimpleOpComp = ceph::async::Completion; template auto create_pool_snap(int64_t pool, std::string_view snapName, CompletionToken&& token) { - boost::asio::async_completion init(token); - create_pool_snap(pool, snapName, - SimpleOpComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + create_pool_snap(pool, snapName, + SimpleOpComp::create(get_executor(), + std::move(handler))); + }, token); } using SMSnapSig = void(boost::system::error_code, std::uint64_t); @@ -631,63 +641,67 @@ public: template auto allocate_selfmanaged_snap(int64_t pool, CompletionToken&& token) { - boost::asio::async_completion init(token); - allocate_selfmanaged_snap(pool, - SMSnapComp::create( - get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + allocage_selfmanaged_snap(pool, + SMSnapComp::create(get_executor(), + std::move(handler))); + }, token); } template auto delete_pool_snap(int64_t pool, std::string_view snapName, CompletionToken&& token) { - boost::asio::async_completion init(token); - delete_pool_snap(pool, snapName, - SimpleOpComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + delete_pool_snap(pool, snapName, + SimpleOpComp::create(get_executor(), + std::move(handler))); + }, token); } template auto delete_selfmanaged_snap(int64_t pool, std::string_view snapName, CompletionToken&& token) { - boost::asio::async_completion init(token); - delete_selfmanaged_snap(pool, snapName, - SimpleOpComp::create( - get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + delete_selfmanaged_snap(pool, snapName, + SimpleOpComp::create(get_executor(), + std::move(handler))); + }, token); } template auto create_pool(std::string_view name, std::optional crush_rule, CompletionToken&& token) { - boost::asio::async_completion init(token); - create_pool(name, crush_rule, - SimpleOpComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + create_pool(name, crush_rule, + SimpleOpComp::create(get_executor(), + std::move(handler))); + }, token); } template auto delete_pool(std::string_view name, CompletionToken&& token) { - boost::asio::async_completion init(token); - delete_pool(name, - SimpleOpComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + delete_pool(name, + SimpleOpComp::create(get_executor(), + std::move(handler))); + }, token); } template auto delete_pool(int64_t pool, CompletionToken&& token) { - boost::asio::async_completion init(token); - delete_pool(pool, - SimpleOpComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + delete_pool(pool, + SimpleOpComp::create(get_executor(), + std::move(handler))); + }, token); } using PoolStatSig = void(boost::system::error_code, @@ -697,11 +711,12 @@ public: template auto stat_pools(const std::vector& pools, CompletionToken&& token) { - boost::asio::async_completion init(token); - stat_pools(pools, - PoolStatComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + stat_pools(pools, + PoolStatComp::create(get_executor(), + std::move(handler))); + }, token); } using StatFSSig = void(boost::system::error_code, @@ -710,10 +725,11 @@ public: template auto statfs(std::optional pool, CompletionToken&& token) { - boost::asio::async_completion init(token); - ceph_statfs(pool, StatFSComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + statfs(pool, StatFSComp::create(get_executor(), + std::move(handler))); + }, token); } using WatchCB = fu2::unique_function timeout, WatchCB&& cb, CompletionToken&& token) { - boost::asio::async_completion init(token); - watch(o, ioc, timeout, std::move(cb), - WatchComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + watch(o, ioc, timeout, cb, WatchComp::create(get_executor(), + std::move(handler))); + }, token); } template @@ -743,21 +759,22 @@ public: uint64_t cookie, ceph::buffer::list&& bl, CompletionToken&& token) { - boost::asio::async_completion init(token); - notify_ack(o, ioc, notify_id, cookie, std::move(bl), - SimpleOpComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + notify_ack(o, ioc, notify_id, cookie, std::move(bl), + SimpleOpComp::create(get_executor(), + std::move(handler))); + }, token); } template auto unwatch(std::uint64_t cookie, const IOContext& ioc, CompletionToken&& token) { - boost::asio::async_completion init(token); - unwatch(cookie, ioc, - SimpleOpComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + unwatch(cookie, ioc, SimpleOpComp::create(get_executor(), + std::move(handler))); + }, token); } // This is one of those places where having to force everything into @@ -768,10 +785,11 @@ public: using VoidOpComp = ceph::async::Completion; template auto flush_watch(CompletionToken&& token) { - boost::asio::async_completion init(token); - flush_watch(VoidOpComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [this](auto&& handler) { + flush_watch(VoidOpComp::create(get_executor(), + std::move(handler))); + }, token); } using NotifySig = void(boost::system::error_code, ceph::buffer::list); @@ -780,12 +798,12 @@ public: auto notify(const Object& oid, const IOContext& ioc, ceph::buffer::list&& bl, std::optional timeout, CompletionToken&& token) { - boost::asio::async_completion init(token); - notify(oid, ioc, std::move(bl), timeout, - NotifyComp::create(get_executor(), - std::move(init.completion_handler))); - - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + notify(oid, ioc, std::move(bl), timeout, + NotifyComp::create(get_executor(), + std::move(handler))); + }, token); } // The versions with pointers are fine for coroutines, but @@ -799,11 +817,12 @@ public: const Cursor& end, const std::uint32_t max, const ceph::buffer::list& filter, CompletionToken&& token) { - boost::asio::async_completion init(token); - enumerate_objects(ioc, begin, end, max, filter, - EnumerateComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + enumerate_objects(ioc, begin, end, max, filter, + EnumerateComp::create(get_executor(), + std::move(handler))); + }, token); } using CommandSig = void(boost::system::error_code, @@ -812,61 +831,67 @@ public: template auto osd_command(int osd, std::vector&& cmd, ceph::buffer::list&& in, CompletionToken&& token) { - boost::asio::async_completion init(token); - osd_command(osd, std::move(cmd), std::move(in), - CommandComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + osd_command(osd, std::move(cmd), std::move(in), + CommandComp::create(get_executor(), + std::move(handler))); + }, token); } template auto pg_command(PG pg, std::vector&& cmd, ceph::buffer::list&& in, CompletionToken&& token) { - boost::asio::async_completion init(token); - pg_command(pg, std::move(cmd), std::move(in), - CommandComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + pg_command(pg, std::move(cmd), std::move(in), + CommandComp::create(get_executor(), + std::move(handler))); + }, token); } template - auto mon_command(std::vector command, + auto mon_command(const std::vector& command, const ceph::buffer::list& bl, std::string* outs, ceph::buffer::list* outbl, CompletionToken&& token) { - boost::asio::async_completion init(token); - mon_command(command, bl, outs, outbl, - SimpleOpComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + mon_command(command, bl, outs, outbl, + SimpleOpComp::create(get_executor(), + std::move(handler))); + }, token); } template auto enable_application(std::string_view pool, std::string_view app_name, bool force, CompletionToken&& token) { - boost::asio::async_completion init(token); - enable_application(pool, app_name, force, - SimpleOpComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + enable_application(pool, app_name, force, + SimpleOpComp::create(get_executor(), + std::move(handler))); + }, token); } template auto blocklist_add(std::string_view client_address, std::optional expire, CompletionToken&& token) { - boost::asio::async_completion init(token); - blocklist_add(client_address, expire, - SimpleOpComp::create(get_executor(), - std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [&, this](auto&& handler) { + blocklist_add(client_address, expire, + SimpleOpComp::create(get_executor(), + std::move(handler))); + }, token); } template auto wait_for_latest_osd_map(CompletionToken&& token) { - boost::asio::async_completion init(token); - wait_for_latest_osd_map( - SimpleOpComp::create(get_executor(), std::move(init.completion_handler))); - return init.result.get(); + return boost::asio::async_initiate( + [this](auto&& handler) { + wait_for_latest_osd_map(SimpleOpComp::create(get_executor(), + std::move(handler))); + }, token); } uint64_t instance_id() const; @@ -962,6 +987,7 @@ private: // Proxy object to provide access to low-level RADOS messaging clients std::unique_ptr impl; }; +#pragma clang diagnostic pop enum class errc { pool_dne = 1, -- 2.39.5