From 769841a08c3e79985d9634f06c9ff4d62647dcda Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Wed, 6 Nov 2019 15:57:01 -0500 Subject: [PATCH] rgw: use new spawn() implementation Signed-off-by: Casey Bodley --- src/common/async/yield_context.h | 17 +++++++---------- src/rgw/CMakeLists.txt | 27 +++++++++++++++------------ src/rgw/rgw_aio.cc | 4 ++-- src/rgw/rgw_aio_throttle.h | 4 ++-- src/rgw/rgw_asio_frontend.cc | 20 +++++++++----------- 5 files changed, 35 insertions(+), 37 deletions(-) diff --git a/src/common/async/yield_context.h b/src/common/async/yield_context.h index 436192c02f7..fdfb3f5b8fe 100644 --- a/src/common/async/yield_context.h +++ b/src/common/async/yield_context.h @@ -22,31 +22,28 @@ #ifndef HAVE_BOOST_CONTEXT -// hide the dependencies on boost::context and boost::coroutines -namespace boost::asio { +// hide the dependency on boost::context +namespace spawn { struct yield_context; } #else // HAVE_BOOST_CONTEXT -#ifndef BOOST_COROUTINES_NO_DEPRECATION_WARNING -#define BOOST_COROUTINES_NO_DEPRECATION_WARNING -#endif -#include +#include #endif // HAVE_BOOST_CONTEXT -/// optional-like wrapper for a boost::asio::yield_context and its associated +/// optional-like wrapper for a spawn::yield_context and its associated /// boost::asio::io_context. operations that take an optional_yield argument /// will, when passed a non-empty yield context, suspend this coroutine instead /// of the blocking the thread of execution class optional_yield { boost::asio::io_context *c = nullptr; - boost::asio::yield_context *y = nullptr; + spawn::yield_context *y = nullptr; public: /// construct with a valid io and yield_context explicit optional_yield(boost::asio::io_context& c, - boost::asio::yield_context& y) noexcept + spawn::yield_context& y) noexcept : c(&c), y(&y) {} /// type tag to construct an empty object @@ -60,7 +57,7 @@ class optional_yield { boost::asio::io_context& get_io_context() const noexcept { return *c; } /// return a reference to the yield_context. only valid if non-empty - boost::asio::yield_context& get_yield_context() const noexcept { return *y; } + spawn::yield_context& get_yield_context() const noexcept { return *y; } }; // type tag object to construct an empty optional_yield diff --git a/src/rgw/CMakeLists.txt b/src/rgw/CMakeLists.txt index 3be5bcf3602..a90b72a29b6 100644 --- a/src/rgw/CMakeLists.txt +++ b/src/rgw/CMakeLists.txt @@ -157,6 +157,10 @@ target_include_directories(rgw_common SYSTEM PUBLIC "services") target_include_directories(rgw_common PUBLIC "${CMAKE_SOURCE_DIR}/src/dmclock/support/src") target_include_directories(rgw_common PUBLIC "${CMAKE_SOURCE_DIR}/src/fmt/include") +if(WITH_BOOST_CONTEXT) + target_link_libraries(rgw_common PUBLIC spawn) +endif() + if(WITH_LTTNG) # rgw/rgw_op.cc includes "tracing/rgw_op.h" # rgw/rgw_rados.cc includes "tracing/rgw_rados.h" @@ -233,7 +237,7 @@ if(WITH_CURL_OPENSSL) endif() if(WITH_BOOST_CONTEXT) - target_link_libraries(rgw_a PRIVATE spawn) + target_link_libraries(rgw_a PUBLIC spawn) endif() set(rgw_libs rgw_a) @@ -266,6 +270,10 @@ if(WITH_RADOSGW_BEAST_FRONTEND) rgw_dmclock_async_scheduler.cc) endif() +add_library(rgw_schedulers STATIC ${rgw_schedulers_srcs}) +target_link_libraries(rgw_schedulers + PUBLIC dmclock::dmclock) + add_library(radosgw SHARED ${radosgw_srcs} ${rgw_a_srcs} rgw_main.cc $) @@ -279,19 +287,17 @@ target_link_libraries(radosgw PRIVATE ${rgw_libs} rgw_schedulers PUBLIC dmclock::dmclock ) -if(WITH_RADOSGW_BEAST_FRONTEND AND WITH_RADOSGW_BEAST_OPENSSL) -target_link_libraries(radosgw - # used by rgw_asio_frontend.cc - PRIVATE OpenSSL::SSL) +if(WITH_RADOSGW_BEAST_FRONTEND) + target_link_libraries(rgw_schedulers PUBLIC spawn) + if(WITH_RADOSGW_BEAST_OPENSSL) + # used by rgw_asio_frontend.cc + target_link_libraries(radosgw PRIVATE OpenSSL::SSL) + endif() endif() set_target_properties(radosgw PROPERTIES OUTPUT_NAME radosgw VERSION 2.0.0 SOVERSION 2) install(TARGETS radosgw DESTINATION ${CMAKE_INSTALL_LIBDIR}) -add_library(rgw_schedulers STATIC ${rgw_schedulers_srcs}) -target_link_libraries(rgw_schedulers - PUBLIC dmclock::dmclock) - add_executable(radosgwd radosgw.cc) target_link_libraries(radosgwd radosgw librados cls_rgw_client cls_otp_client cls_lock_client cls_refcount_client @@ -415,9 +421,6 @@ endif() if(WITH_RADOSGW_KAFKA_ENDPOINT) target_link_libraries(rgw_admin_user PRIVATE RDKafka::RDKafka) endif() -if(WITH_BOOST_CONTEXT) - target_link_libraries(rgw_admin_user PRIVATE Boost::coroutine Boost::context) -endif() if(WITH_TESTS) add_executable(ceph_rgw_jsonparser diff --git a/src/rgw/rgw_aio.cc b/src/rgw/rgw_aio.cc index e32ba48c23c..48c83be98ac 100644 --- a/src/rgw/rgw_aio.cc +++ b/src/rgw/rgw_aio.cc @@ -80,12 +80,12 @@ struct Handler { template Aio::OpFunc aio_abstract(Op&& op, boost::asio::io_context& context, - boost::asio::yield_context yield) { + spawn::yield_context yield) { return [op = std::move(op), &context, yield] (Aio* aio, AioResult& r) mutable { // arrange for the completion Handler to run on the yield_context's strand // executor so it can safely call back into Aio without locking using namespace boost::asio; - async_completion init(yield); + async_completion init(yield); auto ex = get_associated_executor(init.completion_handler); auto& ref = r.obj.get_ref(); diff --git a/src/rgw/rgw_aio_throttle.h b/src/rgw/rgw_aio_throttle.h index 2b09b6ef51f..764469d7ed3 100644 --- a/src/rgw/rgw_aio_throttle.h +++ b/src/rgw/rgw_aio_throttle.h @@ -83,7 +83,7 @@ class BlockingAioThrottle final : public Aio, private Throttle { // functions must be called within the coroutine strand class YieldingAioThrottle final : public Aio, private Throttle { boost::asio::io_context& context; - boost::asio::yield_context yield; + spawn::yield_context yield; struct Handler; // completion callback associated with the waiter @@ -97,7 +97,7 @@ class YieldingAioThrottle final : public Aio, private Throttle { public: YieldingAioThrottle(uint64_t window, boost::asio::io_context& context, - boost::asio::yield_context yield) + spawn::yield_context yield) : Throttle(window), context(context), yield(yield) {} diff --git a/src/rgw/rgw_asio_frontend.cc b/src/rgw/rgw_asio_frontend.cc index deab1b0c66f..7896862d0a0 100644 --- a/src/rgw/rgw_asio_frontend.cc +++ b/src/rgw/rgw_asio_frontend.cc @@ -6,12 +6,10 @@ #include #include -#define BOOST_COROUTINES_NO_DEPRECATION_WARNING -#include -#include -#include #include +#include + #include "common/async/shared_mutex.h" #include "common/errno.h" @@ -40,11 +38,11 @@ template class StreamIO : public rgw::asio::ClientIO { CephContext* const cct; Stream& stream; - boost::asio::yield_context yield; + spawn::yield_context yield; parse_buffer& buffer; public: StreamIO(CephContext *cct, Stream& stream, rgw::asio::parser_type& parser, - boost::asio::yield_context yield, + spawn::yield_context yield, parse_buffer& buffer, bool is_ssl, const tcp::endpoint& local_endpoint, const tcp::endpoint& remote_endpoint) @@ -94,7 +92,7 @@ void handle_connection(boost::asio::io_context& context, SharedMutex& pause_mutex, rgw::dmclock::Scheduler *scheduler, boost::system::error_code& ec, - boost::asio::yield_context yield) + spawn::yield_context yield) { // limit header to 4k, since we read it all into a single flat_buffer static constexpr size_t header_limit = 4096; @@ -594,8 +592,8 @@ void AsioFrontend::accept(Listener& l, boost::system::error_code ec) // spawn a coroutine to handle the connection #ifdef WITH_RADOSGW_BEAST_OPENSSL if (l.use_ssl) { - boost::asio::spawn(context, - [this, s=std::move(socket)] (boost::asio::yield_context yield) mutable { + spawn::spawn(context, + [this, s=std::move(socket)] (spawn::yield_context yield) mutable { Connection conn{s}; auto c = connections.add(conn); // wrap the socket in an ssl stream @@ -622,8 +620,8 @@ void AsioFrontend::accept(Listener& l, boost::system::error_code ec) #else { #endif // WITH_RADOSGW_BEAST_OPENSSL - boost::asio::spawn(context, - [this, s=std::move(socket)] (boost::asio::yield_context yield) mutable { + spawn::spawn(context, + [this, s=std::move(socket)] (spawn::yield_context yield) mutable { Connection conn{s}; auto c = connections.add(conn); auto buffer = std::make_unique(); -- 2.39.5