include_directories(SYSTEM src/blkin/blkin-lib)
endif(WITH_BLKIN)
-option(WITH_BOOST_CONTEXT "Enable boost::asio stackful coroutines" ON)
-if(WITH_BOOST_CONTEXT)
- set(HAVE_BOOST_CONTEXT ON)
-endif()
-
#option for RGW
option(WITH_RADOSGW "Rados Gateway is enabled" ON)
option(WITH_RADOSGW_FCGI_FRONTEND "Rados Gateway's FCGI frontend is enabled" OFF)
if(WITH_RADOSGW_FCGI_FRONTEND)
find_package(fcgi REQUIRED)
endif()
- if(WITH_RADOSGW_BEAST_FRONTEND AND NOT WITH_BOOST_CONTEXT)
- message(WARNING "disabling WITH_RADOSGW_BEAST_FRONTEND, which depends on WITH_BOOST_CONTEXT")
- set(WITH_RADOSGW_BEAST_FRONTEND OFF)
- endif()
find_package(OATH REQUIRED)
# https://curl.haxx.se/docs/install.html mentions the
# Boost::thread depends on Boost::atomic, so list it explicitly.
set(BOOST_COMPONENTS
atomic chrono thread system regex random program_options date_time
- iostreams)
+ iostreams context coroutine)
set(BOOST_HEADER_COMPONENTS container)
if(WITH_MGR)
list(APPEND BOOST_COMPONENTS
python${MGR_PYTHON_VERSION_MAJOR}${MGR_PYTHON_VERSION_MINOR})
endif()
-if(WITH_BOOST_CONTEXT)
- list(APPEND BOOST_COMPONENTS context coroutine)
-endif()
if(WITH_SEASTAR)
list(APPEND BOOST_COMPONENTS filesystem timer)
endif()
add_subdirectory(rbd_replay)
endif(WITH_RBD)
-if(WITH_BOOST_CONTEXT)
- set(SPAWN_BUILD_TESTS OFF CACHE INTERNAL "disable building of spawn unit tests")
- set(SPAWN_INSTALL OFF CACHE INTERNAL "disable installation of spawn headers")
- add_subdirectory(spawn)
-endif()
+set(SPAWN_BUILD_TESTS OFF CACHE INTERNAL "disable building of spawn unit tests")
+set(SPAWN_INSTALL OFF CACHE INTERNAL "disable installation of spawn headers")
+add_subdirectory(spawn)
# RadosGW
if(WITH_KVS)
#include "acconfig.h"
-#ifndef HAVE_BOOST_CONTEXT
-
-// hide the dependency on boost::context
-namespace spawn {
-struct yield_context;
-}
-
-#else // HAVE_BOOST_CONTEXT
#include <spawn/spawn.hpp>
-#endif // HAVE_BOOST_CONTEXT
-
-
/// 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
/* Defined if getentropy() is available */
#cmakedefine HAVE_GETENTROPY
-/* Defined if boost::context is available */
-#cmakedefine HAVE_BOOST_CONTEXT
-
/* Defined if libradosstriper is enabled: */
#cmakedefine WITH_LIBRADOSSTRIPER
target_include_directories(rgw_common PRIVATE "${CMAKE_BINARY_DIR}/src/lua")
-if(WITH_BOOST_CONTEXT)
- target_include_directories(rgw_common PRIVATE
- $<TARGET_PROPERTY:spawn,INTERFACE_INCLUDE_DIRECTORIES>)
-endif()
+target_include_directories(rgw_common PRIVATE
+ $<TARGET_PROPERTY:spawn,INTERFACE_INCLUDE_DIRECTORIES>)
if(WITH_LTTNG)
# rgw/rgw_op.cc includes "tracing/rgw_op.h"
endif()
target_link_libraries(rgw_a PRIVATE liblua)
-
-if(WITH_BOOST_CONTEXT)
- target_link_libraries(rgw_a PUBLIC spawn)
-endif()
+target_link_libraries(rgw_a PUBLIC spawn)
set(rgw_libs rgw_a)
if(WITH_RADOSGW_AMQP_ENDPOINT)
};
}
-#ifdef HAVE_BOOST_CONTEXT
struct Handler {
Aio* throttle = nullptr;
AioResult& r;
bind_executor(ex, Handler{aio, r}));
};
}
-#endif // HAVE_BOOST_CONTEXT
template <typename Op>
Aio::OpFunc aio_abstract(Op&& op, optional_yield y) {
static_assert(std::is_base_of_v<librados::ObjectOperation, std::decay_t<Op>>);
static_assert(!std::is_lvalue_reference_v<Op>);
static_assert(!std::is_const_v<Op>);
-#ifdef HAVE_BOOST_CONTEXT
if (y) {
return aio_abstract(std::forward<Op>(op), y.get_io_context(),
y.get_yield_context());
}
-#endif
return aio_abstract(std::forward<Op>(op));
}
return std::move(completed);
}
-#ifdef HAVE_BOOST_CONTEXT
-
template <typename CompletionToken>
auto YieldingAioThrottle::async_wait(CompletionToken&& token)
{
}
return std::move(completed);
}
-#endif // HAVE_BOOST_CONTEXT
-
} // namespace rgw
AioResultList drain() override final;
};
-#ifdef HAVE_BOOST_CONTEXT
// a throttle that yields the coroutine instead of blocking. all public
// functions must be called within the coroutine strand
class YieldingAioThrottle final : public Aio, private Throttle {
AioResultList drain() override final;
};
-#endif // HAVE_BOOST_CONTEXT
// return a smart pointer to Aio
inline auto make_throttle(uint64_t window_size, optional_yield y)
{
-#ifdef HAVE_BOOST_CONTEXT
std::unique_ptr<Aio> aio;
if (y) {
aio = std::make_unique<YieldingAioThrottle>(window_size,
aio = std::make_unique<BlockingAioThrottle>(window_size);
}
return aio;
-#else
- return std::make_optional<BlockingAioThrottle>(window_size);
-#endif
}
} // namespace rgw
if (done) {
return ret;
}
-#ifdef HAVE_BOOST_CONTEXT
if (y) {
auto& context = y.get_io_context();
auto& yield = y.get_yield_context();
if (is_asio_thread) {
dout(20) << "WARNING: blocking http request" << dendl;
}
-#endif
std::unique_lock l{lock};
cond.wait(l, [this]{return done==true;});
return ret;
if (done) {
return ret;
}
-#ifdef HAVE_BOOST_CONTEXT
if (y) {
- auto& io_ctx = y.get_io_context();
+ auto& io_ctx = y.get_io_context();
auto& yield_ctx = y.get_yield_context();
boost::system::error_code ec;
async_wait(io_ctx, yield_ctx[ec]);
return -ec.value();
}
-#endif
std::unique_lock l(lock);
cond.wait(l, [this]{return (done==true);});
return ret;
if (done) {
return ret;
}
-#ifdef HAVE_BOOST_CONTEXT
if (y) {
auto& io_ctx = y.get_io_context();
auto& yield_ctx = y.get_yield_context();
async_wait(io_ctx, yield_ctx[ec]);
return -ec.value();
}
-#endif
std::unique_lock l(lock);
cond.wait(l, [this]{return (done==true);});
return ret;
return -ECANCELED;
}
-#ifdef HAVE_BOOST_CONTEXT
if (y) {
auto& context = y.get_io_context();
auto& yield = y.get_yield_context();
waiters.erase(waiters.iterator_to(waiter));
return -ec.value();
}
-#endif
cond.wait_for(lock, duration);
librados::ObjectReadOperation *op, bufferlist* pbl,
optional_yield y, int flags)
{
-#ifdef HAVE_BOOST_CONTEXT
// given a yield_context, call async_operate() to yield the coroutine instead
// of blocking
if (y) {
if (is_asio_thread) {
dout(20) << "WARNING: blocking librados call" << dendl;
}
-#endif
return ioctx.operate(oid, op, nullptr, flags);
}
librados::ObjectWriteOperation *op, optional_yield y,
int flags)
{
-#ifdef HAVE_BOOST_CONTEXT
if (y) {
auto& context = y.get_io_context();
auto& yield = y.get_yield_context();
if (is_asio_thread) {
dout(20) << "WARNING: blocking librados call" << dendl;
}
-#endif
return ioctx.operate(oid, op, flags);
}
bufferlist& bl, uint64_t timeout_ms, bufferlist* pbl,
optional_yield y)
{
-#ifdef HAVE_BOOST_CONTEXT
if (y) {
auto& context = y.get_io_context();
auto& yield = y.get_yield_context();
if (is_asio_thread) {
dout(20) << "WARNING: blocking librados call" << dendl;
}
-#endif
return ioctx.notify2(oid, bl, timeout_ms, pbl);
}
$<TARGET_PROPERTY:GTest::GTest,INTERFACE_INCLUDE_DIRECTORIES>)
add_subdirectory(cls_hello)
-if(WITH_BOOST_CONTEXT)
add_subdirectory(cls_fifo)
-endif()
add_subdirectory(cls_lock)
add_subdirectory(cls_cas)
add_subdirectory(cls_log)
${UNITTEST_LIBS}
${EXTRALIBS}
)
-if(WITH_BOOST_CONTEXT)
target_link_libraries(ceph_test_librgw_file_nfsns spawn)
-endif()
-
# ceph_test_librgw_file_aw (nfs write transaction [atomic write] tests)
add_executable(ceph_test_librgw_file_aw
${UNITTEST_LIBS}
${EXTRALIBS}
)
-if(WITH_BOOST_CONTEXT)
target_link_libraries(ceph_test_librgw_file_marker spawn)
-endif()
# ceph_test_rgw_token
add_executable(ceph_test_rgw_token
-if(WITH_BOOST_CONTEXT)
add_executable(ceph_test_cls_fifo
test_cls_fifo.cc
)
install(TARGETS
ceph_test_cls_fifo
DESTINATION ${CMAKE_INSTALL_BINDIR})
-endif()
add_executable(ceph_test_rados_api_asio asio.cc)
target_link_libraries(ceph_test_rados_api_asio global
- librados ${UNITTEST_LIBS})
-if(WITH_BOOST_CONTEXT)
- target_link_libraries(ceph_test_rados_api_asio Boost::coroutine Boost::context)
-endif()
+ librados ${UNITTEST_LIBS} Boost::coroutine Boost::context)
add_executable(ceph_test_rados_api_list
list.cc
tier_cxx.cc
$<TARGET_OBJECTS:unit-main>)
target_link_libraries(ceph_test_rados_api_tier_pp
- librados global ${UNITTEST_LIBS} Boost::system radostest-cxx cls_cas_internal)
-if(WITH_BOOST_CONTEXT)
- target_link_libraries(ceph_test_rados_api_tier_pp spawn)
-endif()
+ librados global ${UNITTEST_LIBS} Boost::system radostest-cxx cls_cas_internal
+ spawn)
add_executable(ceph_test_rados_api_snapshots
snapshots.cc)
#include "common/errno.h"
#include "global/global_init.h"
-#ifdef HAVE_BOOST_CONTEXT
#define BOOST_COROUTINES_NO_DEPRECATION_WARNING
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/asio/spawn.hpp>
-#endif
#include <boost/asio/use_future.hpp>
#define dout_subsys ceph_subsys_rados
EXPECT_THROW(f2.get(), boost::system::system_error);
}
-#ifdef HAVE_BOOST_CONTEXT
TEST_F(AsioRados, AsyncReadYield)
{
boost::asio::io_service service;
service.run();
}
-#endif
TEST_F(AsioRados, AsyncWriteCallback)
{
EXPECT_THROW(f2.get(), boost::system::system_error);
}
-#ifdef HAVE_BOOST_CONTEXT
TEST_F(AsioRados, AsyncWriteYield)
{
boost::asio::io_service service;
service.run();
}
-#endif
TEST_F(AsioRados, AsyncReadOperationCallback)
{
EXPECT_THROW(f2.get(), boost::system::system_error);
}
-#ifdef HAVE_BOOST_CONTEXT
TEST_F(AsioRados, AsyncReadOperationYield)
{
boost::asio::io_service service;
service.run();
}
-#endif
TEST_F(AsioRados, AsyncWriteOperationCallback)
{
EXPECT_THROW(f2.get(), boost::system::system_error);
}
-#ifdef HAVE_BOOST_CONTEXT
TEST_F(AsioRados, AsyncWriteOperationYield)
{
boost::asio::io_service service;
service.run();
}
-#endif
int main(int argc, char **argv)
{
add_ceph_unittest(unittest_rgw_dmclock_scheduler)
target_link_libraries(unittest_rgw_dmclock_scheduler rgw_schedulers global ${UNITTEST_LIBS})
-if(WITH_BOOST_CONTEXT)
- target_compile_definitions(unittest_rgw_dmclock_scheduler PRIVATE BOOST_COROUTINES_NO_DEPRECATION_WARNING)
- target_link_libraries(unittest_rgw_dmclock_scheduler Boost::coroutine Boost::context)
-endif()
+target_compile_definitions(unittest_rgw_dmclock_scheduler PRIVATE BOOST_COROUTINES_NO_DEPRECATION_WARNING)
+target_link_libraries(unittest_rgw_dmclock_scheduler Boost::coroutine Boost::context)
if(WITH_RADOSGW_AMQP_ENDPOINT)
add_executable(unittest_rgw_amqp test_rgw_amqp.cc)
#include "rgw/rgw_dmclock_async_scheduler.h"
#include <optional>
-#ifdef HAVE_BOOST_CONTEXT
#include <boost/asio/spawn.hpp>
-#endif
#include <gtest/gtest.h>
#include "acconfig.h"
#include "global/global_context.h"
EXPECT_EQ(0u, counters(client_id::auth)->get(queue_counters::l_cancel));
}
-#ifdef HAVE_BOOST_CONTEXT
TEST(Queue, RateLimit)
{
boost::asio::io_context context;
EXPECT_TRUE(context.stopped());
}
-#endif
-
} // namespace rgw::dmclock
*/
#include "rgw/rgw_reshard.h"
-#ifdef HAVE_BOOST_CONTEXT
#include <spawn/spawn.hpp>
-#endif
#include <gtest/gtest.h>
short_waiter.stop();
}
-#ifdef HAVE_BOOST_CONTEXT
TEST(ReshardWait, wait_yield)
{
constexpr ceph::timespan wait_duration = 50ms;
EXPECT_GT(long_duration, elapsed); // waited less than 10s
short_waiter.stop();
}
-#endif // HAVE_BOOST_CONTEXT
#include <thread>
#include "include/scope_guard.h"
-#ifdef HAVE_BOOST_CONTEXT
#include <spawn/spawn.hpp>
-#endif
#include <gtest/gtest.h>
struct RadosEnv : public ::testing::Environment {
EXPECT_EQ(window, max_outstanding);
}
-#ifdef HAVE_BOOST_CONTEXT
TEST_F(Aio_Throttle, YieldCostOverWindow)
{
auto obj = make_obj(__PRETTY_FUNCTION__);
EXPECT_EQ(0u, outstanding);
EXPECT_EQ(window, max_outstanding);
}
-#endif // HAVE_BOOST_CONTEXT
} // namespace rgw
endif()
install(TARGETS rados DESTINATION bin)
-if(WITH_BOOST_CONTEXT AND NOT WIN32)
+if(NOT WIN32)
set(neorados_srcs
neorados.cc)
add_executable(neorados ${neorados_srcs})
target_include_directories(neorados PRIVATE
$<TARGET_PROPERTY:spawn,INTERFACE_INCLUDE_DIRECTORIES>)
+endif()
target_link_libraries(neorados libneorados spawn ${CMAKE_DL_LIBS})
#install(TARGETS neorados DESTINATION bin)
-endif()
if(WITH_TESTS)
add_executable(ceph_scratchtool scratchtool.c)