// impl/compose.hpp
// ~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/asio/detail/config.hpp>
#include <boost/asio/associated_executor.hpp>
+#include <boost/asio/detail/base_from_cancellation_state.hpp>
#include <boost/asio/detail/handler_alloc_helpers.hpp>
#include <boost/asio/detail/handler_cont_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
executor_type executor_;
};
+ template <>
+ struct composed_work_guard<system_executor>
+ {
+ public:
+ typedef system_executor executor_type;
+
+ composed_work_guard(const system_executor&)
+ {
+ }
+
+ void reset()
+ {
+ }
+
+ executor_type get_executor() const BOOST_ASIO_NOEXCEPT
+ {
+ return system_executor();
+ }
+ };
+
#if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
template <typename Executor>
template <typename Impl, typename Work, typename Handler, typename Signature>
class composed_op
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+ : public base_from_cancellation_state<Handler>
{
public:
template <typename I, typename W, typename H>
composed_op(BOOST_ASIO_MOVE_ARG(I) impl,
BOOST_ASIO_MOVE_ARG(W) work,
BOOST_ASIO_MOVE_ARG(H) handler)
- : impl_(BOOST_ASIO_MOVE_CAST(I)(impl)),
+ : base_from_cancellation_state<Handler>(
+ handler, enable_terminal_cancellation()),
+ impl_(BOOST_ASIO_MOVE_CAST(I)(impl)),
work_(BOOST_ASIO_MOVE_CAST(W)(work)),
handler_(BOOST_ASIO_MOVE_CAST(H)(handler)),
invocations_(0)
#if defined(BOOST_ASIO_HAS_MOVE)
composed_op(composed_op&& other)
- : impl_(BOOST_ASIO_MOVE_CAST(Impl)(other.impl_)),
+ : base_from_cancellation_state<Handler>(
+ BOOST_ASIO_MOVE_CAST(base_from_cancellation_state<
+ Handler>)(other)),
+ impl_(BOOST_ASIO_MOVE_CAST(Impl)(other.impl_)),
work_(BOOST_ASIO_MOVE_CAST(Work)(other.work_)),
handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
invocations_(other.invocations_)
{
if (invocations_ < ~0u)
++invocations_;
+ this->get_cancellation_state().slot().clear();
impl_(*this, BOOST_ASIO_MOVE_CAST(T)(t)...);
}
void complete(Args... args)
{
this->work_.reset();
- this->handler_(BOOST_ASIO_MOVE_CAST(Args)(args)...);
+ BOOST_ASIO_MOVE_OR_LVALUE(Handler)(this->handler_)(
+ BOOST_ASIO_MOVE_CAST(Args)(args)...);
}
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
{
if (invocations_ < ~0u)
++invocations_;
+ this->get_cancellation_state().slot().clear();
impl_(*this);
}
void complete()
{
this->work_.reset();
- this->handler_();
+ BOOST_ASIO_MOVE_OR_LVALUE(Handler)(this->handler_)();
}
#define BOOST_ASIO_PRIVATE_COMPOSED_OP_DEF(n) \
{ \
if (invocations_ < ~0u) \
++invocations_; \
+ this->get_cancellation_state().slot().clear(); \
impl_(*this, BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
} \
\
void complete(BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
{ \
this->work_.reset(); \
- this->handler_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
+ BOOST_ASIO_MOVE_OR_LVALUE(Handler)(this->handler_)( \
+ BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
} \
/**/
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_COMPOSED_OP_DEF)
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+ void reset_cancellation_state()
+ {
+ base_from_cancellation_state<Handler>::reset_cancellation_state(handler_);
+ }
+
+ template <typename Filter>
+ void reset_cancellation_state(BOOST_ASIO_MOVE_ARG(Filter) filter)
+ {
+ base_from_cancellation_state<Handler>::reset_cancellation_state(handler_,
+ BOOST_ASIO_MOVE_CAST(Filter)(filter));
+ }
+
+ template <typename InFilter, typename OutFilter>
+ void reset_cancellation_state(BOOST_ASIO_MOVE_ARG(InFilter) in_filter,
+ BOOST_ASIO_MOVE_ARG(OutFilter) out_filter)
+ {
+ base_from_cancellation_state<Handler>::reset_cancellation_state(handler_,
+ BOOST_ASIO_MOVE_CAST(InFilter)(in_filter),
+ BOOST_ASIO_MOVE_CAST(OutFilter)(out_filter));
+ }
+
//private:
Impl impl_;
Work work_;
get_composed_io_executor(IoObject& io_object,
typename enable_if<
!is_executor<IoObject>::value
- && !execution::is_executor<IoObject>::value
+ >::type* = 0,
+ typename enable_if<
+ !execution::is_executor<IoObject>::value
>::type* = 0)
{
return io_object.get_executor();
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
+
+template <template <typename, typename> class Associator,
+ typename Impl, typename Work, typename Handler,
+ typename Signature, typename DefaultCandidate>
+struct associator<Associator,
+ detail::composed_op<Impl, Work, Handler, Signature>,
+ DefaultCandidate>
+ : Associator<Handler, DefaultCandidate>
+{
+ static typename Associator<Handler, DefaultCandidate>::type get(
+ const detail::composed_op<Impl, Work, Handler, Signature>& h,
+ const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
+ {
+ return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
+ }
+};
+
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename CompletionToken, typename Signature,