From 00e00e9210a0971ed9b62e8aa861c6640277203d Mon Sep 17 00:00:00 2001 From: Oliver Kowalke Date: Sun, 2 Jul 2017 19:05:31 +0200 Subject: [PATCH] use boost.coroutine2 if supported - use boost.coroutine2 instead of deprecated boost.coroutine - boost.coroutine2 uses callcc() from boost.context, - boost.context defines BOOST_CONTEX_NO_CXX11 if callcc() can not be be provided because of required C++11 are missing --- include/boost/asio/impl/spawn.hpp | 63 ++++++++++++++++++++++++++++++++++++++- include/boost/asio/spawn.hpp | 39 +++++++++++++++++++++++- 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/include/boost/asio/impl/spawn.hpp b/include/boost/asio/impl/spawn.hpp index a42fc6fb..004876d6 100644 --- a/include/boost/asio/impl/spawn.hpp +++ b/include/boost/asio/impl/spawn.hpp @@ -265,7 +265,7 @@ namespace detail { void operator()(typename basic_yield_context::caller_type& ca) { shared_ptr > data(data_); -#if !defined(BOOST_COROUTINES_UNIDIRECT) && !defined(BOOST_COROUTINES_V2) +#if !defined(BOOST_COROUTINES_UNIDIRECT) && !defined(BOOST_COROUTINES_V2) && defined(BOOST_CONTEXT_NO_CXX11) ca(); // Yield until coroutine pointer has been initialised. #endif // !defined(BOOST_COROUTINES_UNIDIRECT) && !defined(BOOST_COROUTINES_V2) const basic_yield_context yield( @@ -278,26 +278,86 @@ namespace detail { shared_ptr > data_; }; +#if ! defined(BOOST_CONTEXT_NO_CXX11) + template +#else template +#endif struct spawn_helper { void operator()() { typedef typename basic_yield_context::callee_type callee_type; coro_entry_point entry_point = { data_ }; +#if ! defined(BOOST_CONTEXT_NO_CXX11) + shared_ptr coro(new callee_type(salloc_, entry_point)); +#else shared_ptr coro(new callee_type(entry_point, attributes_)); +#endif data_->coro_ = coro; (*coro)(); } shared_ptr > data_; +#if ! defined(BOOST_CONTEXT_NO_CXX11) + StackAllocator salloc_; +#else boost::coroutines::attributes attributes_; +#endif }; inline void default_spawn_handler() {} } // namespace detail +#if ! defined(BOOST_CONTEXT_NO_CXX11) +template +void spawn(BOOST_ASIO_MOVE_ARG(Handler) handler, + BOOST_ASIO_MOVE_ARG(Function) function, + const StackAllocator& salloc) +{ + detail::spawn_helper helper; + helper.data_.reset( + new detail::spawn_data( + BOOST_ASIO_MOVE_CAST(Handler)(handler), true, + BOOST_ASIO_MOVE_CAST(Function)(function))); + helper.salloc_ = salloc; + boost_asio_handler_invoke_helpers::invoke(helper, helper.data_->handler_); +} + +template +void spawn(basic_yield_context ctx, + BOOST_ASIO_MOVE_ARG(Function) function, + const StackAllocator& salloc) +{ + Handler handler(ctx.handler_); // Explicit copy that might be moved from. + detail::spawn_helper helper; + helper.data_.reset( + new detail::spawn_data( + BOOST_ASIO_MOVE_CAST(Handler)(handler), false, + BOOST_ASIO_MOVE_CAST(Function)(function))); + helper.salloc_ = salloc; + boost_asio_handler_invoke_helpers::invoke(helper, helper.data_->handler_); +} + +template +void spawn(boost::asio::io_service::strand strand, + BOOST_ASIO_MOVE_ARG(Function) function, + const StackAllocator& salloc) +{ + boost::asio::spawn(strand.wrap(&detail::default_spawn_handler), + BOOST_ASIO_MOVE_CAST(Function)(function), salloc); +} + +template +void spawn(boost::asio::io_service& io_service, + BOOST_ASIO_MOVE_ARG(Function) function, + const StackAllocator& salloc) +{ + boost::asio::spawn(boost::asio::io_service::strand(io_service), + BOOST_ASIO_MOVE_CAST(Function)(function), salloc); +} +#else template void spawn(BOOST_ASIO_MOVE_ARG(Handler) handler, BOOST_ASIO_MOVE_ARG(Function) function, @@ -344,6 +404,7 @@ void spawn(boost::asio::io_service& io_service, boost::asio::spawn(boost::asio::io_service::strand(io_service), BOOST_ASIO_MOVE_CAST(Function)(function), attributes); } +#endif #endif // !defined(GENERATING_DOCUMENTATION) diff --git a/include/boost/asio/spawn.hpp b/include/boost/asio/spawn.hpp index 966bd3ef..20caf213 100644 --- a/include/boost/asio/spawn.hpp +++ b/include/boost/asio/spawn.hpp @@ -16,7 +16,12 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include -#include +#include +#if ! defined(BOOST_CONTEXT_NO_CXX11) +# include +#else +# include +#endif #include #include #include @@ -58,6 +63,8 @@ class basic_yield_context */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined callee_type; +#elif ! defined(BOOST_CONTEXT_NO_CXX11) + typedef boost::coroutines2::coroutine::push_type callee_type; #elif defined(BOOST_COROUTINES_UNIDIRECT) || defined(BOOST_COROUTINES_V2) typedef boost::coroutines::push_coroutine callee_type; #else @@ -73,6 +80,8 @@ class basic_yield_context */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined caller_type; +#elif ! defined(BOOST_CONTEXT_NO_CXX11) + typedef boost::coroutines2::coroutine::pull_type caller_type; #elif defined(BOOST_COROUTINES_UNIDIRECT) || defined(BOOST_COROUTINES_V2) typedef boost::coroutines::pull_coroutine caller_type; #else @@ -191,11 +200,18 @@ typedef basic_yield_context< * * @param attributes Boost.Coroutine attributes used to customise the coroutine. */ +#if ! defined(BOOST_CONTEXT_NO_CXX11) +template +void spawn(BOOST_ASIO_MOVE_ARG(Handler) handler, + BOOST_ASIO_MOVE_ARG(Function) function, + const StackAllocator& salloc = StackAllocator()); +#else template void spawn(BOOST_ASIO_MOVE_ARG(Handler) handler, BOOST_ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes = boost::coroutines::attributes()); +#endif /// Start a new stackful coroutine, inheriting the execution context of another. /** @@ -212,11 +228,18 @@ void spawn(BOOST_ASIO_MOVE_ARG(Handler) handler, * * @param attributes Boost.Coroutine attributes used to customise the coroutine. */ +#if ! defined(BOOST_CONTEXT_NO_CXX11) +template +void spawn(basic_yield_context ctx, + BOOST_ASIO_MOVE_ARG(Function) function, + const StackAllocator& salloc = StackAllocator()); +#else template void spawn(basic_yield_context ctx, BOOST_ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes = boost::coroutines::attributes()); +#endif /// Start a new stackful coroutine that executes in the context of a strand. /** @@ -231,11 +254,18 @@ void spawn(basic_yield_context ctx, * * @param attributes Boost.Coroutine attributes used to customise the coroutine. */ +#if ! defined(BOOST_CONTEXT_NO_CXX11) +template +void spawn(boost::asio::io_service::strand strand, + BOOST_ASIO_MOVE_ARG(Function) function, + const StackAllocator& salloc = StackAllocator()); +#else template void spawn(boost::asio::io_service::strand strand, BOOST_ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes = boost::coroutines::attributes()); +#endif /// Start a new stackful coroutine that executes on a given io_service. /** @@ -249,11 +279,18 @@ void spawn(boost::asio::io_service::strand strand, * * @param attributes Boost.Coroutine attributes used to customise the coroutine. */ +#if ! defined(BOOST_CONTEXT_NO_CXX11) +template +void spawn(boost::asio::io_service& io_service, + BOOST_ASIO_MOVE_ARG(Function) function, + const StackAllocator& salloc = StackAllocator()); +#else template void spawn(boost::asio::io_service& io_service, BOOST_ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes = boost::coroutines::attributes()); +#endif /*@}*/