Support BOOST_ASIO_NO_TS_EXECUTORS

This commit is contained in:
Richard Hodges
2020-07-04 07:35:14 +02:00
parent 5f1adfbc6d
commit 060f59685c
20 changed files with 285 additions and 92 deletions
+24 -14
View File
@@ -14,10 +14,10 @@
#include <boost/beast/core/bind_handler.hpp>
#include <boost/beast/core/detail/allocator.hpp>
#include <boost/beast/core/detail/async_base.hpp>
#include <boost/beast/core/detail/work_guard.hpp>
#include <boost/asio/associated_allocator.hpp>
#include <boost/asio/associated_executor.hpp>
#include <boost/asio/bind_executor.hpp>
#include <boost/asio/executor_work_guard.hpp>
#include <boost/asio/handler_alloc_hook.hpp>
#include <boost/asio/handler_continuation_hook.hpp>
#include <boost/asio/handler_invoke_hook.hpp>
@@ -186,7 +186,27 @@ class async_base
"Executor type requirements not met");
Handler h_;
net::executor_work_guard<Executor1> wg1_;
detail::select_work_guard_t<Executor1> wg1_;
public:
/** The type of executor associated with this object.
If a class derived from @ref async_base is a completion
handler, then the associated executor of the derived class will
be this type.
*/
using executor_type =
#if BOOST_BEAST_DOXYGEN
__implementation_defined__;
#else
typename
net::associated_executor<
Handler,
typename detail::select_work_guard_t<Executor1>::executor_type
>::type;
#endif
private:
virtual
void
@@ -229,7 +249,7 @@ public:
Handler_&& handler,
Executor1 const& ex1)
: h_(std::forward<Handler_>(handler))
, wg1_(ex1)
, wg1_(detail::make_work_guard(ex1))
{
}
@@ -262,15 +282,6 @@ public:
using allocator_type =
net::associated_allocator_t<Handler, Allocator>;
/** The type of executor associated with this object.
If a class derived from @ref async_base is a completion
handler, then the associated executor of the derived class will
be this type.
*/
using executor_type =
net::associated_executor_t<Handler, Executor1>;
/** Returns the allocator associated with this object.
If a class derived from @ref async_base is a completion
@@ -293,8 +304,7 @@ public:
executor_type
get_executor() const noexcept
{
return net::get_associated_executor(
h_, wg1_.get_executor());
return net::get_associated_executor(h_, wg1_.get_executor());
}
/// Returns the handler associated with this object
@@ -11,6 +11,9 @@
#define BOOST_BEAST_DETAIL_GET_IO_CONTEXT_HPP
#include <boost/beast/core/stream_traits.hpp>
#ifdef BOOST_ASIO_NO_TS_EXECUTORS
#include <boost/asio/execution.hpp>
#endif
#include <boost/asio/executor.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/strand.hpp>
@@ -0,0 +1,93 @@
#ifndef BOOST_BEAST_CORE_DETAIL_WORK_GUARD_HPP
#define BOOST_BEAST_CORE_DETAIL_WORK_GUARD_HPP
#include <boost/asio/executor_work_guard.hpp>
#include <boost/asio/execution.hpp>
#include <boost/optional.hpp>
namespace boost {
namespace beast {
namespace detail {
template<class Executor, class Enable = void>
struct select_work_guard;
template<class Executor>
using select_work_guard_t = typename
select_work_guard<Executor>::type;
#if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
template<class Executor>
struct select_work_guard
<
Executor,
typename std::enable_if
<
net::is_executor<Executor>::value
>::type
>
{
using type = net::executor_work_guard<Executor>;
};
#endif
template<class Executor>
struct execution_work_guard
{
using executor_type = decltype(
net::prefer(std::declval<Executor const&>(),
net::execution::outstanding_work.tracked));
execution_work_guard(Executor const& exec)
: ex_(net::prefer(exec, net::execution::outstanding_work.tracked))
{
}
executor_type
get_executor() const noexcept
{
BOOST_ASSERT(ex_.has_value());
return *ex_;
}
void reset() noexcept
{
ex_.reset();
}
private:
boost::optional<executor_type> ex_;
};
template<class Executor>
struct select_work_guard
<
Executor,
typename std::enable_if
<
net::execution::is_executor<Executor>::value
#if defined(BOOST_ASIO_NO_TS_EXECUTORS)
|| net::is_executor<Executor>::value
#else
&& !net::is_executor<Executor>::value
#endif
>::type
>
{
using type = execution_work_guard<Executor>;
};
template<class Executor>
select_work_guard_t<Executor>
make_work_guard(Executor const& exec) noexcept
{
return select_work_guard_t<Executor>(exec);
}
}
}
}
#endif // BOOST_BEAST_CORE_DETAIL_WORK_GUARD_HPP
@@ -64,9 +64,10 @@ class saved_handler::impl final : public base
ebo_pair v_;
#if defined(BOOST_ASIO_NO_TS_EXECUTORS)
std::decay_t<decltype(net::prefer(
std::declval<net::associated_executor_t<Handler>>(),
net::execution::outstanding_work.tracked))> wg2_;
typename std::decay<decltype(net::prefer(std::declval<
net::associated_executor_t<Handler>>(),
net::execution::outstanding_work.tracked))>::type
wg2_;
#else // defined(BOOST_ASIO_NO_TS_EXECUTORS)
net::executor_work_guard<
net::associated_executor_t<Handler>> wg2_;
@@ -128,7 +128,8 @@ struct stream<NextLayer, deflateSupported>::impl_type
boost::empty_init_t{},
std::forward<Args>(args)...)
, detail::service::impl_type(
this->boost::empty_value<NextLayer>::get().get_executor().context())
net::query(this->boost::empty_value<NextLayer>::get().get_executor(),
net::execution::context))
, timer(this->boost::empty_value<NextLayer>::get().get_executor())
{
timeout_opt.handshake_timeout = none();