update boost
This commit is contained in:
132
linx64/include/boost/asio/impl/any_completion_executor.ipp
Normal file
132
linx64/include/boost/asio/impl/any_completion_executor.ipp
Normal file
@@ -0,0 +1,132 @@
|
||||
//
|
||||
// impl/any_completion_executor.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2023 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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_ASIO_IMPL_ANY_COMPLETION_EXECUTOR_IPP
|
||||
#define BOOST_ASIO_IMPL_ANY_COMPLETION_EXECUTOR_IPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#if !defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
|
||||
|
||||
#include <boost/asio/any_completion_executor.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
any_completion_executor::any_completion_executor() BOOST_ASIO_NOEXCEPT
|
||||
: base_type()
|
||||
{
|
||||
}
|
||||
|
||||
any_completion_executor::any_completion_executor(nullptr_t) BOOST_ASIO_NOEXCEPT
|
||||
: base_type(nullptr_t())
|
||||
{
|
||||
}
|
||||
|
||||
any_completion_executor::any_completion_executor(
|
||||
const any_completion_executor& e) BOOST_ASIO_NOEXCEPT
|
||||
: base_type(static_cast<const base_type&>(e))
|
||||
{
|
||||
}
|
||||
|
||||
any_completion_executor::any_completion_executor(std::nothrow_t,
|
||||
const any_completion_executor& e) BOOST_ASIO_NOEXCEPT
|
||||
: base_type(static_cast<const base_type&>(e))
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
any_completion_executor::any_completion_executor(
|
||||
any_completion_executor&& e) BOOST_ASIO_NOEXCEPT
|
||||
: base_type(static_cast<base_type&&>(e))
|
||||
{
|
||||
}
|
||||
|
||||
any_completion_executor::any_completion_executor(std::nothrow_t,
|
||||
any_completion_executor&& e) BOOST_ASIO_NOEXCEPT
|
||||
: base_type(static_cast<base_type&&>(e))
|
||||
{
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
any_completion_executor& any_completion_executor::operator=(
|
||||
const any_completion_executor& e) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
base_type::operator=(static_cast<const base_type&>(e));
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
any_completion_executor& any_completion_executor::operator=(
|
||||
any_completion_executor&& e) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
base_type::operator=(static_cast<base_type&&>(e));
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
any_completion_executor& any_completion_executor::operator=(nullptr_t)
|
||||
{
|
||||
base_type::operator=(nullptr_t());
|
||||
return *this;
|
||||
}
|
||||
|
||||
any_completion_executor::~any_completion_executor()
|
||||
{
|
||||
}
|
||||
|
||||
void any_completion_executor::swap(
|
||||
any_completion_executor& other) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
static_cast<base_type&>(*this).swap(static_cast<base_type&>(other));
|
||||
}
|
||||
|
||||
template <>
|
||||
any_completion_executor any_completion_executor::prefer(
|
||||
const execution::outstanding_work_t::tracked_t& p, int) const
|
||||
{
|
||||
return static_cast<const base_type&>(*this).prefer(p);
|
||||
}
|
||||
|
||||
template <>
|
||||
any_completion_executor any_completion_executor::prefer(
|
||||
const execution::outstanding_work_t::untracked_t& p, int) const
|
||||
{
|
||||
return static_cast<const base_type&>(*this).prefer(p);
|
||||
}
|
||||
|
||||
template <>
|
||||
any_completion_executor any_completion_executor::prefer(
|
||||
const execution::relationship_t::fork_t& p, int) const
|
||||
{
|
||||
return static_cast<const base_type&>(*this).prefer(p);
|
||||
}
|
||||
|
||||
template <>
|
||||
any_completion_executor any_completion_executor::prefer(
|
||||
const execution::relationship_t::continuation_t& p, int) const
|
||||
{
|
||||
return static_cast<const base_type&>(*this).prefer(p);
|
||||
}
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // !defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
|
||||
|
||||
#endif // BOOST_ASIO_IMPL_ANY_COMPLETION_EXECUTOR_IPP
|
||||
143
linx64/include/boost/asio/impl/any_io_executor.ipp
Normal file
143
linx64/include/boost/asio/impl/any_io_executor.ipp
Normal file
@@ -0,0 +1,143 @@
|
||||
//
|
||||
// impl/any_io_executor.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2023 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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_ASIO_IMPL_ANY_IO_EXECUTOR_IPP
|
||||
#define BOOST_ASIO_IMPL_ANY_IO_EXECUTOR_IPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#if !defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
|
||||
|
||||
#include <boost/asio/any_io_executor.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
any_io_executor::any_io_executor() BOOST_ASIO_NOEXCEPT
|
||||
: base_type()
|
||||
{
|
||||
}
|
||||
|
||||
any_io_executor::any_io_executor(nullptr_t) BOOST_ASIO_NOEXCEPT
|
||||
: base_type(nullptr_t())
|
||||
{
|
||||
}
|
||||
|
||||
any_io_executor::any_io_executor(const any_io_executor& e) BOOST_ASIO_NOEXCEPT
|
||||
: base_type(static_cast<const base_type&>(e))
|
||||
{
|
||||
}
|
||||
|
||||
any_io_executor::any_io_executor(std::nothrow_t,
|
||||
const any_io_executor& e) BOOST_ASIO_NOEXCEPT
|
||||
: base_type(static_cast<const base_type&>(e))
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
any_io_executor::any_io_executor(any_io_executor&& e) BOOST_ASIO_NOEXCEPT
|
||||
: base_type(static_cast<base_type&&>(e))
|
||||
{
|
||||
}
|
||||
|
||||
any_io_executor::any_io_executor(std::nothrow_t,
|
||||
any_io_executor&& e) BOOST_ASIO_NOEXCEPT
|
||||
: base_type(static_cast<base_type&&>(e))
|
||||
{
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
any_io_executor& any_io_executor::operator=(
|
||||
const any_io_executor& e) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
base_type::operator=(static_cast<const base_type&>(e));
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
any_io_executor& any_io_executor::operator=(
|
||||
any_io_executor&& e) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
base_type::operator=(static_cast<base_type&&>(e));
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
any_io_executor& any_io_executor::operator=(nullptr_t)
|
||||
{
|
||||
base_type::operator=(nullptr_t());
|
||||
return *this;
|
||||
}
|
||||
|
||||
any_io_executor::~any_io_executor()
|
||||
{
|
||||
}
|
||||
|
||||
void any_io_executor::swap(any_io_executor& other) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
static_cast<base_type&>(*this).swap(static_cast<base_type&>(other));
|
||||
}
|
||||
|
||||
template <>
|
||||
any_io_executor any_io_executor::require(
|
||||
const execution::blocking_t::never_t& p, int) const
|
||||
{
|
||||
return static_cast<const base_type&>(*this).require(p);
|
||||
}
|
||||
|
||||
template <>
|
||||
any_io_executor any_io_executor::prefer(
|
||||
const execution::blocking_t::possibly_t& p, int) const
|
||||
{
|
||||
return static_cast<const base_type&>(*this).prefer(p);
|
||||
}
|
||||
|
||||
template <>
|
||||
any_io_executor any_io_executor::prefer(
|
||||
const execution::outstanding_work_t::tracked_t& p, int) const
|
||||
{
|
||||
return static_cast<const base_type&>(*this).prefer(p);
|
||||
}
|
||||
|
||||
template <>
|
||||
any_io_executor any_io_executor::prefer(
|
||||
const execution::outstanding_work_t::untracked_t& p, int) const
|
||||
{
|
||||
return static_cast<const base_type&>(*this).prefer(p);
|
||||
}
|
||||
|
||||
template <>
|
||||
any_io_executor any_io_executor::prefer(
|
||||
const execution::relationship_t::fork_t& p, int) const
|
||||
{
|
||||
return static_cast<const base_type&>(*this).prefer(p);
|
||||
}
|
||||
|
||||
template <>
|
||||
any_io_executor any_io_executor::prefer(
|
||||
const execution::relationship_t::continuation_t& p, int) const
|
||||
{
|
||||
return static_cast<const base_type&>(*this).prefer(p);
|
||||
}
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // !defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
|
||||
|
||||
#endif // BOOST_ASIO_IMPL_ANY_IO_EXECUTOR_IPP
|
||||
227
linx64/include/boost/asio/impl/append.hpp
Normal file
227
linx64/include/boost/asio/impl/append.hpp
Normal file
@@ -0,0 +1,227 @@
|
||||
//
|
||||
// impl/append.hpp
|
||||
// ~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2023 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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_ASIO_IMPL_APPEND_HPP
|
||||
#define BOOST_ASIO_IMPL_APPEND_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#include <boost/asio/associator.hpp>
|
||||
#include <boost/asio/async_result.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>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
#include <boost/asio/detail/utility.hpp>
|
||||
#include <boost/asio/detail/variadic_templates.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
// Class to adapt an append_t as a completion handler.
|
||||
template <typename Handler, typename... Values>
|
||||
class append_handler
|
||||
{
|
||||
public:
|
||||
typedef void result_type;
|
||||
|
||||
template <typename H>
|
||||
append_handler(BOOST_ASIO_MOVE_ARG(H) handler, std::tuple<Values...> values)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(H)(handler)),
|
||||
values_(BOOST_ASIO_MOVE_CAST(std::tuple<Values...>)(values))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
this->invoke(
|
||||
index_sequence_for<Values...>{},
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
|
||||
template <std::size_t... I, typename... Args>
|
||||
void invoke(index_sequence<I...>, BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)(
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...,
|
||||
BOOST_ASIO_MOVE_CAST(Values)(std::get<I>(values_))...);
|
||||
}
|
||||
|
||||
//private:
|
||||
Handler handler_;
|
||||
std::tuple<Values...> values_;
|
||||
};
|
||||
|
||||
template <typename Handler>
|
||||
inline asio_handler_allocate_is_deprecated
|
||||
asio_handler_allocate(std::size_t size,
|
||||
append_handler<Handler>* this_handler)
|
||||
{
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
|
||||
return asio_handler_allocate_is_no_longer_used();
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
inline asio_handler_deallocate_is_deprecated
|
||||
asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
append_handler<Handler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_deallocate_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
inline bool asio_handler_is_continuation(
|
||||
append_handler<Handler>* this_handler)
|
||||
{
|
||||
return boost_asio_handler_cont_helpers::is_continuation(
|
||||
this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler>
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(Function& function,
|
||||
append_handler<Handler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler>
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(const Function& function,
|
||||
append_handler<Handler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Signature, typename... Values>
|
||||
struct append_signature;
|
||||
|
||||
template <typename R, typename... Args, typename... Values>
|
||||
struct append_signature<R(Args...), Values...>
|
||||
{
|
||||
typedef R type(typename decay<Args>::type..., Values...);
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename CompletionToken, typename... Values, typename Signature>
|
||||
struct async_result<
|
||||
append_t<CompletionToken, Values...>, Signature>
|
||||
: async_result<CompletionToken,
|
||||
typename detail::append_signature<
|
||||
Signature, Values...>::type>
|
||||
{
|
||||
typedef typename detail::append_signature<
|
||||
Signature, Values...>::type signature;
|
||||
|
||||
template <typename Initiation>
|
||||
struct init_wrapper
|
||||
{
|
||||
init_wrapper(Initiation init)
|
||||
: initiation_(BOOST_ASIO_MOVE_CAST(Initiation)(init))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Handler, typename... Args>
|
||||
void operator()(
|
||||
BOOST_ASIO_MOVE_ARG(Handler) handler,
|
||||
std::tuple<Values...> values,
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)(
|
||||
detail::append_handler<
|
||||
typename decay<Handler>::type, Values...>(
|
||||
BOOST_ASIO_MOVE_CAST(Handler)(handler),
|
||||
BOOST_ASIO_MOVE_CAST(std::tuple<Values...>)(values)),
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
|
||||
Initiation initiation_;
|
||||
};
|
||||
|
||||
template <typename Initiation, typename RawCompletionToken, typename... Args>
|
||||
static BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, signature,
|
||||
(async_initiate<CompletionToken, signature>(
|
||||
declval<init_wrapper<typename decay<Initiation>::type> >(),
|
||||
declval<CompletionToken&>(),
|
||||
declval<std::tuple<Values...> >(),
|
||||
declval<BOOST_ASIO_MOVE_ARG(Args)>()...)))
|
||||
initiate(
|
||||
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
return async_initiate<CompletionToken, signature>(
|
||||
init_wrapper<typename decay<Initiation>::type>(
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
|
||||
token.token_,
|
||||
BOOST_ASIO_MOVE_CAST(std::tuple<Values...>)(token.values_),
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <template <typename, typename> class Associator,
|
||||
typename Handler, typename... Values, typename DefaultCandidate>
|
||||
struct associator<Associator,
|
||||
detail::append_handler<Handler, Values...>, DefaultCandidate>
|
||||
: Associator<Handler, DefaultCandidate>
|
||||
{
|
||||
static typename Associator<Handler, DefaultCandidate>::type
|
||||
get(const detail::append_handler<Handler, Values...>& h) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return Associator<Handler, DefaultCandidate>::get(h.handler_);
|
||||
}
|
||||
|
||||
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
|
||||
typename Associator<Handler, DefaultCandidate>::type)
|
||||
get(const detail::append_handler<Handler, Values...>& h,
|
||||
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
|
||||
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
|
||||
Associator<Handler, DefaultCandidate>::get(h.handler_, c)))
|
||||
{
|
||||
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_IMPL_APPEND_HPP
|
||||
322
linx64/include/boost/asio/impl/as_tuple.hpp
Normal file
322
linx64/include/boost/asio/impl/as_tuple.hpp
Normal file
@@ -0,0 +1,322 @@
|
||||
//
|
||||
// impl/as_tuple.hpp
|
||||
// ~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2023 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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_ASIO_IMPL_AS_TUPLE_HPP
|
||||
#define BOOST_ASIO_IMPL_AS_TUPLE_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#include <boost/asio/associator.hpp>
|
||||
#include <boost/asio/async_result.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>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
#include <boost/asio/detail/variadic_templates.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
// Class to adapt a as_tuple_t as a completion handler.
|
||||
template <typename Handler>
|
||||
class as_tuple_handler
|
||||
{
|
||||
public:
|
||||
typedef void result_type;
|
||||
|
||||
template <typename CompletionToken>
|
||||
as_tuple_handler(as_tuple_t<CompletionToken> e)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(CompletionToken)(e.token_))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename RedirectedHandler>
|
||||
as_tuple_handler(BOOST_ASIO_MOVE_ARG(RedirectedHandler) h)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(RedirectedHandler)(h))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)(
|
||||
std::make_tuple(BOOST_ASIO_MOVE_CAST(Args)(args)...));
|
||||
}
|
||||
|
||||
//private:
|
||||
Handler handler_;
|
||||
};
|
||||
|
||||
template <typename Handler>
|
||||
inline asio_handler_allocate_is_deprecated
|
||||
asio_handler_allocate(std::size_t size,
|
||||
as_tuple_handler<Handler>* this_handler)
|
||||
{
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
|
||||
return asio_handler_allocate_is_no_longer_used();
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
inline asio_handler_deallocate_is_deprecated
|
||||
asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
as_tuple_handler<Handler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_deallocate_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
inline bool asio_handler_is_continuation(
|
||||
as_tuple_handler<Handler>* this_handler)
|
||||
{
|
||||
return boost_asio_handler_cont_helpers::is_continuation(
|
||||
this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler>
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(Function& function,
|
||||
as_tuple_handler<Handler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler>
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(const Function& function,
|
||||
as_tuple_handler<Handler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Signature>
|
||||
struct as_tuple_signature;
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct as_tuple_signature<R(Args...)>
|
||||
{
|
||||
typedef R type(std::tuple<typename decay<Args>::type...>);
|
||||
};
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct as_tuple_signature<R(Args...) &>
|
||||
{
|
||||
typedef R type(std::tuple<typename decay<Args>::type...>) &;
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct as_tuple_signature<R(Args...) &&>
|
||||
{
|
||||
typedef R type(std::tuple<typename decay<Args>::type...>) &&;
|
||||
};
|
||||
|
||||
# if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct as_tuple_signature<R(Args...) noexcept>
|
||||
{
|
||||
typedef R type(std::tuple<typename decay<Args>::type...>) noexcept;
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct as_tuple_signature<R(Args...) & noexcept>
|
||||
{
|
||||
typedef R type(std::tuple<typename decay<Args>::type...>) & noexcept;
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct as_tuple_signature<R(Args...) && noexcept>
|
||||
{
|
||||
typedef R type(std::tuple<typename decay<Args>::type...>) && noexcept;
|
||||
};
|
||||
|
||||
# endif // defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
|
||||
#endif // defined(BOOST_ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename CompletionToken, typename... Signatures>
|
||||
struct async_result<as_tuple_t<CompletionToken>, Signatures...>
|
||||
: async_result<CompletionToken,
|
||||
typename detail::as_tuple_signature<Signatures>::type...>
|
||||
{
|
||||
template <typename Initiation>
|
||||
struct init_wrapper
|
||||
{
|
||||
init_wrapper(Initiation init)
|
||||
: initiation_(BOOST_ASIO_MOVE_CAST(Initiation)(init))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Handler, typename... Args>
|
||||
void operator()(
|
||||
BOOST_ASIO_MOVE_ARG(Handler) handler,
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)(
|
||||
detail::as_tuple_handler<
|
||||
typename decay<Handler>::type>(
|
||||
BOOST_ASIO_MOVE_CAST(Handler)(handler)),
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
|
||||
Initiation initiation_;
|
||||
};
|
||||
|
||||
template <typename Initiation, typename RawCompletionToken, typename... Args>
|
||||
static BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,
|
||||
typename detail::as_tuple_signature<Signatures>::type...)
|
||||
initiate(
|
||||
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<
|
||||
typename conditional<
|
||||
is_const<typename remove_reference<RawCompletionToken>::type>::value,
|
||||
const CompletionToken, CompletionToken>::type,
|
||||
typename detail::as_tuple_signature<Signatures>::type...>(
|
||||
init_wrapper<typename decay<Initiation>::type>(
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
|
||||
token.token_, BOOST_ASIO_MOVE_CAST(Args)(args)...)))
|
||||
{
|
||||
return async_initiate<
|
||||
typename conditional<
|
||||
is_const<typename remove_reference<RawCompletionToken>::type>::value,
|
||||
const CompletionToken, CompletionToken>::type,
|
||||
typename detail::as_tuple_signature<Signatures>::type...>(
|
||||
init_wrapper<typename decay<Initiation>::type>(
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
|
||||
token.token_, BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(BOOST_ASIO_MSVC)
|
||||
|
||||
// Workaround for MSVC internal compiler error.
|
||||
|
||||
template <typename CompletionToken, typename Signature>
|
||||
struct async_result<as_tuple_t<CompletionToken>, Signature>
|
||||
: async_result<CompletionToken,
|
||||
typename detail::as_tuple_signature<Signature>::type>
|
||||
{
|
||||
template <typename Initiation>
|
||||
struct init_wrapper
|
||||
{
|
||||
init_wrapper(Initiation init)
|
||||
: initiation_(BOOST_ASIO_MOVE_CAST(Initiation)(init))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Handler, typename... Args>
|
||||
void operator()(
|
||||
BOOST_ASIO_MOVE_ARG(Handler) handler,
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)(
|
||||
detail::as_tuple_handler<
|
||||
typename decay<Handler>::type>(
|
||||
BOOST_ASIO_MOVE_CAST(Handler)(handler)),
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
|
||||
Initiation initiation_;
|
||||
};
|
||||
|
||||
template <typename Initiation, typename RawCompletionToken, typename... Args>
|
||||
static BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,
|
||||
typename detail::as_tuple_signature<Signatures>::type...)
|
||||
initiate(
|
||||
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<
|
||||
typename conditional<
|
||||
is_const<typename remove_reference<RawCompletionToken>::type>::value,
|
||||
const CompletionToken, CompletionToken>::type,
|
||||
typename detail::as_tuple_signature<Signature>::type>(
|
||||
init_wrapper<typename decay<Initiation>::type>(
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
|
||||
token.token_, BOOST_ASIO_MOVE_CAST(Args)(args)...)))
|
||||
{
|
||||
return async_initiate<
|
||||
typename conditional<
|
||||
is_const<typename remove_reference<RawCompletionToken>::type>::value,
|
||||
const CompletionToken, CompletionToken>::type,
|
||||
typename detail::as_tuple_signature<Signature>::type>(
|
||||
init_wrapper<typename decay<Initiation>::type>(
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
|
||||
token.token_, BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // defined(BOOST_ASIO_MSVC)
|
||||
|
||||
template <template <typename, typename> class Associator,
|
||||
typename Handler, typename DefaultCandidate>
|
||||
struct associator<Associator,
|
||||
detail::as_tuple_handler<Handler>, DefaultCandidate>
|
||||
: Associator<Handler, DefaultCandidate>
|
||||
{
|
||||
static typename Associator<Handler, DefaultCandidate>::type
|
||||
get(const detail::as_tuple_handler<Handler>& h) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return Associator<Handler, DefaultCandidate>::get(h.handler_);
|
||||
}
|
||||
|
||||
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
|
||||
typename Associator<Handler, DefaultCandidate>::type)
|
||||
get(const detail::as_tuple_handler<Handler>& h,
|
||||
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
|
||||
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
|
||||
Associator<Handler, DefaultCandidate>::get(h.handler_, c)))
|
||||
{
|
||||
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_IMPL_AS_TUPLE_HPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/awaitable.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -19,20 +19,33 @@
|
||||
#include <exception>
|
||||
#include <new>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <boost/asio/cancellation_signal.hpp>
|
||||
#include <boost/asio/cancellation_state.hpp>
|
||||
#include <boost/asio/detail/thread_context.hpp>
|
||||
#include <boost/asio/detail/thread_info_base.hpp>
|
||||
#include <boost/asio/detail/throw_error.hpp>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <boost/system/system_error.hpp>
|
||||
#include <boost/asio/this_coro.hpp>
|
||||
|
||||
#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
# if defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
|
||||
# include <boost/asio/detail/source_location.hpp>
|
||||
# endif // defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
|
||||
#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
struct awaitable_thread_has_context_switched {};
|
||||
template <typename, typename> class awaitable_async_op_handler;
|
||||
template <typename, typename, typename> class awaitable_async_op;
|
||||
|
||||
// An awaitable_thread represents a thread-of-execution that is composed of one
|
||||
// or more "stack frames", with each frame represented by an awaitable_frame.
|
||||
// All execution occurs in the context of the awaitable_thread's executor. An
|
||||
@@ -78,7 +91,7 @@ public:
|
||||
{
|
||||
return boost::asio::detail::thread_info_base::allocate(
|
||||
boost::asio::detail::thread_info_base::awaitable_frame_tag(),
|
||||
boost::asio::detail::thread_context::thread_call_stack::top(),
|
||||
boost::asio::detail::thread_context::top_of_thread_call_stack(),
|
||||
size);
|
||||
}
|
||||
|
||||
@@ -86,7 +99,7 @@ public:
|
||||
{
|
||||
boost::asio::detail::thread_info_base::deallocate(
|
||||
boost::asio::detail::thread_info_base::awaitable_frame_tag(),
|
||||
boost::asio::detail::thread_context::thread_call_stack::top(),
|
||||
boost::asio::detail::thread_context::top_of_thread_call_stack(),
|
||||
pointer, size);
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_DISABLE_AWAITABLE_FRAME_RECYCLING)
|
||||
@@ -112,7 +125,7 @@ public:
|
||||
|
||||
void await_suspend(coroutine_handle<void>) noexcept
|
||||
{
|
||||
this_->pop_frame();
|
||||
this->this_->pop_frame();
|
||||
}
|
||||
|
||||
void await_resume() const noexcept
|
||||
@@ -147,12 +160,45 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void clear_cancellation_slot()
|
||||
{
|
||||
this->attached_thread_->entry_point()->cancellation_state_.slot().clear();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto await_transform(awaitable<T, Executor> a) const
|
||||
{
|
||||
if (attached_thread_->entry_point()->throw_if_cancelled_)
|
||||
if (!!attached_thread_->get_cancellation_state().cancelled())
|
||||
throw_error(boost::asio::error::operation_aborted, "co_await");
|
||||
return a;
|
||||
}
|
||||
|
||||
template <typename Op>
|
||||
auto await_transform(Op&& op,
|
||||
typename constraint<is_async_operation<Op>::value>::type = 0
|
||||
#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
# if defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
|
||||
, detail::source_location location = detail::source_location::current()
|
||||
# endif // defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
|
||||
#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
)
|
||||
{
|
||||
if (attached_thread_->entry_point()->throw_if_cancelled_)
|
||||
if (!!attached_thread_->get_cancellation_state().cancelled())
|
||||
throw_error(boost::asio::error::operation_aborted, "co_await");
|
||||
|
||||
return awaitable_async_op<typename completion_signature_of<Op>::type,
|
||||
typename decay<Op>::type, Executor>{
|
||||
std::forward<Op>(op), this
|
||||
#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
# if defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
|
||||
, location
|
||||
# endif // defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
|
||||
#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
};
|
||||
}
|
||||
|
||||
// This await transformation obtains the associated executor of the thread of
|
||||
// execution.
|
||||
auto await_transform(this_coro::executor_t) noexcept
|
||||
@@ -179,6 +225,175 @@ public:
|
||||
return result{this};
|
||||
}
|
||||
|
||||
// This await transformation obtains the associated cancellation state of the
|
||||
// thread of execution.
|
||||
auto await_transform(this_coro::cancellation_state_t) noexcept
|
||||
{
|
||||
struct result
|
||||
{
|
||||
awaitable_frame_base* this_;
|
||||
|
||||
bool await_ready() const noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void await_suspend(coroutine_handle<void>) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
auto await_resume() const noexcept
|
||||
{
|
||||
return this_->attached_thread_->get_cancellation_state();
|
||||
}
|
||||
};
|
||||
|
||||
return result{this};
|
||||
}
|
||||
|
||||
// This await transformation resets the associated cancellation state.
|
||||
auto await_transform(this_coro::reset_cancellation_state_0_t) noexcept
|
||||
{
|
||||
struct result
|
||||
{
|
||||
awaitable_frame_base* this_;
|
||||
|
||||
bool await_ready() const noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void await_suspend(coroutine_handle<void>) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
auto await_resume() const
|
||||
{
|
||||
return this_->attached_thread_->reset_cancellation_state();
|
||||
}
|
||||
};
|
||||
|
||||
return result{this};
|
||||
}
|
||||
|
||||
// This await transformation resets the associated cancellation state.
|
||||
template <typename Filter>
|
||||
auto await_transform(
|
||||
this_coro::reset_cancellation_state_1_t<Filter> reset) noexcept
|
||||
{
|
||||
struct result
|
||||
{
|
||||
awaitable_frame_base* this_;
|
||||
Filter filter_;
|
||||
|
||||
bool await_ready() const noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void await_suspend(coroutine_handle<void>) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
auto await_resume()
|
||||
{
|
||||
return this_->attached_thread_->reset_cancellation_state(
|
||||
BOOST_ASIO_MOVE_CAST(Filter)(filter_));
|
||||
}
|
||||
};
|
||||
|
||||
return result{this, BOOST_ASIO_MOVE_CAST(Filter)(reset.filter)};
|
||||
}
|
||||
|
||||
// This await transformation resets the associated cancellation state.
|
||||
template <typename InFilter, typename OutFilter>
|
||||
auto await_transform(
|
||||
this_coro::reset_cancellation_state_2_t<InFilter, OutFilter> reset)
|
||||
noexcept
|
||||
{
|
||||
struct result
|
||||
{
|
||||
awaitable_frame_base* this_;
|
||||
InFilter in_filter_;
|
||||
OutFilter out_filter_;
|
||||
|
||||
bool await_ready() const noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void await_suspend(coroutine_handle<void>) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
auto await_resume()
|
||||
{
|
||||
return this_->attached_thread_->reset_cancellation_state(
|
||||
BOOST_ASIO_MOVE_CAST(InFilter)(in_filter_),
|
||||
BOOST_ASIO_MOVE_CAST(OutFilter)(out_filter_));
|
||||
}
|
||||
};
|
||||
|
||||
return result{this,
|
||||
BOOST_ASIO_MOVE_CAST(InFilter)(reset.in_filter),
|
||||
BOOST_ASIO_MOVE_CAST(OutFilter)(reset.out_filter)};
|
||||
}
|
||||
|
||||
// This await transformation determines whether cancellation is propagated as
|
||||
// an exception.
|
||||
auto await_transform(this_coro::throw_if_cancelled_0_t)
|
||||
noexcept
|
||||
{
|
||||
struct result
|
||||
{
|
||||
awaitable_frame_base* this_;
|
||||
|
||||
bool await_ready() const noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void await_suspend(coroutine_handle<void>) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
auto await_resume()
|
||||
{
|
||||
return this_->attached_thread_->throw_if_cancelled();
|
||||
}
|
||||
};
|
||||
|
||||
return result{this};
|
||||
}
|
||||
|
||||
// This await transformation sets whether cancellation is propagated as an
|
||||
// exception.
|
||||
auto await_transform(this_coro::throw_if_cancelled_1_t throw_if_cancelled)
|
||||
noexcept
|
||||
{
|
||||
struct result
|
||||
{
|
||||
awaitable_frame_base* this_;
|
||||
bool value_;
|
||||
|
||||
bool await_ready() const noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void await_suspend(coroutine_handle<void>) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
auto await_resume()
|
||||
{
|
||||
this_->attached_thread_->throw_if_cancelled(value_);
|
||||
}
|
||||
};
|
||||
|
||||
return result{this, throw_if_cancelled.value};
|
||||
}
|
||||
|
||||
// This await transformation is used to run an async operation's initiation
|
||||
// function object after the coroutine has been suspended. This ensures that
|
||||
// immediate resumption of the coroutine in another thread does not cause a
|
||||
@@ -190,7 +405,7 @@ public:
|
||||
typename result_of<Function(awaitable_frame_base*)>::type,
|
||||
awaitable_thread<Executor>*
|
||||
>::value
|
||||
>::type* = 0)
|
||||
>::type* = nullptr)
|
||||
{
|
||||
struct result
|
||||
{
|
||||
@@ -204,7 +419,12 @@ public:
|
||||
|
||||
void await_suspend(coroutine_handle<void>) noexcept
|
||||
{
|
||||
function_(this_);
|
||||
this_->after_suspend(
|
||||
[](void* arg)
|
||||
{
|
||||
result* r = static_cast<result*>(arg);
|
||||
r->function_(r->this_);
|
||||
}, this);
|
||||
}
|
||||
|
||||
void await_resume() const noexcept
|
||||
@@ -215,6 +435,31 @@ public:
|
||||
return result{std::move(f), this};
|
||||
}
|
||||
|
||||
// Access the awaitable thread's has_context_switched_ flag.
|
||||
auto await_transform(detail::awaitable_thread_has_context_switched) noexcept
|
||||
{
|
||||
struct result
|
||||
{
|
||||
awaitable_frame_base* this_;
|
||||
|
||||
bool await_ready() const noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void await_suspend(coroutine_handle<void>) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
bool& await_resume() const noexcept
|
||||
{
|
||||
return this_->attached_thread_->entry_point()->has_context_switched_;
|
||||
}
|
||||
};
|
||||
|
||||
return result{this};
|
||||
}
|
||||
|
||||
void attach_thread(awaitable_thread<Executor>* handler) noexcept
|
||||
{
|
||||
attached_thread_ = handler;
|
||||
@@ -222,6 +467,7 @@ public:
|
||||
|
||||
awaitable_thread<Executor>* detach_thread() noexcept
|
||||
{
|
||||
attached_thread_->entry_point()->has_context_switched_ = true;
|
||||
return std::exchange(attached_thread_, nullptr);
|
||||
}
|
||||
|
||||
@@ -229,7 +475,7 @@ public:
|
||||
{
|
||||
caller_ = caller;
|
||||
attached_thread_ = caller_->attached_thread_;
|
||||
attached_thread_->top_of_stack_ = this;
|
||||
attached_thread_->entry_point()->top_of_stack_ = this;
|
||||
caller_->attached_thread_ = nullptr;
|
||||
}
|
||||
|
||||
@@ -237,14 +483,30 @@ public:
|
||||
{
|
||||
if (caller_)
|
||||
caller_->attached_thread_ = attached_thread_;
|
||||
attached_thread_->top_of_stack_ = caller_;
|
||||
attached_thread_->entry_point()->top_of_stack_ = caller_;
|
||||
attached_thread_ = nullptr;
|
||||
caller_ = nullptr;
|
||||
}
|
||||
|
||||
struct resume_context
|
||||
{
|
||||
void (*after_suspend_fn_)(void*) = nullptr;
|
||||
void *after_suspend_arg_ = nullptr;
|
||||
};
|
||||
|
||||
void resume()
|
||||
{
|
||||
resume_context context;
|
||||
resume_context_ = &context;
|
||||
coro_.resume();
|
||||
if (context.after_suspend_fn_)
|
||||
context.after_suspend_fn_(context.after_suspend_arg_);
|
||||
}
|
||||
|
||||
void after_suspend(void (*fn)(void*), void* arg)
|
||||
{
|
||||
resume_context_->after_suspend_fn_ = fn;
|
||||
resume_context_->after_suspend_arg_ = arg;
|
||||
}
|
||||
|
||||
void destroy()
|
||||
@@ -257,6 +519,7 @@ protected:
|
||||
awaitable_thread<Executor>* attached_thread_ = nullptr;
|
||||
awaitable_frame_base<Executor>* caller_ = nullptr;
|
||||
std::exception_ptr pending_exception_ = nullptr;
|
||||
resume_context* resume_context_ = nullptr;
|
||||
};
|
||||
|
||||
template <typename T, typename Executor>
|
||||
@@ -332,25 +595,88 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct awaitable_thread_entry_point {};
|
||||
|
||||
template <typename Executor>
|
||||
class awaitable_frame<awaitable_thread_entry_point, Executor>
|
||||
: public awaitable_frame_base<Executor>
|
||||
{
|
||||
public:
|
||||
awaitable_frame()
|
||||
: top_of_stack_(0),
|
||||
has_executor_(false),
|
||||
has_context_switched_(false),
|
||||
throw_if_cancelled_(true)
|
||||
{
|
||||
}
|
||||
|
||||
~awaitable_frame()
|
||||
{
|
||||
if (has_executor_)
|
||||
u_.executor_.~Executor();
|
||||
}
|
||||
|
||||
awaitable<awaitable_thread_entry_point, Executor> get_return_object()
|
||||
{
|
||||
this->coro_ = coroutine_handle<awaitable_frame>::from_promise(*this);
|
||||
return awaitable<awaitable_thread_entry_point, Executor>(this);
|
||||
};
|
||||
|
||||
void return_void()
|
||||
{
|
||||
}
|
||||
|
||||
void get()
|
||||
{
|
||||
this->caller_ = nullptr;
|
||||
this->rethrow_exception();
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename> friend class awaitable_frame_base;
|
||||
template <typename, typename> friend class awaitable_async_op_handler;
|
||||
template <typename, typename> friend class awaitable_handler_base;
|
||||
template <typename> friend class awaitable_thread;
|
||||
|
||||
union u
|
||||
{
|
||||
u() {}
|
||||
~u() {}
|
||||
char c_;
|
||||
Executor executor_;
|
||||
} u_;
|
||||
|
||||
awaitable_frame_base<Executor>* top_of_stack_;
|
||||
boost::asio::cancellation_slot parent_cancellation_slot_;
|
||||
boost::asio::cancellation_state cancellation_state_;
|
||||
bool has_executor_;
|
||||
bool has_context_switched_;
|
||||
bool throw_if_cancelled_;
|
||||
};
|
||||
|
||||
template <typename Executor>
|
||||
class awaitable_thread
|
||||
{
|
||||
public:
|
||||
typedef Executor executor_type;
|
||||
typedef cancellation_slot cancellation_slot_type;
|
||||
|
||||
// Construct from the entry point of a new thread of execution.
|
||||
awaitable_thread(awaitable<void, Executor> p, const Executor& ex)
|
||||
: bottom_of_stack_(std::move(p)),
|
||||
top_of_stack_(bottom_of_stack_.frame_),
|
||||
executor_(ex)
|
||||
awaitable_thread(awaitable<awaitable_thread_entry_point, Executor> p,
|
||||
const Executor& ex, cancellation_slot parent_cancel_slot,
|
||||
cancellation_state cancel_state)
|
||||
: bottom_of_stack_(std::move(p))
|
||||
{
|
||||
bottom_of_stack_.frame_->top_of_stack_ = bottom_of_stack_.frame_;
|
||||
new (&bottom_of_stack_.frame_->u_.executor_) Executor(ex);
|
||||
bottom_of_stack_.frame_->has_executor_ = true;
|
||||
bottom_of_stack_.frame_->parent_cancellation_slot_ = parent_cancel_slot;
|
||||
bottom_of_stack_.frame_->cancellation_state_ = cancel_state;
|
||||
}
|
||||
|
||||
// Transfer ownership from another awaitable_thread.
|
||||
awaitable_thread(awaitable_thread&& other) noexcept
|
||||
: bottom_of_stack_(std::move(other.bottom_of_stack_)),
|
||||
top_of_stack_(std::exchange(other.top_of_stack_, nullptr)),
|
||||
executor_(std::move(other.executor_))
|
||||
: bottom_of_stack_(std::move(other.bottom_of_stack_))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -361,23 +687,74 @@ public:
|
||||
if (bottom_of_stack_.valid())
|
||||
{
|
||||
// Coroutine "stack unwinding" must be performed through the executor.
|
||||
(post)(executor_,
|
||||
auto* bottom_frame = bottom_of_stack_.frame_;
|
||||
(post)(bottom_frame->u_.executor_,
|
||||
[a = std::move(bottom_of_stack_)]() mutable
|
||||
{
|
||||
awaitable<void, Executor>(std::move(a));
|
||||
(void)awaitable<awaitable_thread_entry_point, Executor>(
|
||||
std::move(a));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
awaitable_frame<awaitable_thread_entry_point, Executor>* entry_point()
|
||||
{
|
||||
return bottom_of_stack_.frame_;
|
||||
}
|
||||
|
||||
executor_type get_executor() const noexcept
|
||||
{
|
||||
return executor_;
|
||||
return bottom_of_stack_.frame_->u_.executor_;
|
||||
}
|
||||
|
||||
cancellation_state get_cancellation_state() const noexcept
|
||||
{
|
||||
return bottom_of_stack_.frame_->cancellation_state_;
|
||||
}
|
||||
|
||||
void reset_cancellation_state()
|
||||
{
|
||||
bottom_of_stack_.frame_->cancellation_state_ =
|
||||
cancellation_state(bottom_of_stack_.frame_->parent_cancellation_slot_);
|
||||
}
|
||||
|
||||
template <typename Filter>
|
||||
void reset_cancellation_state(BOOST_ASIO_MOVE_ARG(Filter) filter)
|
||||
{
|
||||
bottom_of_stack_.frame_->cancellation_state_ =
|
||||
cancellation_state(bottom_of_stack_.frame_->parent_cancellation_slot_,
|
||||
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)
|
||||
{
|
||||
bottom_of_stack_.frame_->cancellation_state_ =
|
||||
cancellation_state(bottom_of_stack_.frame_->parent_cancellation_slot_,
|
||||
BOOST_ASIO_MOVE_CAST(InFilter)(in_filter),
|
||||
BOOST_ASIO_MOVE_CAST(OutFilter)(out_filter));
|
||||
}
|
||||
|
||||
bool throw_if_cancelled() const
|
||||
{
|
||||
return bottom_of_stack_.frame_->throw_if_cancelled_;
|
||||
}
|
||||
|
||||
void throw_if_cancelled(bool value)
|
||||
{
|
||||
bottom_of_stack_.frame_->throw_if_cancelled_ = value;
|
||||
}
|
||||
|
||||
cancellation_slot_type get_cancellation_slot() const noexcept
|
||||
{
|
||||
return bottom_of_stack_.frame_->cancellation_state_.slot();
|
||||
}
|
||||
|
||||
// Launch a new thread of execution.
|
||||
void launch()
|
||||
{
|
||||
top_of_stack_->attach_thread(this);
|
||||
bottom_of_stack_.frame_->top_of_stack_->attach_thread(this);
|
||||
pump();
|
||||
}
|
||||
|
||||
@@ -388,17 +765,399 @@ protected:
|
||||
// has been transferred to another resumable_thread object.
|
||||
void pump()
|
||||
{
|
||||
do top_of_stack_->resume(); while (top_of_stack_);
|
||||
if (bottom_of_stack_.valid())
|
||||
do
|
||||
bottom_of_stack_.frame_->top_of_stack_->resume();
|
||||
while (bottom_of_stack_.frame_ && bottom_of_stack_.frame_->top_of_stack_);
|
||||
|
||||
if (bottom_of_stack_.frame_)
|
||||
{
|
||||
awaitable<void, Executor> a(std::move(bottom_of_stack_));
|
||||
awaitable<awaitable_thread_entry_point, Executor> a(
|
||||
std::move(bottom_of_stack_));
|
||||
a.frame_->rethrow_exception();
|
||||
}
|
||||
}
|
||||
|
||||
awaitable<void, Executor> bottom_of_stack_;
|
||||
awaitable_frame_base<Executor>* top_of_stack_;
|
||||
executor_type executor_;
|
||||
awaitable<awaitable_thread_entry_point, Executor> bottom_of_stack_;
|
||||
};
|
||||
|
||||
template <typename Signature, typename Executor>
|
||||
class awaitable_async_op_handler;
|
||||
|
||||
template <typename R, typename Executor>
|
||||
class awaitable_async_op_handler<R(), Executor>
|
||||
: public awaitable_thread<Executor>
|
||||
{
|
||||
public:
|
||||
struct result_type {};
|
||||
|
||||
awaitable_async_op_handler(
|
||||
awaitable_thread<Executor>* h, result_type&)
|
||||
: awaitable_thread<Executor>(std::move(*h))
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
this->entry_point()->top_of_stack_->attach_thread(this);
|
||||
this->entry_point()->top_of_stack_->clear_cancellation_slot();
|
||||
this->pump();
|
||||
}
|
||||
|
||||
static void resume(result_type&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename Executor>
|
||||
class awaitable_async_op_handler<R(boost::system::error_code), Executor>
|
||||
: public awaitable_thread<Executor>
|
||||
{
|
||||
public:
|
||||
typedef boost::system::error_code* result_type;
|
||||
|
||||
awaitable_async_op_handler(
|
||||
awaitable_thread<Executor>* h, result_type& result)
|
||||
: awaitable_thread<Executor>(std::move(*h)),
|
||||
result_(result)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(boost::system::error_code ec)
|
||||
{
|
||||
result_ = &ec;
|
||||
this->entry_point()->top_of_stack_->attach_thread(this);
|
||||
this->entry_point()->top_of_stack_->clear_cancellation_slot();
|
||||
this->pump();
|
||||
}
|
||||
|
||||
static void resume(result_type& result)
|
||||
{
|
||||
throw_error(*result);
|
||||
}
|
||||
|
||||
private:
|
||||
result_type& result_;
|
||||
};
|
||||
|
||||
template <typename R, typename Executor>
|
||||
class awaitable_async_op_handler<R(std::exception_ptr), Executor>
|
||||
: public awaitable_thread<Executor>
|
||||
{
|
||||
public:
|
||||
typedef std::exception_ptr* result_type;
|
||||
|
||||
awaitable_async_op_handler(
|
||||
awaitable_thread<Executor>* h, result_type& result)
|
||||
: awaitable_thread<Executor>(std::move(*h)),
|
||||
result_(result)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(std::exception_ptr ex)
|
||||
{
|
||||
result_ = &ex;
|
||||
this->entry_point()->top_of_stack_->attach_thread(this);
|
||||
this->entry_point()->top_of_stack_->clear_cancellation_slot();
|
||||
this->pump();
|
||||
}
|
||||
|
||||
static void resume(result_type& result)
|
||||
{
|
||||
if (*result)
|
||||
{
|
||||
std::exception_ptr ex = std::exchange(*result, nullptr);
|
||||
std::rethrow_exception(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
result_type& result_;
|
||||
};
|
||||
|
||||
template <typename R, typename T, typename Executor>
|
||||
class awaitable_async_op_handler<R(T), Executor>
|
||||
: public awaitable_thread<Executor>
|
||||
{
|
||||
public:
|
||||
typedef T* result_type;
|
||||
|
||||
awaitable_async_op_handler(
|
||||
awaitable_thread<Executor>* h, result_type& result)
|
||||
: awaitable_thread<Executor>(std::move(*h)),
|
||||
result_(result)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(T result)
|
||||
{
|
||||
result_ = &result;
|
||||
this->entry_point()->top_of_stack_->attach_thread(this);
|
||||
this->entry_point()->top_of_stack_->clear_cancellation_slot();
|
||||
this->pump();
|
||||
}
|
||||
|
||||
static T resume(result_type& result)
|
||||
{
|
||||
return std::move(*result);
|
||||
}
|
||||
|
||||
private:
|
||||
result_type& result_;
|
||||
};
|
||||
|
||||
template <typename R, typename T, typename Executor>
|
||||
class awaitable_async_op_handler<R(boost::system::error_code, T), Executor>
|
||||
: public awaitable_thread<Executor>
|
||||
{
|
||||
public:
|
||||
struct result_type
|
||||
{
|
||||
boost::system::error_code* ec_;
|
||||
T* value_;
|
||||
};
|
||||
|
||||
awaitable_async_op_handler(
|
||||
awaitable_thread<Executor>* h, result_type& result)
|
||||
: awaitable_thread<Executor>(std::move(*h)),
|
||||
result_(result)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(boost::system::error_code ec, T value)
|
||||
{
|
||||
result_.ec_ = &ec;
|
||||
result_.value_ = &value;
|
||||
this->entry_point()->top_of_stack_->attach_thread(this);
|
||||
this->entry_point()->top_of_stack_->clear_cancellation_slot();
|
||||
this->pump();
|
||||
}
|
||||
|
||||
static T resume(result_type& result)
|
||||
{
|
||||
throw_error(*result.ec_);
|
||||
return std::move(*result.value_);
|
||||
}
|
||||
|
||||
private:
|
||||
result_type& result_;
|
||||
};
|
||||
|
||||
template <typename R, typename T, typename Executor>
|
||||
class awaitable_async_op_handler<R(std::exception_ptr, T), Executor>
|
||||
: public awaitable_thread<Executor>
|
||||
{
|
||||
public:
|
||||
struct result_type
|
||||
{
|
||||
std::exception_ptr* ex_;
|
||||
T* value_;
|
||||
};
|
||||
|
||||
awaitable_async_op_handler(
|
||||
awaitable_thread<Executor>* h, result_type& result)
|
||||
: awaitable_thread<Executor>(std::move(*h)),
|
||||
result_(result)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(std::exception_ptr ex, T value)
|
||||
{
|
||||
result_.ex_ = &ex;
|
||||
result_.value_ = &value;
|
||||
this->entry_point()->top_of_stack_->attach_thread(this);
|
||||
this->entry_point()->top_of_stack_->clear_cancellation_slot();
|
||||
this->pump();
|
||||
}
|
||||
|
||||
static T resume(result_type& result)
|
||||
{
|
||||
if (*result.ex_)
|
||||
{
|
||||
std::exception_ptr ex = std::exchange(*result.ex_, nullptr);
|
||||
std::rethrow_exception(ex);
|
||||
}
|
||||
return std::move(*result.value_);
|
||||
}
|
||||
|
||||
private:
|
||||
result_type& result_;
|
||||
};
|
||||
|
||||
template <typename R, typename... Ts, typename Executor>
|
||||
class awaitable_async_op_handler<R(Ts...), Executor>
|
||||
: public awaitable_thread<Executor>
|
||||
{
|
||||
public:
|
||||
typedef std::tuple<Ts...>* result_type;
|
||||
|
||||
awaitable_async_op_handler(
|
||||
awaitable_thread<Executor>* h, result_type& result)
|
||||
: awaitable_thread<Executor>(std::move(*h)),
|
||||
result_(result)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void operator()(Args&&... args)
|
||||
{
|
||||
std::tuple<Ts...> result(std::forward<Args>(args)...);
|
||||
result_ = &result;
|
||||
this->entry_point()->top_of_stack_->attach_thread(this);
|
||||
this->entry_point()->top_of_stack_->clear_cancellation_slot();
|
||||
this->pump();
|
||||
}
|
||||
|
||||
static std::tuple<Ts...> resume(result_type& result)
|
||||
{
|
||||
return std::move(*result);
|
||||
}
|
||||
|
||||
private:
|
||||
result_type& result_;
|
||||
};
|
||||
|
||||
template <typename R, typename... Ts, typename Executor>
|
||||
class awaitable_async_op_handler<R(boost::system::error_code, Ts...), Executor>
|
||||
: public awaitable_thread<Executor>
|
||||
{
|
||||
public:
|
||||
struct result_type
|
||||
{
|
||||
boost::system::error_code* ec_;
|
||||
std::tuple<Ts...>* value_;
|
||||
};
|
||||
|
||||
awaitable_async_op_handler(
|
||||
awaitable_thread<Executor>* h, result_type& result)
|
||||
: awaitable_thread<Executor>(std::move(*h)),
|
||||
result_(result)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void operator()(boost::system::error_code ec, Args&&... args)
|
||||
{
|
||||
result_.ec_ = &ec;
|
||||
std::tuple<Ts...> value(std::forward<Args>(args)...);
|
||||
result_.value_ = &value;
|
||||
this->entry_point()->top_of_stack_->attach_thread(this);
|
||||
this->entry_point()->top_of_stack_->clear_cancellation_slot();
|
||||
this->pump();
|
||||
}
|
||||
|
||||
static std::tuple<Ts...> resume(result_type& result)
|
||||
{
|
||||
throw_error(*result.ec_);
|
||||
return std::move(*result.value_);
|
||||
}
|
||||
|
||||
private:
|
||||
result_type& result_;
|
||||
};
|
||||
|
||||
template <typename R, typename... Ts, typename Executor>
|
||||
class awaitable_async_op_handler<R(std::exception_ptr, Ts...), Executor>
|
||||
: public awaitable_thread<Executor>
|
||||
{
|
||||
public:
|
||||
struct result_type
|
||||
{
|
||||
std::exception_ptr* ex_;
|
||||
std::tuple<Ts...>* value_;
|
||||
};
|
||||
|
||||
awaitable_async_op_handler(
|
||||
awaitable_thread<Executor>* h, result_type& result)
|
||||
: awaitable_thread<Executor>(std::move(*h)),
|
||||
result_(result)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void operator()(std::exception_ptr ex, Args&&... args)
|
||||
{
|
||||
result_.ex_ = &ex;
|
||||
std::tuple<Ts...> value(std::forward<Args>(args)...);
|
||||
result_.value_ = &value;
|
||||
this->entry_point()->top_of_stack_->attach_thread(this);
|
||||
this->entry_point()->top_of_stack_->clear_cancellation_slot();
|
||||
this->pump();
|
||||
}
|
||||
|
||||
static std::tuple<Ts...> resume(result_type& result)
|
||||
{
|
||||
if (*result.ex_)
|
||||
{
|
||||
std::exception_ptr ex = std::exchange(*result.ex_, nullptr);
|
||||
std::rethrow_exception(ex);
|
||||
}
|
||||
return std::move(*result.value_);
|
||||
}
|
||||
|
||||
private:
|
||||
result_type& result_;
|
||||
};
|
||||
|
||||
template <typename Signature, typename Op, typename Executor>
|
||||
class awaitable_async_op
|
||||
{
|
||||
public:
|
||||
typedef awaitable_async_op_handler<Signature, Executor> handler_type;
|
||||
|
||||
awaitable_async_op(Op&& o, awaitable_frame_base<Executor>* frame
|
||||
#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
# if defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
|
||||
, const detail::source_location& location
|
||||
# endif // defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
|
||||
#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
)
|
||||
: op_(std::forward<Op>(o)),
|
||||
frame_(frame),
|
||||
result_()
|
||||
#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
# if defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
|
||||
, location_(location)
|
||||
# endif // defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
|
||||
#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
{
|
||||
}
|
||||
|
||||
bool await_ready() const noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void await_suspend(coroutine_handle<void>)
|
||||
{
|
||||
frame_->after_suspend(
|
||||
[](void* arg)
|
||||
{
|
||||
awaitable_async_op* self = static_cast<awaitable_async_op*>(arg);
|
||||
#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
# if defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
|
||||
BOOST_ASIO_HANDLER_LOCATION((self->location_.file_name(),
|
||||
self->location_.line(), self->location_.function_name()));
|
||||
# endif // defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
|
||||
#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
std::forward<Op&&>(self->op_)(
|
||||
handler_type(self->frame_->detach_thread(), self->result_));
|
||||
}, this);
|
||||
}
|
||||
|
||||
auto await_resume()
|
||||
{
|
||||
return handler_type::resume(result_);
|
||||
}
|
||||
|
||||
private:
|
||||
Op&& op_;
|
||||
awaitable_frame_base<Executor>* frame_;
|
||||
typename handler_type::result_type result_;
|
||||
#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
# if defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
|
||||
detail::source_location location_;
|
||||
# endif // defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
|
||||
#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
@@ -406,6 +1165,19 @@ protected:
|
||||
} // namespace boost
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
# if defined(BOOST_ASIO_HAS_STD_COROUTINE)
|
||||
|
||||
namespace std {
|
||||
|
||||
template <typename T, typename Executor, typename... Args>
|
||||
struct coroutine_traits<boost::asio::awaitable<T, Executor>, Args...>
|
||||
{
|
||||
typedef boost::asio::detail::awaitable_frame<T, Executor> promise_type;
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
# else // defined(BOOST_ASIO_HAS_STD_COROUTINE)
|
||||
|
||||
namespace std { namespace experimental {
|
||||
|
||||
@@ -417,6 +1189,7 @@ struct coroutine_traits<boost::asio::awaitable<T, Executor>, Args...>
|
||||
|
||||
}} // namespace std::experimental
|
||||
|
||||
# endif // defined(BOOST_ASIO_HAS_STD_COROUTINE)
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/buffered_read_stream.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -15,13 +15,13 @@
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/associator.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>
|
||||
#include <boost/asio/detail/handler_type_requirements.hpp>
|
||||
#include <boost/asio/detail/non_const_lvalue.hpp>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace detail
|
||||
const std::size_t bytes_transferred)
|
||||
{
|
||||
storage_.resize(previous_size_ + bytes_transferred);
|
||||
handler_(ec, bytes_transferred);
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(ec, bytes_transferred);
|
||||
}
|
||||
|
||||
//private:
|
||||
@@ -101,19 +101,29 @@ namespace detail
|
||||
};
|
||||
|
||||
template <typename ReadHandler>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
inline asio_handler_allocate_is_deprecated
|
||||
asio_handler_allocate(std::size_t size,
|
||||
buffered_fill_handler<ReadHandler>* this_handler)
|
||||
{
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
|
||||
return asio_handler_allocate_is_no_longer_used();
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename ReadHandler>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
inline asio_handler_deallocate_is_deprecated
|
||||
asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
buffered_fill_handler<ReadHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_deallocate_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename ReadHandler>
|
||||
@@ -125,26 +135,50 @@ namespace detail
|
||||
}
|
||||
|
||||
template <typename Function, typename ReadHandler>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(Function& function,
|
||||
buffered_fill_handler<ReadHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Function, typename ReadHandler>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(const Function& function,
|
||||
buffered_fill_handler<ReadHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
struct initiate_async_buffered_fill
|
||||
template <typename Stream>
|
||||
class initiate_async_buffered_fill
|
||||
{
|
||||
template <typename ReadHandler, typename Stream>
|
||||
public:
|
||||
typedef typename remove_reference<
|
||||
Stream>::type::lowest_layer_type::executor_type executor_type;
|
||||
|
||||
explicit initiate_async_buffered_fill(
|
||||
typename remove_reference<Stream>::type& next_layer)
|
||||
: next_layer_(next_layer)
|
||||
{
|
||||
}
|
||||
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return next_layer_.lowest_layer().get_executor();
|
||||
}
|
||||
|
||||
template <typename ReadHandler>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
|
||||
buffered_stream_storage* storage, Stream* next_layer) const
|
||||
buffered_stream_storage* storage) const
|
||||
{
|
||||
// If you get an error on the following line it means that your handler
|
||||
// does not meet the documented type requirements for a ReadHandler.
|
||||
@@ -153,56 +187,65 @@ namespace detail
|
||||
non_const_lvalue<ReadHandler> handler2(handler);
|
||||
std::size_t previous_size = storage->size();
|
||||
storage->resize(storage->capacity());
|
||||
next_layer->async_read_some(
|
||||
next_layer_.async_read_some(
|
||||
buffer(
|
||||
storage->data() + previous_size,
|
||||
storage->size() - previous_size),
|
||||
buffered_fill_handler<typename decay<ReadHandler>::type>(
|
||||
*storage, previous_size, handler2.value));
|
||||
}
|
||||
|
||||
private:
|
||||
typename remove_reference<Stream>::type& next_layer_;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename ReadHandler, typename Allocator>
|
||||
struct associated_allocator<
|
||||
detail::buffered_fill_handler<ReadHandler>, Allocator>
|
||||
template <template <typename, typename> class Associator,
|
||||
typename ReadHandler, typename DefaultCandidate>
|
||||
struct associator<Associator,
|
||||
detail::buffered_fill_handler<ReadHandler>,
|
||||
DefaultCandidate>
|
||||
: Associator<ReadHandler, DefaultCandidate>
|
||||
{
|
||||
typedef typename associated_allocator<ReadHandler, Allocator>::type type;
|
||||
|
||||
static type get(const detail::buffered_fill_handler<ReadHandler>& h,
|
||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
||||
static typename Associator<ReadHandler, DefaultCandidate>::type
|
||||
get(const detail::buffered_fill_handler<ReadHandler>& h) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
|
||||
return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ReadHandler, typename Executor>
|
||||
struct associated_executor<
|
||||
detail::buffered_fill_handler<ReadHandler>, Executor>
|
||||
{
|
||||
typedef typename associated_executor<ReadHandler, Executor>::type type;
|
||||
|
||||
static type get(const detail::buffered_fill_handler<ReadHandler>& h,
|
||||
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
|
||||
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
|
||||
typename Associator<ReadHandler, DefaultCandidate>::type)
|
||||
get(const detail::buffered_fill_handler<ReadHandler>& h,
|
||||
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
|
||||
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
|
||||
Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))
|
||||
{
|
||||
return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
|
||||
return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename Stream>
|
||||
template <typename ReadHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
std::size_t)) ReadHandler>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadHandler,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
buffered_read_stream<Stream>::async_fill(
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
declval<detail::initiate_async_buffered_fill<Stream> >(),
|
||||
handler, declval<detail::buffered_stream_storage*>())))
|
||||
{
|
||||
return async_initiate<ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
detail::initiate_async_buffered_fill(), handler, &storage_, &next_layer_);
|
||||
detail::initiate_async_buffered_fill<Stream>(next_layer_),
|
||||
handler, &storage_);
|
||||
}
|
||||
|
||||
template <typename Stream>
|
||||
@@ -272,14 +315,14 @@ namespace detail
|
||||
if (ec || storage_.empty())
|
||||
{
|
||||
const std::size_t length = 0;
|
||||
handler_(ec, length);
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(ec, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::size_t bytes_copied = boost::asio::buffer_copy(
|
||||
buffers_, storage_.data(), storage_.size());
|
||||
storage_.consume(bytes_copied);
|
||||
handler_(ec, bytes_copied);
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(ec, bytes_copied);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,21 +333,31 @@ namespace detail
|
||||
};
|
||||
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
inline asio_handler_allocate_is_deprecated
|
||||
asio_handler_allocate(std::size_t size,
|
||||
buffered_read_some_handler<
|
||||
MutableBufferSequence, ReadHandler>* this_handler)
|
||||
{
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
|
||||
return asio_handler_allocate_is_no_longer_used();
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
inline asio_handler_deallocate_is_deprecated
|
||||
asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
buffered_read_some_handler<
|
||||
MutableBufferSequence, ReadHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_deallocate_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
@@ -318,30 +371,53 @@ namespace detail
|
||||
|
||||
template <typename Function, typename MutableBufferSequence,
|
||||
typename ReadHandler>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(Function& function,
|
||||
buffered_read_some_handler<
|
||||
MutableBufferSequence, ReadHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Function, typename MutableBufferSequence,
|
||||
typename ReadHandler>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(const Function& function,
|
||||
buffered_read_some_handler<
|
||||
MutableBufferSequence, ReadHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
struct initiate_async_buffered_read_some
|
||||
template <typename Stream>
|
||||
class initiate_async_buffered_read_some
|
||||
{
|
||||
template <typename ReadHandler, typename Stream,
|
||||
typename MutableBufferSequence>
|
||||
public:
|
||||
typedef typename remove_reference<
|
||||
Stream>::type::lowest_layer_type::executor_type executor_type;
|
||||
|
||||
explicit initiate_async_buffered_read_some(
|
||||
typename remove_reference<Stream>::type& next_layer)
|
||||
: next_layer_(next_layer)
|
||||
{
|
||||
}
|
||||
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return next_layer_.lowest_layer().get_executor();
|
||||
}
|
||||
|
||||
template <typename ReadHandler, typename MutableBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
|
||||
buffered_stream_storage* storage, Stream* next_layer,
|
||||
buffered_stream_storage* storage,
|
||||
const MutableBufferSequence& buffers) const
|
||||
{
|
||||
// If you get an error on the following line it means that your handler
|
||||
@@ -352,73 +428,76 @@ namespace detail
|
||||
non_const_lvalue<ReadHandler> handler2(handler);
|
||||
if (buffer_size(buffers) == 0 || !storage->empty())
|
||||
{
|
||||
next_layer->async_read_some(BOOST_ASIO_MUTABLE_BUFFER(0, 0),
|
||||
next_layer_.async_read_some(BOOST_ASIO_MUTABLE_BUFFER(0, 0),
|
||||
buffered_read_some_handler<MutableBufferSequence,
|
||||
typename decay<ReadHandler>::type>(
|
||||
*storage, buffers, handler2.value));
|
||||
}
|
||||
else
|
||||
{
|
||||
initiate_async_buffered_fill()(
|
||||
initiate_async_buffered_fill<Stream>(this->next_layer_)(
|
||||
buffered_read_some_handler<MutableBufferSequence,
|
||||
typename decay<ReadHandler>::type>(
|
||||
*storage, buffers, handler2.value),
|
||||
storage, next_layer);
|
||||
storage);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
typename remove_reference<Stream>::type& next_layer_;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename MutableBufferSequence,
|
||||
typename ReadHandler, typename Allocator>
|
||||
struct associated_allocator<
|
||||
template <template <typename, typename> class Associator,
|
||||
typename MutableBufferSequence, typename ReadHandler,
|
||||
typename DefaultCandidate>
|
||||
struct associator<Associator,
|
||||
detail::buffered_read_some_handler<MutableBufferSequence, ReadHandler>,
|
||||
Allocator>
|
||||
DefaultCandidate>
|
||||
: Associator<ReadHandler, DefaultCandidate>
|
||||
{
|
||||
typedef typename associated_allocator<ReadHandler, Allocator>::type type;
|
||||
|
||||
static type get(
|
||||
const detail::buffered_read_some_handler<
|
||||
MutableBufferSequence, ReadHandler>& h,
|
||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
||||
static typename Associator<ReadHandler, DefaultCandidate>::type
|
||||
get(const detail::buffered_read_some_handler<
|
||||
MutableBufferSequence, ReadHandler>& h) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
|
||||
return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename MutableBufferSequence,
|
||||
typename ReadHandler, typename Executor>
|
||||
struct associated_executor<
|
||||
detail::buffered_read_some_handler<MutableBufferSequence, ReadHandler>,
|
||||
Executor>
|
||||
{
|
||||
typedef typename associated_executor<ReadHandler, Executor>::type type;
|
||||
|
||||
static type get(
|
||||
const detail::buffered_read_some_handler<
|
||||
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
|
||||
typename Associator<ReadHandler, DefaultCandidate>::type)
|
||||
get(const detail::buffered_read_some_handler<
|
||||
MutableBufferSequence, ReadHandler>& h,
|
||||
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
|
||||
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
|
||||
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
|
||||
Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))
|
||||
{
|
||||
return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
|
||||
return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename Stream>
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
|
||||
template <typename MutableBufferSequence,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
std::size_t)) ReadHandler>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadHandler,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
buffered_read_stream<Stream>::async_read_some(
|
||||
const MutableBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
declval<detail::initiate_async_buffered_read_some<Stream> >(),
|
||||
handler, declval<detail::buffered_stream_storage*>(), buffers)))
|
||||
{
|
||||
return async_initiate<ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
detail::initiate_async_buffered_read_some(),
|
||||
handler, &storage_, &next_layer_, buffers);
|
||||
detail::initiate_async_buffered_read_some<Stream>(next_layer_),
|
||||
handler, &storage_, buffers);
|
||||
}
|
||||
|
||||
template <typename Stream>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/buffered_write_stream.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -15,8 +15,7 @@
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/associator.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>
|
||||
@@ -78,7 +77,7 @@ namespace detail
|
||||
const std::size_t bytes_written)
|
||||
{
|
||||
storage_.consume(bytes_written);
|
||||
handler_(ec, bytes_written);
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec, bytes_written);
|
||||
}
|
||||
|
||||
//private:
|
||||
@@ -87,19 +86,29 @@ namespace detail
|
||||
};
|
||||
|
||||
template <typename WriteHandler>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
inline asio_handler_allocate_is_deprecated
|
||||
asio_handler_allocate(std::size_t size,
|
||||
buffered_flush_handler<WriteHandler>* this_handler)
|
||||
{
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
|
||||
return asio_handler_allocate_is_no_longer_used();
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename WriteHandler>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
inline asio_handler_deallocate_is_deprecated
|
||||
asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
buffered_flush_handler<WriteHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_deallocate_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename WriteHandler>
|
||||
@@ -111,80 +120,112 @@ namespace detail
|
||||
}
|
||||
|
||||
template <typename Function, typename WriteHandler>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(Function& function,
|
||||
buffered_flush_handler<WriteHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Function, typename WriteHandler>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(const Function& function,
|
||||
buffered_flush_handler<WriteHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
struct initiate_async_buffered_flush
|
||||
template <typename Stream>
|
||||
class initiate_async_buffered_flush
|
||||
{
|
||||
template <typename WriteHandler, typename Stream>
|
||||
public:
|
||||
typedef typename remove_reference<
|
||||
Stream>::type::lowest_layer_type::executor_type executor_type;
|
||||
|
||||
explicit initiate_async_buffered_flush(
|
||||
typename remove_reference<Stream>::type& next_layer)
|
||||
: next_layer_(next_layer)
|
||||
{
|
||||
}
|
||||
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return next_layer_.lowest_layer().get_executor();
|
||||
}
|
||||
|
||||
template <typename WriteHandler>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
|
||||
buffered_stream_storage* storage, Stream* next_layer) const
|
||||
buffered_stream_storage* storage) const
|
||||
{
|
||||
// If you get an error on the following line it means that your handler
|
||||
// does not meet the documented type requirements for a WriteHandler.
|
||||
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
|
||||
|
||||
non_const_lvalue<WriteHandler> handler2(handler);
|
||||
async_write(*next_layer, buffer(storage->data(), storage->size()),
|
||||
async_write(next_layer_, buffer(storage->data(), storage->size()),
|
||||
buffered_flush_handler<typename decay<WriteHandler>::type>(
|
||||
*storage, handler2.value));
|
||||
}
|
||||
|
||||
private:
|
||||
typename remove_reference<Stream>::type& next_layer_;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename WriteHandler, typename Allocator>
|
||||
struct associated_allocator<
|
||||
detail::buffered_flush_handler<WriteHandler>, Allocator>
|
||||
template <template <typename, typename> class Associator,
|
||||
typename WriteHandler, typename DefaultCandidate>
|
||||
struct associator<Associator,
|
||||
detail::buffered_flush_handler<WriteHandler>,
|
||||
DefaultCandidate>
|
||||
: Associator<WriteHandler, DefaultCandidate>
|
||||
{
|
||||
typedef typename associated_allocator<WriteHandler, Allocator>::type type;
|
||||
|
||||
static type get(const detail::buffered_flush_handler<WriteHandler>& h,
|
||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
||||
static typename Associator<WriteHandler, DefaultCandidate>::type
|
||||
get(const detail::buffered_flush_handler<WriteHandler>& h) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_allocator<WriteHandler, Allocator>::get(h.handler_, a);
|
||||
return Associator<WriteHandler, DefaultCandidate>::get(h.handler_);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename WriteHandler, typename Executor>
|
||||
struct associated_executor<
|
||||
detail::buffered_flush_handler<WriteHandler>, Executor>
|
||||
{
|
||||
typedef typename associated_executor<WriteHandler, Executor>::type type;
|
||||
|
||||
static type get(const detail::buffered_flush_handler<WriteHandler>& h,
|
||||
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
|
||||
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
|
||||
typename Associator<WriteHandler, DefaultCandidate>::type)
|
||||
get(const detail::buffered_flush_handler<WriteHandler>& h,
|
||||
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
|
||||
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
|
||||
Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)))
|
||||
{
|
||||
return associated_executor<WriteHandler, Executor>::get(h.handler_, ex);
|
||||
return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename Stream>
|
||||
template <typename WriteHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
std::size_t)) WriteHandler>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteHandler,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
buffered_write_stream<Stream>::async_flush(
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<WriteHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
declval<detail::initiate_async_buffered_flush<Stream> >(),
|
||||
handler, declval<detail::buffered_stream_storage*>())))
|
||||
{
|
||||
return async_initiate<WriteHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
detail::initiate_async_buffered_flush(),
|
||||
handler, &storage_, &next_layer_);
|
||||
detail::initiate_async_buffered_flush<Stream>(next_layer_),
|
||||
handler, &storage_);
|
||||
}
|
||||
|
||||
template <typename Stream>
|
||||
@@ -254,7 +295,7 @@ namespace detail
|
||||
if (ec)
|
||||
{
|
||||
const std::size_t length = 0;
|
||||
handler_(ec, length);
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -267,7 +308,7 @@ namespace detail
|
||||
storage_.resize(orig_size + length);
|
||||
const std::size_t bytes_copied = boost::asio::buffer_copy(
|
||||
storage_.data() + orig_size, buffers_, length);
|
||||
handler_(ec, bytes_copied);
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec, bytes_copied);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,21 +319,31 @@ namespace detail
|
||||
};
|
||||
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
inline asio_handler_allocate_is_deprecated
|
||||
asio_handler_allocate(std::size_t size,
|
||||
buffered_write_some_handler<
|
||||
ConstBufferSequence, WriteHandler>* this_handler)
|
||||
{
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
|
||||
return asio_handler_allocate_is_no_longer_used();
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
inline asio_handler_deallocate_is_deprecated
|
||||
asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
buffered_write_some_handler<
|
||||
ConstBufferSequence, WriteHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_deallocate_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
@@ -306,30 +357,53 @@ namespace detail
|
||||
|
||||
template <typename Function, typename ConstBufferSequence,
|
||||
typename WriteHandler>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(Function& function,
|
||||
buffered_write_some_handler<
|
||||
ConstBufferSequence, WriteHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Function, typename ConstBufferSequence,
|
||||
typename WriteHandler>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(const Function& function,
|
||||
buffered_write_some_handler<
|
||||
ConstBufferSequence, WriteHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
struct initiate_async_buffered_write_some
|
||||
template <typename Stream>
|
||||
class initiate_async_buffered_write_some
|
||||
{
|
||||
template <typename WriteHandler, typename Stream,
|
||||
typename ConstBufferSequence>
|
||||
public:
|
||||
typedef typename remove_reference<
|
||||
Stream>::type::lowest_layer_type::executor_type executor_type;
|
||||
|
||||
explicit initiate_async_buffered_write_some(
|
||||
typename remove_reference<Stream>::type& next_layer)
|
||||
: next_layer_(next_layer)
|
||||
{
|
||||
}
|
||||
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return next_layer_.lowest_layer().get_executor();
|
||||
}
|
||||
|
||||
template <typename WriteHandler, typename ConstBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
|
||||
buffered_stream_storage* storage, Stream* next_layer,
|
||||
buffered_stream_storage* storage,
|
||||
const ConstBufferSequence& buffers) const
|
||||
{
|
||||
// If you get an error on the following line it means that your handler
|
||||
@@ -340,73 +414,76 @@ namespace detail
|
||||
non_const_lvalue<WriteHandler> handler2(handler);
|
||||
if (buffer_size(buffers) == 0 || storage->size() < storage->capacity())
|
||||
{
|
||||
next_layer->async_write_some(BOOST_ASIO_CONST_BUFFER(0, 0),
|
||||
next_layer_.async_write_some(BOOST_ASIO_CONST_BUFFER(0, 0),
|
||||
buffered_write_some_handler<ConstBufferSequence,
|
||||
typename decay<WriteHandler>::type>(
|
||||
*storage, buffers, handler2.value));
|
||||
}
|
||||
else
|
||||
{
|
||||
initiate_async_buffered_flush()(
|
||||
initiate_async_buffered_flush<Stream>(this->next_layer_)(
|
||||
buffered_write_some_handler<ConstBufferSequence,
|
||||
typename decay<WriteHandler>::type>(
|
||||
*storage, buffers, handler2.value),
|
||||
storage, next_layer);
|
||||
storage);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
typename remove_reference<Stream>::type& next_layer_;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename ConstBufferSequence,
|
||||
typename WriteHandler, typename Allocator>
|
||||
struct associated_allocator<
|
||||
template <template <typename, typename> class Associator,
|
||||
typename ConstBufferSequence, typename WriteHandler,
|
||||
typename DefaultCandidate>
|
||||
struct associator<Associator,
|
||||
detail::buffered_write_some_handler<ConstBufferSequence, WriteHandler>,
|
||||
Allocator>
|
||||
DefaultCandidate>
|
||||
: Associator<WriteHandler, DefaultCandidate>
|
||||
{
|
||||
typedef typename associated_allocator<WriteHandler, Allocator>::type type;
|
||||
|
||||
static type get(
|
||||
const detail::buffered_write_some_handler<
|
||||
ConstBufferSequence, WriteHandler>& h,
|
||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
||||
static typename Associator<WriteHandler, DefaultCandidate>::type
|
||||
get(const detail::buffered_write_some_handler<
|
||||
ConstBufferSequence, WriteHandler>& h) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_allocator<WriteHandler, Allocator>::get(h.handler_, a);
|
||||
return Associator<WriteHandler, DefaultCandidate>::get(h.handler_);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ConstBufferSequence,
|
||||
typename WriteHandler, typename Executor>
|
||||
struct associated_executor<
|
||||
detail::buffered_write_some_handler<ConstBufferSequence, WriteHandler>,
|
||||
Executor>
|
||||
{
|
||||
typedef typename associated_executor<WriteHandler, Executor>::type type;
|
||||
|
||||
static type get(
|
||||
const detail::buffered_write_some_handler<
|
||||
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
|
||||
typename Associator<WriteHandler, DefaultCandidate>::type)
|
||||
get(const detail::buffered_write_some_handler<
|
||||
ConstBufferSequence, WriteHandler>& h,
|
||||
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
|
||||
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
|
||||
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
|
||||
Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)))
|
||||
{
|
||||
return associated_executor<WriteHandler, Executor>::get(h.handler_, ex);
|
||||
return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename Stream>
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
|
||||
template <typename ConstBufferSequence,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
std::size_t)) WriteHandler>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteHandler,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
buffered_write_stream<Stream>::async_write_some(
|
||||
const ConstBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<WriteHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
declval<detail::initiate_async_buffered_write_some<Stream> >(),
|
||||
handler, declval<detail::buffered_stream_storage*>(), buffers)))
|
||||
{
|
||||
return async_initiate<WriteHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
detail::initiate_async_buffered_write_some(),
|
||||
handler, &storage_, &next_layer_, buffers);
|
||||
detail::initiate_async_buffered_write_some<Stream>(next_layer_),
|
||||
handler, &storage_, buffers);
|
||||
}
|
||||
|
||||
template <typename Stream>
|
||||
|
||||
98
linx64/include/boost/asio/impl/cancellation_signal.ipp
Normal file
98
linx64/include/boost/asio/impl/cancellation_signal.ipp
Normal file
@@ -0,0 +1,98 @@
|
||||
//
|
||||
// impl/cancellation_signal.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2023 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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_ASIO_IMPL_CANCELLATION_SIGNAL_IPP
|
||||
#define BOOST_ASIO_IMPL_CANCELLATION_SIGNAL_IPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <boost/asio/cancellation_signal.hpp>
|
||||
#include <boost/asio/detail/thread_context.hpp>
|
||||
#include <boost/asio/detail/thread_info_base.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
cancellation_signal::~cancellation_signal()
|
||||
{
|
||||
if (handler_)
|
||||
{
|
||||
std::pair<void*, std::size_t> mem = handler_->destroy();
|
||||
detail::thread_info_base::deallocate(
|
||||
detail::thread_info_base::cancellation_signal_tag(),
|
||||
detail::thread_context::top_of_thread_call_stack(),
|
||||
mem.first, mem.second);
|
||||
}
|
||||
}
|
||||
|
||||
void cancellation_slot::clear()
|
||||
{
|
||||
if (handler_ != 0 && *handler_ != 0)
|
||||
{
|
||||
std::pair<void*, std::size_t> mem = (*handler_)->destroy();
|
||||
detail::thread_info_base::deallocate(
|
||||
detail::thread_info_base::cancellation_signal_tag(),
|
||||
detail::thread_context::top_of_thread_call_stack(),
|
||||
mem.first, mem.second);
|
||||
*handler_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<void*, std::size_t> cancellation_slot::prepare_memory(
|
||||
std::size_t size, std::size_t align)
|
||||
{
|
||||
assert(handler_);
|
||||
std::pair<void*, std::size_t> mem;
|
||||
if (*handler_)
|
||||
{
|
||||
mem = (*handler_)->destroy();
|
||||
*handler_ = 0;
|
||||
}
|
||||
if (size > mem.second
|
||||
|| reinterpret_cast<std::size_t>(mem.first) % align != 0)
|
||||
{
|
||||
if (mem.first)
|
||||
{
|
||||
detail::thread_info_base::deallocate(
|
||||
detail::thread_info_base::cancellation_signal_tag(),
|
||||
detail::thread_context::top_of_thread_call_stack(),
|
||||
mem.first, mem.second);
|
||||
}
|
||||
mem.first = detail::thread_info_base::allocate(
|
||||
detail::thread_info_base::cancellation_signal_tag(),
|
||||
detail::thread_context::top_of_thread_call_stack(),
|
||||
size, align);
|
||||
mem.second = size;
|
||||
}
|
||||
return mem;
|
||||
}
|
||||
|
||||
cancellation_slot::auto_delete_helper::~auto_delete_helper()
|
||||
{
|
||||
if (mem.first)
|
||||
{
|
||||
detail::thread_info_base::deallocate(
|
||||
detail::thread_info_base::cancellation_signal_tag(),
|
||||
detail::thread_context::top_of_thread_call_stack(),
|
||||
mem.first, mem.second);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_IMPL_CANCELLATION_SIGNAL_IPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/co_spawn.hpp
|
||||
// ~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -16,9 +16,14 @@
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <boost/asio/associated_cancellation_slot.hpp>
|
||||
#include <boost/asio/awaitable.hpp>
|
||||
#include <boost/asio/detail/memory.hpp>
|
||||
#include <boost/asio/detail/recycling_allocator.hpp>
|
||||
#include <boost/asio/dispatch.hpp>
|
||||
#include <boost/asio/execution/outstanding_work.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <boost/asio/prefer.hpp>
|
||||
#include <boost/asio/use_awaitable.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
@@ -27,106 +32,404 @@ namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
template <typename T, typename Executor, typename F, typename Handler>
|
||||
awaitable<void, Executor> co_spawn_entry_point(
|
||||
awaitable<T, Executor>*, Executor ex, F f, Handler handler)
|
||||
template <typename Executor, typename = void>
|
||||
class co_spawn_work_guard
|
||||
{
|
||||
auto spawn_work = make_work_guard(ex);
|
||||
auto handler_work = make_work_guard(handler, ex);
|
||||
public:
|
||||
typedef typename decay<
|
||||
typename prefer_result<Executor,
|
||||
execution::outstanding_work_t::tracked_t
|
||||
>::type
|
||||
>::type executor_type;
|
||||
|
||||
(void) co_await (post)(spawn_work.get_executor(),
|
||||
use_awaitable_t<Executor>{});
|
||||
co_spawn_work_guard(const Executor& ex)
|
||||
: executor_(boost::asio::prefer(ex, execution::outstanding_work.tracked))
|
||||
{
|
||||
}
|
||||
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return executor_;
|
||||
}
|
||||
|
||||
private:
|
||||
executor_type executor_;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
||||
|
||||
template <typename Executor>
|
||||
struct co_spawn_work_guard<Executor,
|
||||
typename enable_if<
|
||||
!execution::is_executor<Executor>::value
|
||||
>::type> : executor_work_guard<Executor>
|
||||
{
|
||||
co_spawn_work_guard(const Executor& ex)
|
||||
: executor_work_guard<Executor>(ex)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
||||
|
||||
template <typename Handler, typename Executor,
|
||||
typename Function, typename = void>
|
||||
struct co_spawn_state
|
||||
{
|
||||
template <typename H, typename F>
|
||||
co_spawn_state(H&& h, const Executor& ex, F&& f)
|
||||
: handler(std::forward<H>(h)),
|
||||
spawn_work(ex),
|
||||
handler_work(boost::asio::get_associated_executor(handler, ex)),
|
||||
function(std::forward<F>(f))
|
||||
{
|
||||
}
|
||||
|
||||
Handler handler;
|
||||
co_spawn_work_guard<Executor> spawn_work;
|
||||
co_spawn_work_guard<typename associated_executor<
|
||||
Handler, Executor>::type> handler_work;
|
||||
Function function;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Executor, typename Function>
|
||||
struct co_spawn_state<Handler, Executor, Function,
|
||||
typename enable_if<
|
||||
is_same<
|
||||
typename associated_executor<Handler,
|
||||
Executor>::asio_associated_executor_is_unspecialised,
|
||||
void
|
||||
>::value
|
||||
>::type>
|
||||
{
|
||||
template <typename H, typename F>
|
||||
co_spawn_state(H&& h, const Executor& ex, F&& f)
|
||||
: handler(std::forward<H>(h)),
|
||||
handler_work(ex),
|
||||
function(std::forward<F>(f))
|
||||
{
|
||||
}
|
||||
|
||||
Handler handler;
|
||||
co_spawn_work_guard<Executor> handler_work;
|
||||
Function function;
|
||||
};
|
||||
|
||||
struct co_spawn_dispatch
|
||||
{
|
||||
template <typename CompletionToken>
|
||||
auto operator()(CompletionToken&& token) const
|
||||
-> decltype(boost::asio::dispatch(std::forward<CompletionToken>(token)))
|
||||
{
|
||||
return boost::asio::dispatch(std::forward<CompletionToken>(token));
|
||||
}
|
||||
};
|
||||
|
||||
struct co_spawn_post
|
||||
{
|
||||
template <typename CompletionToken>
|
||||
auto operator()(CompletionToken&& token) const
|
||||
-> decltype(boost::asio::post(std::forward<CompletionToken>(token)))
|
||||
{
|
||||
return boost::asio::post(std::forward<CompletionToken>(token));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Handler, typename Executor, typename Function>
|
||||
awaitable<awaitable_thread_entry_point, Executor> co_spawn_entry_point(
|
||||
awaitable<T, Executor>*, co_spawn_state<Handler, Executor, Function> s)
|
||||
{
|
||||
(void) co_await co_spawn_dispatch{};
|
||||
|
||||
(co_await awaitable_thread_has_context_switched{}) = false;
|
||||
std::exception_ptr e = nullptr;
|
||||
bool done = false;
|
||||
try
|
||||
{
|
||||
T t = co_await f();
|
||||
T t = co_await s.function();
|
||||
|
||||
done = true;
|
||||
|
||||
(dispatch)(handler_work.get_executor(),
|
||||
[handler = std::move(handler), t = std::move(t)]() mutable
|
||||
bool switched = (co_await awaitable_thread_has_context_switched{});
|
||||
if (!switched)
|
||||
(void) co_await co_spawn_post();
|
||||
|
||||
(dispatch)(s.handler_work.get_executor(),
|
||||
[handler = std::move(s.handler), t = std::move(t)]() mutable
|
||||
{
|
||||
handler(std::exception_ptr(), std::move(t));
|
||||
std::move(handler)(std::exception_ptr(), std::move(t));
|
||||
});
|
||||
|
||||
co_return;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (done)
|
||||
throw;
|
||||
|
||||
(dispatch)(handler_work.get_executor(),
|
||||
[handler = std::move(handler), e = std::current_exception()]() mutable
|
||||
{
|
||||
handler(e, T());
|
||||
});
|
||||
e = std::current_exception();
|
||||
}
|
||||
|
||||
bool switched = (co_await awaitable_thread_has_context_switched{});
|
||||
if (!switched)
|
||||
(void) co_await co_spawn_post();
|
||||
|
||||
(dispatch)(s.handler_work.get_executor(),
|
||||
[handler = std::move(s.handler), e]() mutable
|
||||
{
|
||||
std::move(handler)(e, T());
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Executor, typename F, typename Handler>
|
||||
awaitable<void, Executor> co_spawn_entry_point(
|
||||
awaitable<void, Executor>*, Executor ex, F f, Handler handler)
|
||||
template <typename Handler, typename Executor, typename Function>
|
||||
awaitable<awaitable_thread_entry_point, Executor> co_spawn_entry_point(
|
||||
awaitable<void, Executor>*, co_spawn_state<Handler, Executor, Function> s)
|
||||
{
|
||||
auto spawn_work = make_work_guard(ex);
|
||||
auto handler_work = make_work_guard(handler, ex);
|
||||
|
||||
(void) co_await (post)(spawn_work.get_executor(),
|
||||
use_awaitable_t<Executor>{});
|
||||
(void) co_await co_spawn_dispatch{};
|
||||
|
||||
(co_await awaitable_thread_has_context_switched{}) = false;
|
||||
std::exception_ptr e = nullptr;
|
||||
try
|
||||
{
|
||||
co_await f();
|
||||
co_await s.function();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
e = std::current_exception();
|
||||
}
|
||||
|
||||
(dispatch)(handler_work.get_executor(),
|
||||
[handler = std::move(handler), e]() mutable
|
||||
bool switched = (co_await awaitable_thread_has_context_switched{});
|
||||
if (!switched)
|
||||
(void) co_await co_spawn_post();
|
||||
|
||||
(dispatch)(s.handler_work.get_executor(),
|
||||
[handler = std::move(s.handler), e]() mutable
|
||||
{
|
||||
handler(e);
|
||||
std::move(handler)(e);
|
||||
});
|
||||
}
|
||||
|
||||
struct initiate_co_spawn
|
||||
template <typename T, typename Executor>
|
||||
class awaitable_as_function
|
||||
{
|
||||
template <typename Handler, typename Executor, typename F>
|
||||
void operator()(Handler&& handler, const Executor& ex, F&& f) const
|
||||
public:
|
||||
explicit awaitable_as_function(awaitable<T, Executor>&& a)
|
||||
: awaitable_(std::move(a))
|
||||
{
|
||||
}
|
||||
|
||||
awaitable<T, Executor> operator()()
|
||||
{
|
||||
return std::move(awaitable_);
|
||||
}
|
||||
|
||||
private:
|
||||
awaitable<T, Executor> awaitable_;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Executor, typename = void>
|
||||
class co_spawn_cancellation_handler
|
||||
{
|
||||
public:
|
||||
co_spawn_cancellation_handler(const Handler&, const Executor& ex)
|
||||
: signal_(detail::allocate_shared<cancellation_signal>(
|
||||
detail::recycling_allocator<cancellation_signal,
|
||||
detail::thread_info_base::cancellation_signal_tag>())),
|
||||
ex_(ex)
|
||||
{
|
||||
}
|
||||
|
||||
cancellation_slot slot()
|
||||
{
|
||||
return signal_->slot();
|
||||
}
|
||||
|
||||
void operator()(cancellation_type_t type)
|
||||
{
|
||||
shared_ptr<cancellation_signal> sig = signal_;
|
||||
boost::asio::dispatch(ex_, [sig, type]{ sig->emit(type); });
|
||||
}
|
||||
|
||||
private:
|
||||
shared_ptr<cancellation_signal> signal_;
|
||||
Executor ex_;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Executor>
|
||||
class co_spawn_cancellation_handler<Handler, Executor,
|
||||
typename enable_if<
|
||||
is_same<
|
||||
typename associated_executor<Handler,
|
||||
Executor>::asio_associated_executor_is_unspecialised,
|
||||
void
|
||||
>::value
|
||||
>::type>
|
||||
{
|
||||
public:
|
||||
co_spawn_cancellation_handler(const Handler&, const Executor&)
|
||||
{
|
||||
}
|
||||
|
||||
cancellation_slot slot()
|
||||
{
|
||||
return signal_.slot();
|
||||
}
|
||||
|
||||
void operator()(cancellation_type_t type)
|
||||
{
|
||||
signal_.emit(type);
|
||||
}
|
||||
|
||||
private:
|
||||
cancellation_signal signal_;
|
||||
};
|
||||
|
||||
template <typename Executor>
|
||||
class initiate_co_spawn
|
||||
{
|
||||
public:
|
||||
typedef Executor executor_type;
|
||||
|
||||
template <typename OtherExecutor>
|
||||
explicit initiate_co_spawn(const OtherExecutor& ex)
|
||||
: ex_(ex)
|
||||
{
|
||||
}
|
||||
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return ex_;
|
||||
}
|
||||
|
||||
template <typename Handler, typename F>
|
||||
void operator()(Handler&& handler, F&& f) const
|
||||
{
|
||||
typedef typename result_of<F()>::type awaitable_type;
|
||||
typedef typename awaitable_type::executor_type executor_type;
|
||||
typedef typename decay<Handler>::type handler_type;
|
||||
typedef typename decay<F>::type function_type;
|
||||
typedef co_spawn_cancellation_handler<
|
||||
handler_type, Executor> cancel_handler_type;
|
||||
|
||||
auto slot = boost::asio::get_associated_cancellation_slot(handler);
|
||||
cancel_handler_type* cancel_handler = slot.is_connected()
|
||||
? &slot.template emplace<cancel_handler_type>(handler, ex_)
|
||||
: nullptr;
|
||||
|
||||
cancellation_slot proxy_slot(
|
||||
cancel_handler
|
||||
? cancel_handler->slot()
|
||||
: cancellation_slot());
|
||||
|
||||
cancellation_state cancel_state(proxy_slot);
|
||||
|
||||
executor_type ex2(ex);
|
||||
auto a = (co_spawn_entry_point)(static_cast<awaitable_type*>(nullptr),
|
||||
ex2, std::forward<F>(f), std::forward<Handler>(handler));
|
||||
awaitable_handler<executor_type, void>(std::move(a), ex2).launch();
|
||||
co_spawn_state<handler_type, Executor, function_type>(
|
||||
std::forward<Handler>(handler), ex_, std::forward<F>(f)));
|
||||
awaitable_handler<executor_type, void>(std::move(a),
|
||||
ex_, proxy_slot, cancel_state).launch();
|
||||
}
|
||||
|
||||
private:
|
||||
Executor ex_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Executor, typename F, typename CompletionToken>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken,
|
||||
typename detail::awaitable_signature<typename result_of<F()>::type>::type)
|
||||
co_spawn(const Executor& ex, F&& f, CompletionToken&& token,
|
||||
typename enable_if<
|
||||
is_executor<Executor>::value
|
||||
>::type*)
|
||||
template <typename Executor, typename T, typename AwaitableExecutor,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(std::exception_ptr, T)) CompletionToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken, void(std::exception_ptr, T))
|
||||
co_spawn(const Executor& ex,
|
||||
awaitable<T, AwaitableExecutor> a, CompletionToken&& token,
|
||||
typename constraint<
|
||||
(is_executor<Executor>::value || execution::is_executor<Executor>::value)
|
||||
&& is_convertible<Executor, AwaitableExecutor>::value
|
||||
>::type)
|
||||
{
|
||||
return async_initiate<CompletionToken,
|
||||
typename detail::awaitable_signature<typename result_of<F()>::type>>(
|
||||
detail::initiate_co_spawn(), token, ex, std::forward<F>(f));
|
||||
return async_initiate<CompletionToken, void(std::exception_ptr, T)>(
|
||||
detail::initiate_co_spawn<AwaitableExecutor>(AwaitableExecutor(ex)),
|
||||
token, detail::awaitable_as_function<T, AwaitableExecutor>(std::move(a)));
|
||||
}
|
||||
|
||||
template <typename ExecutionContext, typename F, typename CompletionToken>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken,
|
||||
template <typename Executor, typename AwaitableExecutor,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(std::exception_ptr)) CompletionToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken, void(std::exception_ptr))
|
||||
co_spawn(const Executor& ex,
|
||||
awaitable<void, AwaitableExecutor> a, CompletionToken&& token,
|
||||
typename constraint<
|
||||
(is_executor<Executor>::value || execution::is_executor<Executor>::value)
|
||||
&& is_convertible<Executor, AwaitableExecutor>::value
|
||||
>::type)
|
||||
{
|
||||
return async_initiate<CompletionToken, void(std::exception_ptr)>(
|
||||
detail::initiate_co_spawn<AwaitableExecutor>(AwaitableExecutor(ex)),
|
||||
token, detail::awaitable_as_function<
|
||||
void, AwaitableExecutor>(std::move(a)));
|
||||
}
|
||||
|
||||
template <typename ExecutionContext, typename T, typename AwaitableExecutor,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(std::exception_ptr, T)) CompletionToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken, void(std::exception_ptr, T))
|
||||
co_spawn(ExecutionContext& ctx,
|
||||
awaitable<T, AwaitableExecutor> a, CompletionToken&& token,
|
||||
typename constraint<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
&& is_convertible<typename ExecutionContext::executor_type,
|
||||
AwaitableExecutor>::value
|
||||
>::type)
|
||||
{
|
||||
return (co_spawn)(ctx.get_executor(), std::move(a),
|
||||
std::forward<CompletionToken>(token));
|
||||
}
|
||||
|
||||
template <typename ExecutionContext, typename AwaitableExecutor,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(std::exception_ptr)) CompletionToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken, void(std::exception_ptr))
|
||||
co_spawn(ExecutionContext& ctx,
|
||||
awaitable<void, AwaitableExecutor> a, CompletionToken&& token,
|
||||
typename constraint<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
&& is_convertible<typename ExecutionContext::executor_type,
|
||||
AwaitableExecutor>::value
|
||||
>::type)
|
||||
{
|
||||
return (co_spawn)(ctx.get_executor(), std::move(a),
|
||||
std::forward<CompletionToken>(token));
|
||||
}
|
||||
|
||||
template <typename Executor, typename F,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<
|
||||
typename result_of<F()>::type>::type) CompletionToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,
|
||||
typename detail::awaitable_signature<typename result_of<F()>::type>::type)
|
||||
co_spawn(const Executor& ex, F&& f, CompletionToken&& token,
|
||||
typename constraint<
|
||||
is_executor<Executor>::value || execution::is_executor<Executor>::value
|
||||
>::type)
|
||||
{
|
||||
return async_initiate<CompletionToken,
|
||||
typename detail::awaitable_signature<typename result_of<F()>::type>::type>(
|
||||
detail::initiate_co_spawn<
|
||||
typename result_of<F()>::type::executor_type>(ex),
|
||||
token, std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <typename ExecutionContext, typename F,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<
|
||||
typename result_of<F()>::type>::type) CompletionToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,
|
||||
typename detail::awaitable_signature<typename result_of<F()>::type>::type)
|
||||
co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token,
|
||||
typename enable_if<
|
||||
typename constraint<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type*)
|
||||
>::type)
|
||||
{
|
||||
return (co_spawn)(ctx.get_executor(), std::forward<F>(f),
|
||||
std::forward<CompletionToken>(token));
|
||||
|
||||
@@ -1,421 +0,0 @@
|
||||
//
|
||||
// impl/compose.hpp
|
||||
// ~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_ASIO_IMPL_COMPOSE_HPP
|
||||
#define BOOST_ASIO_IMPL_COMPOSE_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.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>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
#include <boost/asio/detail/variadic_templates.hpp>
|
||||
#include <boost/asio/executor_work_guard.hpp>
|
||||
#include <boost/asio/is_executor.hpp>
|
||||
#include <boost/asio/system_executor.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename>
|
||||
struct composed_work;
|
||||
|
||||
template <>
|
||||
struct composed_work<void()>
|
||||
{
|
||||
composed_work() BOOST_ASIO_NOEXCEPT
|
||||
: head_(system_executor())
|
||||
{
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
head_.reset();
|
||||
}
|
||||
|
||||
typedef system_executor head_type;
|
||||
executor_work_guard<system_executor> head_;
|
||||
};
|
||||
|
||||
inline composed_work<void()> make_composed_work()
|
||||
{
|
||||
return composed_work<void()>();
|
||||
}
|
||||
|
||||
template <typename Head>
|
||||
struct composed_work<void(Head)>
|
||||
{
|
||||
explicit composed_work(const Head& ex) BOOST_ASIO_NOEXCEPT
|
||||
: head_(ex)
|
||||
{
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
head_.reset();
|
||||
}
|
||||
|
||||
typedef Head head_type;
|
||||
executor_work_guard<Head> head_;
|
||||
};
|
||||
|
||||
template <typename Head>
|
||||
inline composed_work<void(Head)> make_composed_work(const Head& head)
|
||||
{
|
||||
return composed_work<void(Head)>(head);
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
template <typename Head, typename... Tail>
|
||||
struct composed_work<void(Head, Tail...)>
|
||||
{
|
||||
explicit composed_work(const Head& head,
|
||||
const Tail&... tail) BOOST_ASIO_NOEXCEPT
|
||||
: head_(head),
|
||||
tail_(tail...)
|
||||
{
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
head_.reset();
|
||||
tail_.reset();
|
||||
}
|
||||
|
||||
typedef Head head_type;
|
||||
executor_work_guard<Head> head_;
|
||||
composed_work<void(Tail...)> tail_;
|
||||
};
|
||||
|
||||
template <typename Head, typename... Tail>
|
||||
inline composed_work<void(Head, Tail...)>
|
||||
make_composed_work(const Head& head, const Tail&... tail)
|
||||
{
|
||||
return composed_work<void(Head, Tail...)>(head, tail...);
|
||||
}
|
||||
|
||||
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
#define BOOST_ASIO_PRIVATE_COMPOSED_WORK_DEF(n) \
|
||||
template <typename Head, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
struct composed_work<void(Head, BOOST_ASIO_VARIADIC_TARGS(n))> \
|
||||
{ \
|
||||
explicit composed_work(const Head& head, \
|
||||
BOOST_ASIO_VARIADIC_CONSTREF_PARAMS(n)) BOOST_ASIO_NOEXCEPT \
|
||||
: head_(head), \
|
||||
tail_(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)) \
|
||||
{ \
|
||||
} \
|
||||
\
|
||||
void reset() \
|
||||
{ \
|
||||
head_.reset(); \
|
||||
tail_.reset(); \
|
||||
} \
|
||||
\
|
||||
typedef Head head_type; \
|
||||
executor_work_guard<Head> head_; \
|
||||
composed_work<void(BOOST_ASIO_VARIADIC_TARGS(n))> tail_; \
|
||||
}; \
|
||||
\
|
||||
template <typename Head, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
inline composed_work<void(Head, BOOST_ASIO_VARIADIC_TARGS(n))> \
|
||||
make_composed_work(const Head& head, BOOST_ASIO_VARIADIC_CONSTREF_PARAMS(n)) \
|
||||
{ \
|
||||
return composed_work< \
|
||||
void(Head, BOOST_ASIO_VARIADIC_TARGS(n))>( \
|
||||
head, BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)); \
|
||||
} \
|
||||
/**/
|
||||
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_COMPOSED_WORK_DEF)
|
||||
#undef BOOST_ASIO_PRIVATE_COMPOSED_WORK_DEF
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
template <typename Impl, typename Work, typename Handler, typename Signature>
|
||||
class composed_op;
|
||||
|
||||
template <typename Impl, typename Work, typename Handler,
|
||||
typename R, typename... Args>
|
||||
class composed_op<Impl, Work, Handler, R(Args...)>
|
||||
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
template <typename Impl, typename Work, typename Handler, typename Signature>
|
||||
class composed_op
|
||||
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
{
|
||||
public:
|
||||
composed_op(BOOST_ASIO_MOVE_ARG(Impl) impl,
|
||||
BOOST_ASIO_MOVE_ARG(Work) work,
|
||||
BOOST_ASIO_MOVE_ARG(Handler) handler)
|
||||
: impl_(BOOST_ASIO_MOVE_CAST(Impl)(impl)),
|
||||
work_(BOOST_ASIO_MOVE_CAST(Work)(work)),
|
||||
handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
|
||||
invocations_(0)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
composed_op(composed_op&& 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_)
|
||||
{
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
typedef typename associated_executor<Handler,
|
||||
typename Work::head_type>::type executor_type;
|
||||
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return (get_associated_executor)(handler_, work_.head_.get_executor());
|
||||
}
|
||||
|
||||
typedef typename associated_allocator<Handler,
|
||||
std::allocator<void> >::type allocator_type;
|
||||
|
||||
allocator_type get_allocator() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return (get_associated_allocator)(handler_, std::allocator<void>());
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
template<typename... T>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(T)... t)
|
||||
{
|
||||
if (invocations_ < ~unsigned(0))
|
||||
++invocations_;
|
||||
impl_(*this, BOOST_ASIO_MOVE_CAST(T)(t)...);
|
||||
}
|
||||
|
||||
void complete(Args... args)
|
||||
{
|
||||
this->work_.reset();
|
||||
this->handler_(BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
|
||||
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
void operator()()
|
||||
{
|
||||
if (invocations_ < ~unsigned(0))
|
||||
++invocations_;
|
||||
impl_(*this);
|
||||
}
|
||||
|
||||
void complete()
|
||||
{
|
||||
this->work_.reset();
|
||||
this->handler_();
|
||||
}
|
||||
|
||||
#define BOOST_ASIO_PRIVATE_COMPOSED_OP_DEF(n) \
|
||||
template<BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
void operator()(BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||
{ \
|
||||
if (invocations_ < ~unsigned(0)) \
|
||||
++invocations_; \
|
||||
impl_(*this, BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||
} \
|
||||
\
|
||||
template<BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
void complete(BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||
{ \
|
||||
this->work_.reset(); \
|
||||
this->handler_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||
} \
|
||||
/**/
|
||||
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_COMPOSED_OP_DEF)
|
||||
#undef BOOST_ASIO_PRIVATE_COMPOSED_OP_DEF
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
//private:
|
||||
Impl impl_;
|
||||
Work work_;
|
||||
Handler handler_;
|
||||
unsigned invocations_;
|
||||
};
|
||||
|
||||
template <typename Impl, typename Work, typename Handler, typename Signature>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
composed_op<Impl, Work, Handler, Signature>* this_handler)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Impl, typename Work, typename Handler, typename Signature>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
composed_op<Impl, Work, Handler, Signature>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Impl, typename Work, typename Handler, typename Signature>
|
||||
inline bool asio_handler_is_continuation(
|
||||
composed_op<Impl, Work, Handler, Signature>* this_handler)
|
||||
{
|
||||
return this_handler->invocations_ > 1 ? true
|
||||
: boost_asio_handler_cont_helpers::is_continuation(
|
||||
this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Impl,
|
||||
typename Work, typename Handler, typename Signature>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
composed_op<Impl, Work, Handler, Signature>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Impl,
|
||||
typename Work, typename Handler, typename Signature>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
composed_op<Impl, Work, Handler, Signature>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Signature>
|
||||
struct initiate_composed_op
|
||||
{
|
||||
template <typename Handler, typename Impl, typename Work>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(Handler) handler,
|
||||
BOOST_ASIO_MOVE_ARG(Impl) impl,
|
||||
BOOST_ASIO_MOVE_ARG(Work) work) const
|
||||
{
|
||||
composed_op<typename decay<Impl>::type, typename decay<Work>::type,
|
||||
typename decay<Handler>::type, Signature>(
|
||||
BOOST_ASIO_MOVE_CAST(Impl)(impl), BOOST_ASIO_MOVE_CAST(Work)(work),
|
||||
BOOST_ASIO_MOVE_CAST(Handler)(handler))();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename IoObject>
|
||||
inline typename IoObject::executor_type
|
||||
get_composed_io_executor(IoObject& io_object)
|
||||
{
|
||||
return io_object.get_executor();
|
||||
}
|
||||
|
||||
template <typename Executor>
|
||||
inline const Executor& get_composed_io_executor(const Executor& ex,
|
||||
typename enable_if<is_executor<Executor>::value>::type* = 0)
|
||||
{
|
||||
return ex;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
template <typename CompletionToken, typename Signature,
|
||||
typename Implementation, typename... IoObjectsOrExecutors>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)
|
||||
async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation,
|
||||
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
|
||||
BOOST_ASIO_MOVE_ARG(IoObjectsOrExecutors)... io_objects_or_executors)
|
||||
{
|
||||
return async_initiate<CompletionToken, Signature>(
|
||||
detail::initiate_composed_op<Signature>(), token,
|
||||
BOOST_ASIO_MOVE_CAST(Implementation)(implementation),
|
||||
detail::make_composed_work(
|
||||
detail::get_composed_io_executor(
|
||||
BOOST_ASIO_MOVE_CAST(IoObjectsOrExecutors)(
|
||||
io_objects_or_executors))...));
|
||||
}
|
||||
|
||||
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
template <typename CompletionToken, typename Signature, typename Implementation>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)
|
||||
async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation,
|
||||
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
|
||||
{
|
||||
return async_initiate<CompletionToken, Signature>(
|
||||
detail::initiate_composed_op<Signature>(), token,
|
||||
BOOST_ASIO_MOVE_CAST(Implementation)(implementation),
|
||||
detail::make_composed_work());
|
||||
}
|
||||
|
||||
# define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n) \
|
||||
BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_##n
|
||||
|
||||
# define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_1 \
|
||||
detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1))
|
||||
# define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_2 \
|
||||
detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
|
||||
detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2))
|
||||
# define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_3 \
|
||||
detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
|
||||
detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2)), \
|
||||
detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T3)(x3))
|
||||
# define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_4 \
|
||||
detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
|
||||
detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2)), \
|
||||
detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T3)(x3)), \
|
||||
detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T4)(x4))
|
||||
# define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_5 \
|
||||
detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
|
||||
detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2)), \
|
||||
detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T3)(x3)), \
|
||||
detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T4)(x4)), \
|
||||
detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T5)(x5))
|
||||
|
||||
#define BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF(n) \
|
||||
template <typename CompletionToken, typename Signature, \
|
||||
typename Implementation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature) \
|
||||
async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation, \
|
||||
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
|
||||
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||
{ \
|
||||
return async_initiate<CompletionToken, Signature>( \
|
||||
detail::initiate_composed_op<Signature>(), token, \
|
||||
BOOST_ASIO_MOVE_CAST(Implementation)(implementation), \
|
||||
detail::make_composed_work( \
|
||||
BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n))); \
|
||||
} \
|
||||
/**/
|
||||
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF)
|
||||
#undef BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF
|
||||
|
||||
#undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR
|
||||
#undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_1
|
||||
#undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_2
|
||||
#undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_3
|
||||
#undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_4
|
||||
#undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_5
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_IMPL_COMPOSE_HPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/connect.hpp
|
||||
// ~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -16,15 +16,17 @@
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/associator.hpp>
|
||||
#include <boost/asio/detail/base_from_cancellation_state.hpp>
|
||||
#include <boost/asio/detail/bind_handler.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>
|
||||
#include <boost/asio/detail/handler_tracking.hpp>
|
||||
#include <boost/asio/detail/handler_type_requirements.hpp>
|
||||
#include <boost/asio/detail/non_const_lvalue.hpp>
|
||||
#include <boost/asio/detail/throw_error.hpp>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
|
||||
@@ -73,9 +75,9 @@ namespace detail
|
||||
|
||||
static const bool value =
|
||||
sizeof(asio_connect_condition_check(
|
||||
(*static_cast<legacy_connect_condition_helper<T, Iterator>*>(0))(
|
||||
*static_cast<const boost::system::error_code*>(0),
|
||||
*static_cast<const Iterator*>(0)))) != 1;
|
||||
(declval<legacy_connect_condition_helper<T, Iterator> >())(
|
||||
declval<const boost::system::error_code>(),
|
||||
declval<const Iterator>()))) != 1;
|
||||
};
|
||||
|
||||
template <typename ConnectCondition, typename Iterator>
|
||||
@@ -105,8 +107,8 @@ namespace detail
|
||||
template <typename Protocol, typename Executor, typename EndpointSequence>
|
||||
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
|
||||
const EndpointSequence& endpoints,
|
||||
typename enable_if<is_endpoint_sequence<
|
||||
EndpointSequence>::value>::type*)
|
||||
typename constraint<is_endpoint_sequence<
|
||||
EndpointSequence>::value>::type)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
typename Protocol::endpoint result = connect(s, endpoints, ec);
|
||||
@@ -117,8 +119,8 @@ typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
|
||||
template <typename Protocol, typename Executor, typename EndpointSequence>
|
||||
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
|
||||
const EndpointSequence& endpoints, boost::system::error_code& ec,
|
||||
typename enable_if<is_endpoint_sequence<
|
||||
EndpointSequence>::value>::type*)
|
||||
typename constraint<is_endpoint_sequence<
|
||||
EndpointSequence>::value>::type)
|
||||
{
|
||||
return detail::deref_connect_result<Protocol>(
|
||||
connect(s, endpoints.begin(), endpoints.end(),
|
||||
@@ -128,7 +130,7 @@ typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
template <typename Protocol, typename Executor, typename Iterator>
|
||||
Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
|
||||
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
|
||||
typename constraint<!is_endpoint_sequence<Iterator>::value>::type)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
Iterator result = connect(s, begin, ec);
|
||||
@@ -139,7 +141,7 @@ Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
|
||||
template <typename Protocol, typename Executor, typename Iterator>
|
||||
inline Iterator connect(basic_socket<Protocol, Executor>& s,
|
||||
Iterator begin, boost::system::error_code& ec,
|
||||
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
|
||||
typename constraint<!is_endpoint_sequence<Iterator>::value>::type)
|
||||
{
|
||||
return connect(s, begin, Iterator(), detail::default_connect_condition(), ec);
|
||||
}
|
||||
@@ -166,8 +168,8 @@ template <typename Protocol, typename Executor,
|
||||
typename EndpointSequence, typename ConnectCondition>
|
||||
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
|
||||
const EndpointSequence& endpoints, ConnectCondition connect_condition,
|
||||
typename enable_if<is_endpoint_sequence<
|
||||
EndpointSequence>::value>::type*)
|
||||
typename constraint<is_endpoint_sequence<
|
||||
EndpointSequence>::value>::type)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
typename Protocol::endpoint result = connect(
|
||||
@@ -181,8 +183,8 @@ template <typename Protocol, typename Executor,
|
||||
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
|
||||
const EndpointSequence& endpoints, ConnectCondition connect_condition,
|
||||
boost::system::error_code& ec,
|
||||
typename enable_if<is_endpoint_sequence<
|
||||
EndpointSequence>::value>::type*)
|
||||
typename constraint<is_endpoint_sequence<
|
||||
EndpointSequence>::value>::type)
|
||||
{
|
||||
return detail::deref_connect_result<Protocol>(
|
||||
connect(s, endpoints.begin(), endpoints.end(),
|
||||
@@ -194,7 +196,7 @@ template <typename Protocol, typename Executor,
|
||||
typename Iterator, typename ConnectCondition>
|
||||
Iterator connect(basic_socket<Protocol, Executor>& s,
|
||||
Iterator begin, ConnectCondition connect_condition,
|
||||
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
|
||||
typename constraint<!is_endpoint_sequence<Iterator>::value>::type)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
Iterator result = connect(s, begin, connect_condition, ec);
|
||||
@@ -207,7 +209,7 @@ template <typename Protocol, typename Executor,
|
||||
inline Iterator connect(basic_socket<Protocol, Executor>& s,
|
||||
Iterator begin, ConnectCondition connect_condition,
|
||||
boost::system::error_code& ec,
|
||||
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
|
||||
typename constraint<!is_endpoint_sequence<Iterator>::value>::type)
|
||||
{
|
||||
return connect(s, begin, Iterator(), connect_condition, ec);
|
||||
}
|
||||
@@ -294,14 +296,18 @@ namespace detail
|
||||
|
||||
template <typename Protocol, typename Executor, typename EndpointSequence,
|
||||
typename ConnectCondition, typename RangeConnectHandler>
|
||||
class range_connect_op : base_from_connect_condition<ConnectCondition>
|
||||
class range_connect_op
|
||||
: public base_from_cancellation_state<RangeConnectHandler>,
|
||||
base_from_connect_condition<ConnectCondition>
|
||||
{
|
||||
public:
|
||||
range_connect_op(basic_socket<Protocol, Executor>& sock,
|
||||
const EndpointSequence& endpoints,
|
||||
const ConnectCondition& connect_condition,
|
||||
RangeConnectHandler& handler)
|
||||
: base_from_connect_condition<ConnectCondition>(connect_condition),
|
||||
: base_from_cancellation_state<RangeConnectHandler>(
|
||||
handler, enable_partial_cancellation()),
|
||||
base_from_connect_condition<ConnectCondition>(connect_condition),
|
||||
socket_(sock),
|
||||
endpoints_(endpoints),
|
||||
index_(0),
|
||||
@@ -312,7 +318,8 @@ namespace detail
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
range_connect_op(const range_connect_op& other)
|
||||
: base_from_connect_condition<ConnectCondition>(other),
|
||||
: base_from_cancellation_state<RangeConnectHandler>(other),
|
||||
base_from_connect_condition<ConnectCondition>(other),
|
||||
socket_(other.socket_),
|
||||
endpoints_(other.endpoints_),
|
||||
index_(other.index_),
|
||||
@@ -322,7 +329,10 @@ namespace detail
|
||||
}
|
||||
|
||||
range_connect_op(range_connect_op&& other)
|
||||
: base_from_connect_condition<ConnectCondition>(other),
|
||||
: base_from_cancellation_state<RangeConnectHandler>(
|
||||
BOOST_ASIO_MOVE_CAST(base_from_cancellation_state<
|
||||
RangeConnectHandler>)(other)),
|
||||
base_from_connect_condition<ConnectCondition>(other),
|
||||
socket_(other.socket_),
|
||||
endpoints_(other.endpoints_),
|
||||
index_(other.index_),
|
||||
@@ -358,6 +368,7 @@ namespace detail
|
||||
if (iter != end)
|
||||
{
|
||||
socket_.close(ec);
|
||||
BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect"));
|
||||
socket_.async_connect(*iter,
|
||||
BOOST_ASIO_MOVE_CAST(range_connect_op)(*this));
|
||||
return;
|
||||
@@ -366,13 +377,14 @@ namespace detail
|
||||
if (start)
|
||||
{
|
||||
ec = boost::asio::error::not_found;
|
||||
BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect"));
|
||||
boost::asio::post(socket_.get_executor(),
|
||||
detail::bind_handler(
|
||||
BOOST_ASIO_MOVE_CAST(range_connect_op)(*this), ec));
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
/* fall-through */ default:
|
||||
|
||||
if (iter == end)
|
||||
break;
|
||||
@@ -386,11 +398,18 @@ namespace detail
|
||||
if (!ec)
|
||||
break;
|
||||
|
||||
if (this->cancelled() != cancellation_type::none)
|
||||
{
|
||||
ec = boost::asio::error::operation_aborted;
|
||||
break;
|
||||
}
|
||||
|
||||
++iter;
|
||||
++index_;
|
||||
}
|
||||
|
||||
handler_(static_cast<const boost::system::error_code&>(ec),
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(RangeConnectHandler)(handler_)(
|
||||
static_cast<const boost::system::error_code&>(ec),
|
||||
static_cast<const typename Protocol::endpoint&>(
|
||||
ec || iter == end ? typename Protocol::endpoint() : *iter));
|
||||
}
|
||||
@@ -405,22 +424,32 @@ namespace detail
|
||||
|
||||
template <typename Protocol, typename Executor, typename EndpointSequence,
|
||||
typename ConnectCondition, typename RangeConnectHandler>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
inline asio_handler_allocate_is_deprecated
|
||||
asio_handler_allocate(std::size_t size,
|
||||
range_connect_op<Protocol, Executor, EndpointSequence,
|
||||
ConnectCondition, RangeConnectHandler>* this_handler)
|
||||
{
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
|
||||
return asio_handler_allocate_is_no_longer_used();
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Protocol, typename Executor, typename EndpointSequence,
|
||||
typename ConnectCondition, typename RangeConnectHandler>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
inline asio_handler_deallocate_is_deprecated
|
||||
asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
range_connect_op<Protocol, Executor, EndpointSequence,
|
||||
ConnectCondition, RangeConnectHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_deallocate_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Protocol, typename Executor, typename EndpointSequence,
|
||||
@@ -436,31 +465,53 @@ namespace detail
|
||||
template <typename Function, typename Executor, typename Protocol,
|
||||
typename EndpointSequence, typename ConnectCondition,
|
||||
typename RangeConnectHandler>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(Function& function,
|
||||
range_connect_op<Protocol, Executor, EndpointSequence,
|
||||
ConnectCondition, RangeConnectHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Function, typename Executor, typename Protocol,
|
||||
typename EndpointSequence, typename ConnectCondition,
|
||||
typename RangeConnectHandler>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(const Function& function,
|
||||
range_connect_op<Protocol, Executor, EndpointSequence,
|
||||
ConnectCondition, RangeConnectHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
struct initiate_async_range_connect
|
||||
template <typename Protocol, typename Executor>
|
||||
class initiate_async_range_connect
|
||||
{
|
||||
template <typename RangeConnectHandler, typename Protocol,
|
||||
typename Executor, typename EndpointSequence, typename ConnectCondition>
|
||||
public:
|
||||
typedef Executor executor_type;
|
||||
|
||||
explicit initiate_async_range_connect(basic_socket<Protocol, Executor>& s)
|
||||
: socket_(s)
|
||||
{
|
||||
}
|
||||
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return socket_.get_executor();
|
||||
}
|
||||
|
||||
template <typename RangeConnectHandler,
|
||||
typename EndpointSequence, typename ConnectCondition>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
|
||||
basic_socket<Protocol, Executor>* s, const EndpointSequence& endpoints,
|
||||
const EndpointSequence& endpoints,
|
||||
const ConnectCondition& connect_condition) const
|
||||
{
|
||||
// If you get an error on the following line it means that your
|
||||
@@ -471,21 +522,28 @@ namespace detail
|
||||
|
||||
non_const_lvalue<RangeConnectHandler> handler2(handler);
|
||||
range_connect_op<Protocol, Executor, EndpointSequence, ConnectCondition,
|
||||
typename decay<RangeConnectHandler>::type>(*s, endpoints,
|
||||
typename decay<RangeConnectHandler>::type>(socket_, endpoints,
|
||||
connect_condition, handler2.value)(boost::system::error_code(), 1);
|
||||
}
|
||||
|
||||
private:
|
||||
basic_socket<Protocol, Executor>& socket_;
|
||||
};
|
||||
|
||||
template <typename Protocol, typename Executor, typename Iterator,
|
||||
typename ConnectCondition, typename IteratorConnectHandler>
|
||||
class iterator_connect_op : base_from_connect_condition<ConnectCondition>
|
||||
class iterator_connect_op
|
||||
: public base_from_cancellation_state<IteratorConnectHandler>,
|
||||
base_from_connect_condition<ConnectCondition>
|
||||
{
|
||||
public:
|
||||
iterator_connect_op(basic_socket<Protocol, Executor>& sock,
|
||||
const Iterator& begin, const Iterator& end,
|
||||
const ConnectCondition& connect_condition,
|
||||
IteratorConnectHandler& handler)
|
||||
: base_from_connect_condition<ConnectCondition>(connect_condition),
|
||||
: base_from_cancellation_state<IteratorConnectHandler>(
|
||||
handler, enable_partial_cancellation()),
|
||||
base_from_connect_condition<ConnectCondition>(connect_condition),
|
||||
socket_(sock),
|
||||
iter_(begin),
|
||||
end_(end),
|
||||
@@ -496,7 +554,8 @@ namespace detail
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
iterator_connect_op(const iterator_connect_op& other)
|
||||
: base_from_connect_condition<ConnectCondition>(other),
|
||||
: base_from_cancellation_state<IteratorConnectHandler>(other),
|
||||
base_from_connect_condition<ConnectCondition>(other),
|
||||
socket_(other.socket_),
|
||||
iter_(other.iter_),
|
||||
end_(other.end_),
|
||||
@@ -506,7 +565,10 @@ namespace detail
|
||||
}
|
||||
|
||||
iterator_connect_op(iterator_connect_op&& other)
|
||||
: base_from_connect_condition<ConnectCondition>(other),
|
||||
: base_from_cancellation_state<IteratorConnectHandler>(
|
||||
BOOST_ASIO_MOVE_CAST(base_from_cancellation_state<
|
||||
IteratorConnectHandler>)(other)),
|
||||
base_from_connect_condition<ConnectCondition>(other),
|
||||
socket_(other.socket_),
|
||||
iter_(other.iter_),
|
||||
end_(other.end_),
|
||||
@@ -528,6 +590,7 @@ namespace detail
|
||||
if (iter_ != end_)
|
||||
{
|
||||
socket_.close(ec);
|
||||
BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect"));
|
||||
socket_.async_connect(*iter_,
|
||||
BOOST_ASIO_MOVE_CAST(iterator_connect_op)(*this));
|
||||
return;
|
||||
@@ -536,13 +599,14 @@ namespace detail
|
||||
if (start)
|
||||
{
|
||||
ec = boost::asio::error::not_found;
|
||||
BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect"));
|
||||
boost::asio::post(socket_.get_executor(),
|
||||
detail::bind_handler(
|
||||
BOOST_ASIO_MOVE_CAST(iterator_connect_op)(*this), ec));
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
/* fall-through */ default:
|
||||
|
||||
if (iter_ == end_)
|
||||
break;
|
||||
@@ -556,10 +620,17 @@ namespace detail
|
||||
if (!ec)
|
||||
break;
|
||||
|
||||
if (this->cancelled() != cancellation_type::none)
|
||||
{
|
||||
ec = boost::asio::error::operation_aborted;
|
||||
break;
|
||||
}
|
||||
|
||||
++iter_;
|
||||
}
|
||||
|
||||
handler_(static_cast<const boost::system::error_code&>(ec),
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(IteratorConnectHandler)(handler_)(
|
||||
static_cast<const boost::system::error_code&>(ec),
|
||||
static_cast<const Iterator&>(iter_));
|
||||
}
|
||||
}
|
||||
@@ -574,22 +645,32 @@ namespace detail
|
||||
|
||||
template <typename Protocol, typename Executor, typename Iterator,
|
||||
typename ConnectCondition, typename IteratorConnectHandler>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
inline asio_handler_allocate_is_deprecated
|
||||
asio_handler_allocate(std::size_t size,
|
||||
iterator_connect_op<Protocol, Executor, Iterator,
|
||||
ConnectCondition, IteratorConnectHandler>* this_handler)
|
||||
{
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
|
||||
return asio_handler_allocate_is_no_longer_used();
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Protocol, typename Executor, typename Iterator,
|
||||
typename ConnectCondition, typename IteratorConnectHandler>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
inline asio_handler_deallocate_is_deprecated
|
||||
asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
iterator_connect_op<Protocol, Executor, Iterator,
|
||||
ConnectCondition, IteratorConnectHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_deallocate_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Protocol, typename Executor, typename Iterator,
|
||||
@@ -605,32 +686,55 @@ namespace detail
|
||||
template <typename Function, typename Executor, typename Protocol,
|
||||
typename Iterator, typename ConnectCondition,
|
||||
typename IteratorConnectHandler>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(Function& function,
|
||||
iterator_connect_op<Protocol, Executor, Iterator,
|
||||
ConnectCondition, IteratorConnectHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Function, typename Executor, typename Protocol,
|
||||
typename Iterator, typename ConnectCondition,
|
||||
typename IteratorConnectHandler>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(const Function& function,
|
||||
iterator_connect_op<Protocol, Executor, Iterator,
|
||||
ConnectCondition, IteratorConnectHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
struct initiate_async_iterator_connect
|
||||
template <typename Protocol, typename Executor>
|
||||
class initiate_async_iterator_connect
|
||||
{
|
||||
template <typename IteratorConnectHandler, typename Protocol,
|
||||
typename Executor, typename Iterator, typename ConnectCondition>
|
||||
public:
|
||||
typedef Executor executor_type;
|
||||
|
||||
explicit initiate_async_iterator_connect(
|
||||
basic_socket<Protocol, Executor>& s)
|
||||
: socket_(s)
|
||||
{
|
||||
}
|
||||
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return socket_.get_executor();
|
||||
}
|
||||
|
||||
template <typename IteratorConnectHandler,
|
||||
typename Iterator, typename ConnectCondition>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
|
||||
basic_socket<Protocol, Executor>* s, Iterator begin,
|
||||
Iterator end, const ConnectCondition& connect_condition) const
|
||||
Iterator begin, Iterator end,
|
||||
const ConnectCondition& connect_condition) const
|
||||
{
|
||||
// If you get an error on the following line it means that your
|
||||
// handler does not meet the documented type requirements for an
|
||||
@@ -640,186 +744,213 @@ namespace detail
|
||||
|
||||
non_const_lvalue<IteratorConnectHandler> handler2(handler);
|
||||
iterator_connect_op<Protocol, Executor, Iterator, ConnectCondition,
|
||||
typename decay<IteratorConnectHandler>::type>(*s, begin, end,
|
||||
typename decay<IteratorConnectHandler>::type>(socket_, begin, end,
|
||||
connect_condition, handler2.value)(boost::system::error_code(), 1);
|
||||
}
|
||||
|
||||
private:
|
||||
basic_socket<Protocol, Executor>& socket_;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename Protocol, typename Executor, typename EndpointSequence,
|
||||
typename ConnectCondition, typename RangeConnectHandler, typename Allocator>
|
||||
struct associated_allocator<
|
||||
detail::range_connect_op<Protocol, Executor, EndpointSequence,
|
||||
ConnectCondition, RangeConnectHandler>, Allocator>
|
||||
template <template <typename, typename> class Associator,
|
||||
typename Protocol, typename Executor, typename EndpointSequence,
|
||||
typename ConnectCondition, typename RangeConnectHandler,
|
||||
typename DefaultCandidate>
|
||||
struct associator<Associator,
|
||||
detail::range_connect_op<Protocol, Executor,
|
||||
EndpointSequence, ConnectCondition, RangeConnectHandler>,
|
||||
DefaultCandidate>
|
||||
: Associator<RangeConnectHandler, DefaultCandidate>
|
||||
{
|
||||
typedef typename associated_allocator<
|
||||
RangeConnectHandler, Allocator>::type type;
|
||||
|
||||
static type get(
|
||||
const detail::range_connect_op<Protocol, Executor, EndpointSequence,
|
||||
ConnectCondition, RangeConnectHandler>& h,
|
||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
||||
static typename Associator<RangeConnectHandler, DefaultCandidate>::type
|
||||
get(const detail::range_connect_op<Protocol, Executor, EndpointSequence,
|
||||
ConnectCondition, RangeConnectHandler>& h) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_allocator<RangeConnectHandler,
|
||||
Allocator>::get(h.handler_, a);
|
||||
return Associator<RangeConnectHandler, DefaultCandidate>::get(h.handler_);
|
||||
}
|
||||
|
||||
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
|
||||
typename Associator<RangeConnectHandler, DefaultCandidate>::type)
|
||||
get(const detail::range_connect_op<Protocol, Executor,
|
||||
EndpointSequence, ConnectCondition, RangeConnectHandler>& h,
|
||||
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
|
||||
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
|
||||
Associator<RangeConnectHandler, DefaultCandidate>::get(
|
||||
h.handler_, c)))
|
||||
{
|
||||
return Associator<RangeConnectHandler, DefaultCandidate>::get(
|
||||
h.handler_, c);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Protocol, typename Executor, typename EndpointSequence,
|
||||
typename ConnectCondition, typename RangeConnectHandler, typename Executor1>
|
||||
struct associated_executor<
|
||||
detail::range_connect_op<Protocol, Executor, EndpointSequence,
|
||||
ConnectCondition, RangeConnectHandler>, Executor1>
|
||||
{
|
||||
typedef typename associated_executor<
|
||||
RangeConnectHandler, Executor1>::type type;
|
||||
|
||||
static type get(
|
||||
const detail::range_connect_op<Protocol, Executor, EndpointSequence,
|
||||
ConnectCondition, RangeConnectHandler>& h,
|
||||
const Executor1& ex = Executor1()) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_executor<RangeConnectHandler,
|
||||
Executor1>::get(h.handler_, ex);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Protocol, typename Executor, typename Iterator,
|
||||
template <template <typename, typename> class Associator,
|
||||
typename Protocol, typename Executor, typename Iterator,
|
||||
typename ConnectCondition, typename IteratorConnectHandler,
|
||||
typename Allocator>
|
||||
struct associated_allocator<
|
||||
typename DefaultCandidate>
|
||||
struct associator<Associator,
|
||||
detail::iterator_connect_op<Protocol, Executor,
|
||||
Iterator, ConnectCondition, IteratorConnectHandler>,
|
||||
Allocator>
|
||||
DefaultCandidate>
|
||||
: Associator<IteratorConnectHandler, DefaultCandidate>
|
||||
{
|
||||
typedef typename associated_allocator<
|
||||
IteratorConnectHandler, Allocator>::type type;
|
||||
|
||||
static type get(
|
||||
const detail::iterator_connect_op<Protocol, Executor,
|
||||
Iterator, ConnectCondition, IteratorConnectHandler>& h,
|
||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
||||
static typename Associator<IteratorConnectHandler, DefaultCandidate>::type
|
||||
get(const detail::iterator_connect_op<Protocol, Executor, Iterator,
|
||||
ConnectCondition, IteratorConnectHandler>& h) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_allocator<IteratorConnectHandler,
|
||||
Allocator>::get(h.handler_, a);
|
||||
return Associator<IteratorConnectHandler, DefaultCandidate>::get(
|
||||
h.handler_);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Protocol, typename Executor, typename Iterator,
|
||||
typename ConnectCondition, typename IteratorConnectHandler,
|
||||
typename Executor1>
|
||||
struct associated_executor<
|
||||
detail::iterator_connect_op<Protocol, Executor,
|
||||
Iterator, ConnectCondition, IteratorConnectHandler>,
|
||||
Executor1>
|
||||
{
|
||||
typedef typename associated_executor<
|
||||
IteratorConnectHandler, Executor1>::type type;
|
||||
|
||||
static type get(
|
||||
const detail::iterator_connect_op<Protocol, Executor,
|
||||
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
|
||||
typename Associator<IteratorConnectHandler, DefaultCandidate>::type)
|
||||
get(const detail::iterator_connect_op<Protocol, Executor,
|
||||
Iterator, ConnectCondition, IteratorConnectHandler>& h,
|
||||
const Executor1& ex = Executor1()) BOOST_ASIO_NOEXCEPT
|
||||
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
|
||||
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
|
||||
Associator<IteratorConnectHandler, DefaultCandidate>::get(
|
||||
h.handler_, c)))
|
||||
{
|
||||
return associated_executor<IteratorConnectHandler,
|
||||
Executor1>::get(h.handler_, ex);
|
||||
return Associator<IteratorConnectHandler, DefaultCandidate>::get(
|
||||
h.handler_, c);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename Protocol, typename Executor,
|
||||
typename EndpointSequence, typename RangeConnectHandler>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
|
||||
template <typename Protocol, typename Executor, typename EndpointSequence,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
typename Protocol::endpoint)) RangeConnectToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(RangeConnectToken,
|
||||
void (boost::system::error_code, typename Protocol::endpoint))
|
||||
async_connect(basic_socket<Protocol, Executor>& s,
|
||||
const EndpointSequence& endpoints,
|
||||
BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
|
||||
typename enable_if<is_endpoint_sequence<
|
||||
EndpointSequence>::value>::type*)
|
||||
BOOST_ASIO_MOVE_ARG(RangeConnectToken) token,
|
||||
typename constraint<is_endpoint_sequence<
|
||||
EndpointSequence>::value>::type)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<RangeConnectToken,
|
||||
void (boost::system::error_code, typename Protocol::endpoint)>(
|
||||
declval<detail::initiate_async_range_connect<Protocol, Executor> >(),
|
||||
token, endpoints, declval<detail::default_connect_condition>())))
|
||||
{
|
||||
return async_initiate<RangeConnectHandler,
|
||||
return async_initiate<RangeConnectToken,
|
||||
void (boost::system::error_code, typename Protocol::endpoint)>(
|
||||
detail::initiate_async_range_connect(), handler,
|
||||
&s, endpoints, detail::default_connect_condition());
|
||||
detail::initiate_async_range_connect<Protocol, Executor>(s),
|
||||
token, endpoints, detail::default_connect_condition());
|
||||
}
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
template <typename Protocol, typename Executor,
|
||||
typename Iterator, typename IteratorConnectHandler>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
|
||||
template <typename Protocol, typename Executor, typename Iterator,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
Iterator)) IteratorConnectToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,
|
||||
void (boost::system::error_code, Iterator))
|
||||
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
|
||||
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
|
||||
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
|
||||
BOOST_ASIO_MOVE_ARG(IteratorConnectToken) token,
|
||||
typename constraint<!is_endpoint_sequence<Iterator>::value>::type)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<IteratorConnectToken,
|
||||
void (boost::system::error_code, Iterator)>(
|
||||
declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),
|
||||
token, begin, Iterator(),
|
||||
declval<detail::default_connect_condition>())))
|
||||
{
|
||||
return async_initiate<IteratorConnectHandler,
|
||||
return async_initiate<IteratorConnectToken,
|
||||
void (boost::system::error_code, Iterator)>(
|
||||
detail::initiate_async_iterator_connect(), handler,
|
||||
&s, begin, Iterator(), detail::default_connect_condition());
|
||||
detail::initiate_async_iterator_connect<Protocol, Executor>(s),
|
||||
token, begin, Iterator(),
|
||||
detail::default_connect_condition());
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
template <typename Protocol, typename Executor,
|
||||
typename Iterator, typename IteratorConnectHandler>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
|
||||
template <typename Protocol, typename Executor, typename Iterator,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
Iterator)) IteratorConnectToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,
|
||||
void (boost::system::error_code, Iterator))
|
||||
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,
|
||||
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler)
|
||||
BOOST_ASIO_MOVE_ARG(IteratorConnectToken) token)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<IteratorConnectToken,
|
||||
void (boost::system::error_code, Iterator)>(
|
||||
declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),
|
||||
token, begin, end, declval<detail::default_connect_condition>())))
|
||||
{
|
||||
return async_initiate<IteratorConnectHandler,
|
||||
return async_initiate<IteratorConnectToken,
|
||||
void (boost::system::error_code, Iterator)>(
|
||||
detail::initiate_async_iterator_connect(), handler,
|
||||
&s, begin, end, detail::default_connect_condition());
|
||||
detail::initiate_async_iterator_connect<Protocol, Executor>(s),
|
||||
token, begin, end, detail::default_connect_condition());
|
||||
}
|
||||
|
||||
template <typename Protocol, typename Executor, typename EndpointSequence,
|
||||
typename ConnectCondition, typename RangeConnectHandler>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
|
||||
template <typename Protocol, typename Executor,
|
||||
typename EndpointSequence, typename ConnectCondition,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
typename Protocol::endpoint)) RangeConnectToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(RangeConnectToken,
|
||||
void (boost::system::error_code, typename Protocol::endpoint))
|
||||
async_connect(basic_socket<Protocol, Executor>& s,
|
||||
const EndpointSequence& endpoints, ConnectCondition connect_condition,
|
||||
BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
|
||||
typename enable_if<is_endpoint_sequence<
|
||||
EndpointSequence>::value>::type*)
|
||||
BOOST_ASIO_MOVE_ARG(RangeConnectToken) token,
|
||||
typename constraint<is_endpoint_sequence<
|
||||
EndpointSequence>::value>::type)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<RangeConnectToken,
|
||||
void (boost::system::error_code, typename Protocol::endpoint)>(
|
||||
declval<detail::initiate_async_range_connect<Protocol, Executor> >(),
|
||||
token, endpoints, connect_condition)))
|
||||
{
|
||||
return async_initiate<RangeConnectHandler,
|
||||
return async_initiate<RangeConnectToken,
|
||||
void (boost::system::error_code, typename Protocol::endpoint)>(
|
||||
detail::initiate_async_range_connect(),
|
||||
handler, &s, endpoints, connect_condition);
|
||||
detail::initiate_async_range_connect<Protocol, Executor>(s),
|
||||
token, endpoints, connect_condition);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
template <typename Protocol, typename Executor, typename Iterator,
|
||||
typename ConnectCondition, typename IteratorConnectHandler>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
|
||||
template <typename Protocol, typename Executor,
|
||||
typename Iterator, typename ConnectCondition,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
Iterator)) IteratorConnectToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,
|
||||
void (boost::system::error_code, Iterator))
|
||||
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
|
||||
ConnectCondition connect_condition,
|
||||
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
|
||||
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
|
||||
BOOST_ASIO_MOVE_ARG(IteratorConnectToken) token,
|
||||
typename constraint<!is_endpoint_sequence<Iterator>::value>::type)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<IteratorConnectToken,
|
||||
void (boost::system::error_code, Iterator)>(
|
||||
declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),
|
||||
token, begin, Iterator(), connect_condition)))
|
||||
{
|
||||
return async_initiate<IteratorConnectHandler,
|
||||
return async_initiate<IteratorConnectToken,
|
||||
void (boost::system::error_code, Iterator)>(
|
||||
detail::initiate_async_iterator_connect(),
|
||||
handler, &s, begin, Iterator(), connect_condition);
|
||||
detail::initiate_async_iterator_connect<Protocol, Executor>(s),
|
||||
token, begin, Iterator(), connect_condition);
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
template <typename Protocol, typename Executor, typename Iterator,
|
||||
typename ConnectCondition, typename IteratorConnectHandler>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
|
||||
template <typename Protocol, typename Executor,
|
||||
typename Iterator, typename ConnectCondition,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
Iterator)) IteratorConnectToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,
|
||||
void (boost::system::error_code, Iterator))
|
||||
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
|
||||
Iterator end, ConnectCondition connect_condition,
|
||||
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler)
|
||||
BOOST_ASIO_MOVE_ARG(IteratorConnectToken) token)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<IteratorConnectToken,
|
||||
void (boost::system::error_code, Iterator)>(
|
||||
declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),
|
||||
token, begin, end, connect_condition)))
|
||||
{
|
||||
return async_initiate<IteratorConnectHandler,
|
||||
return async_initiate<IteratorConnectToken,
|
||||
void (boost::system::error_code, Iterator)>(
|
||||
detail::initiate_async_iterator_connect(),
|
||||
handler, &s, begin, end, connect_condition);
|
||||
detail::initiate_async_iterator_connect<Protocol, Executor>(s),
|
||||
token, begin, end, connect_condition);
|
||||
}
|
||||
|
||||
} // namespace asio
|
||||
|
||||
75
linx64/include/boost/asio/impl/connect_pipe.hpp
Normal file
75
linx64/include/boost/asio/impl/connect_pipe.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// impl/connect_pipe.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2023 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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_ASIO_IMPL_CONNECT_PIPE_HPP
|
||||
#define BOOST_ASIO_IMPL_CONNECT_PIPE_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_PIPE)
|
||||
|
||||
#include <boost/asio/connect_pipe.hpp>
|
||||
#include <boost/asio/detail/throw_error.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
template <typename Executor1, typename Executor2>
|
||||
void connect_pipe(basic_readable_pipe<Executor1>& read_end,
|
||||
basic_writable_pipe<Executor2>& write_end)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
boost::asio::connect_pipe(read_end, write_end, ec);
|
||||
boost::asio::detail::throw_error(ec, "connect_pipe");
|
||||
}
|
||||
|
||||
template <typename Executor1, typename Executor2>
|
||||
BOOST_ASIO_SYNC_OP_VOID connect_pipe(basic_readable_pipe<Executor1>& read_end,
|
||||
basic_writable_pipe<Executor2>& write_end, boost::system::error_code& ec)
|
||||
{
|
||||
detail::native_pipe_handle p[2];
|
||||
detail::create_pipe(p, ec);
|
||||
if (ec)
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
|
||||
read_end.assign(p[0], ec);
|
||||
if (ec)
|
||||
{
|
||||
detail::close_pipe(p[0]);
|
||||
detail::close_pipe(p[1]);
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
write_end.assign(p[1], ec);
|
||||
if (ec)
|
||||
{
|
||||
boost::system::error_code temp_ec;
|
||||
read_end.close(temp_ec);
|
||||
detail::close_pipe(p[1]);
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_PIPE)
|
||||
|
||||
#endif // BOOST_ASIO_IMPL_CONNECT_PIPE_HPP
|
||||
151
linx64/include/boost/asio/impl/connect_pipe.ipp
Normal file
151
linx64/include/boost/asio/impl/connect_pipe.ipp
Normal file
@@ -0,0 +1,151 @@
|
||||
//
|
||||
// impl/connect_pipe.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2021 Klemens D. Morgenstern
|
||||
// (klemens dot morgenstern at gmx dot net)
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_ASIO_IMPL_CONNECT_PIPE_IPP
|
||||
#define BOOST_ASIO_IMPL_CONNECT_PIPE_IPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_PIPE)
|
||||
|
||||
#include <boost/asio/connect_pipe.hpp>
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_IOCP)
|
||||
# include <cstdio>
|
||||
# if _WIN32_WINNT >= 0x601
|
||||
# include <bcrypt.h>
|
||||
# if !defined(BOOST_ASIO_NO_DEFAULT_LINKED_LIBS)
|
||||
# if defined(_MSC_VER)
|
||||
# pragma comment(lib, "bcrypt.lib")
|
||||
# endif // defined(_MSC_VER)
|
||||
# endif // !defined(BOOST_ASIO_NO_DEFAULT_LINKED_LIBS)
|
||||
# endif // _WIN32_WINNT >= 0x601
|
||||
#else // defined(BOOST_ASIO_HAS_IOCP)
|
||||
# include <boost/asio/detail/descriptor_ops.hpp>
|
||||
#endif // defined(BOOST_ASIO_HAS_IOCP)
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
void create_pipe(native_pipe_handle p[2], boost::system::error_code& ec)
|
||||
{
|
||||
#if defined(BOOST_ASIO_HAS_IOCP)
|
||||
using namespace std; // For sprintf and memcmp.
|
||||
|
||||
static long counter1 = 0;
|
||||
static long counter2 = 0;
|
||||
|
||||
long n1 = ::InterlockedIncrement(&counter1);
|
||||
long n2 = (static_cast<unsigned long>(n1) % 0x10000000) == 0
|
||||
? ::InterlockedIncrement(&counter2)
|
||||
: ::InterlockedExchangeAdd(&counter2, 0);
|
||||
|
||||
wchar_t pipe_name[128];
|
||||
#if defined(BOOST_ASIO_HAS_SECURE_RTL)
|
||||
swprintf_s(
|
||||
#else // defined(BOOST_ASIO_HAS_SECURE_RTL)
|
||||
_snwprintf(
|
||||
#endif // defined(BOOST_ASIO_HAS_SECURE_RTL)
|
||||
pipe_name, 128,
|
||||
L"\\\\.\\pipe\\asio-A0812896-741A-484D-AF23-BE51BF620E22-%u-%ld-%ld",
|
||||
static_cast<unsigned int>(::GetCurrentProcessId()), n1, n2);
|
||||
|
||||
p[0] = ::CreateNamedPipeW(pipe_name,
|
||||
PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
|
||||
0, 1, 8192, 8192, 0, 0);
|
||||
|
||||
if (p[0] == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
ec.assign(last_error, boost::asio::error::get_system_category());
|
||||
return;
|
||||
}
|
||||
|
||||
p[1] = ::CreateFileW(pipe_name, GENERIC_WRITE, 0,
|
||||
0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
|
||||
|
||||
if (p[1] == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
::CloseHandle(p[0]);
|
||||
ec.assign(last_error, boost::asio::error::get_system_category());
|
||||
return;
|
||||
}
|
||||
|
||||
# if _WIN32_WINNT >= 0x601
|
||||
unsigned char nonce[16];
|
||||
if (::BCryptGenRandom(0, nonce, sizeof(nonce),
|
||||
BCRYPT_USE_SYSTEM_PREFERRED_RNG) != 0)
|
||||
{
|
||||
ec = boost::asio::error::connection_aborted;
|
||||
::CloseHandle(p[0]);
|
||||
::CloseHandle(p[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD bytes_written = 0;
|
||||
BOOL ok = ::WriteFile(p[1], nonce, sizeof(nonce), &bytes_written, 0);
|
||||
if (!ok || bytes_written != sizeof(nonce))
|
||||
{
|
||||
ec = boost::asio::error::connection_aborted;
|
||||
::CloseHandle(p[0]);
|
||||
::CloseHandle(p[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char nonce_check[sizeof(nonce)];
|
||||
DWORD bytes_read = 0;
|
||||
ok = ::ReadFile(p[0], nonce_check, sizeof(nonce), &bytes_read, 0);
|
||||
if (!ok || bytes_read != sizeof(nonce)
|
||||
|| memcmp(nonce, nonce_check, sizeof(nonce)) != 0)
|
||||
{
|
||||
ec = boost::asio::error::connection_aborted;
|
||||
::CloseHandle(p[0]);
|
||||
::CloseHandle(p[1]);
|
||||
return;
|
||||
}
|
||||
#endif // _WIN32_WINNT >= 0x601
|
||||
|
||||
boost::asio::error::clear(ec);
|
||||
#else // defined(BOOST_ASIO_HAS_IOCP)
|
||||
int result = ::pipe(p);
|
||||
detail::descriptor_ops::get_last_error(ec, result != 0);
|
||||
#endif // defined(BOOST_ASIO_HAS_IOCP)
|
||||
}
|
||||
|
||||
void close_pipe(native_pipe_handle p)
|
||||
{
|
||||
#if defined(BOOST_ASIO_HAS_IOCP)
|
||||
::CloseHandle(p);
|
||||
#else // defined(BOOST_ASIO_HAS_IOCP)
|
||||
boost::system::error_code ignored_ec;
|
||||
detail::descriptor_ops::state_type state = 0;
|
||||
detail::descriptor_ops::close(p, state, ignored_ec);
|
||||
#endif // defined(BOOST_ASIO_HAS_IOCP)
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_PIPE)
|
||||
|
||||
#endif // BOOST_ASIO_IMPL_CONNECT_PIPE_IPP
|
||||
204
linx64/include/boost/asio/impl/consign.hpp
Normal file
204
linx64/include/boost/asio/impl/consign.hpp
Normal file
@@ -0,0 +1,204 @@
|
||||
//
|
||||
// impl/consign.hpp
|
||||
// ~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2023 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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_ASIO_IMPL_CONSIGN_HPP
|
||||
#define BOOST_ASIO_IMPL_CONSIGN_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#include <boost/asio/associator.hpp>
|
||||
#include <boost/asio/async_result.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>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
#include <boost/asio/detail/utility.hpp>
|
||||
#include <boost/asio/detail/variadic_templates.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
// Class to adapt a consign_t as a completion handler.
|
||||
template <typename Handler, typename... Values>
|
||||
class consign_handler
|
||||
{
|
||||
public:
|
||||
typedef void result_type;
|
||||
|
||||
template <typename H>
|
||||
consign_handler(BOOST_ASIO_MOVE_ARG(H) handler, std::tuple<Values...> values)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(H)(handler)),
|
||||
values_(BOOST_ASIO_MOVE_CAST(std::tuple<Values...>)(values))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)(
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
|
||||
//private:
|
||||
Handler handler_;
|
||||
std::tuple<Values...> values_;
|
||||
};
|
||||
|
||||
template <typename Handler>
|
||||
inline asio_handler_allocate_is_deprecated
|
||||
asio_handler_allocate(std::size_t size,
|
||||
consign_handler<Handler>* this_handler)
|
||||
{
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
|
||||
return asio_handler_allocate_is_no_longer_used();
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
inline asio_handler_deallocate_is_deprecated
|
||||
asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
consign_handler<Handler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_deallocate_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
inline bool asio_handler_is_continuation(
|
||||
consign_handler<Handler>* this_handler)
|
||||
{
|
||||
return boost_asio_handler_cont_helpers::is_continuation(
|
||||
this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler>
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(Function& function,
|
||||
consign_handler<Handler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler>
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(const Function& function,
|
||||
consign_handler<Handler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename CompletionToken, typename... Values, typename... Signatures>
|
||||
struct async_result<
|
||||
consign_t<CompletionToken, Values...>, Signatures...>
|
||||
: async_result<CompletionToken, Signatures...>
|
||||
{
|
||||
template <typename Initiation>
|
||||
struct init_wrapper
|
||||
{
|
||||
init_wrapper(Initiation init)
|
||||
: initiation_(BOOST_ASIO_MOVE_CAST(Initiation)(init))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Handler, typename... Args>
|
||||
void operator()(
|
||||
BOOST_ASIO_MOVE_ARG(Handler) handler,
|
||||
std::tuple<Values...> values,
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)(
|
||||
detail::consign_handler<
|
||||
typename decay<Handler>::type, Values...>(
|
||||
BOOST_ASIO_MOVE_CAST(Handler)(handler),
|
||||
BOOST_ASIO_MOVE_CAST(std::tuple<Values...>)(values)),
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
|
||||
Initiation initiation_;
|
||||
};
|
||||
|
||||
template <typename Initiation, typename RawCompletionToken, typename... Args>
|
||||
static BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signatures...,
|
||||
(async_initiate<CompletionToken, Signatures...>(
|
||||
declval<init_wrapper<typename decay<Initiation>::type> >(),
|
||||
declval<CompletionToken&>(),
|
||||
declval<std::tuple<Values...> >(),
|
||||
declval<BOOST_ASIO_MOVE_ARG(Args)>()...)))
|
||||
initiate(
|
||||
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
return async_initiate<CompletionToken, Signatures...>(
|
||||
init_wrapper<typename decay<Initiation>::type>(
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
|
||||
token.token_,
|
||||
BOOST_ASIO_MOVE_CAST(std::tuple<Values...>)(token.values_),
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <template <typename, typename> class Associator,
|
||||
typename Handler, typename... Values, typename DefaultCandidate>
|
||||
struct associator<Associator,
|
||||
detail::consign_handler<Handler, Values...>, DefaultCandidate>
|
||||
: Associator<Handler, DefaultCandidate>
|
||||
{
|
||||
static typename Associator<Handler, DefaultCandidate>::type
|
||||
get(const detail::consign_handler<Handler, Values...>& h) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return Associator<Handler, DefaultCandidate>::get(h.handler_);
|
||||
}
|
||||
|
||||
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
|
||||
typename Associator<Handler, DefaultCandidate>::type)
|
||||
get(const detail::consign_handler<Handler, Values...>& h,
|
||||
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
|
||||
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
|
||||
Associator<Handler, DefaultCandidate>::get(h.handler_, c)))
|
||||
{
|
||||
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_IMPL_CONSIGN_HPP
|
||||
@@ -1,93 +0,0 @@
|
||||
//
|
||||
// impl/defer.hpp
|
||||
// ~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_ASIO_IMPL_DEFER_HPP
|
||||
#define BOOST_ASIO_IMPL_DEFER_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/detail/work_dispatcher.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
struct initiate_defer
|
||||
{
|
||||
template <typename CompletionHandler>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) const
|
||||
{
|
||||
typedef typename decay<CompletionHandler>::type DecayedHandler;
|
||||
|
||||
typename associated_executor<DecayedHandler>::type ex(
|
||||
(get_associated_executor)(handler));
|
||||
|
||||
typename associated_allocator<DecayedHandler>::type alloc(
|
||||
(get_associated_allocator)(handler));
|
||||
|
||||
ex.defer(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
|
||||
}
|
||||
|
||||
template <typename CompletionHandler, typename Executor>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
|
||||
BOOST_ASIO_MOVE_ARG(Executor) ex) const
|
||||
{
|
||||
typedef typename decay<CompletionHandler>::type DecayedHandler;
|
||||
|
||||
typename associated_allocator<DecayedHandler>::type alloc(
|
||||
(get_associated_allocator)(handler));
|
||||
|
||||
ex.defer(detail::work_dispatcher<DecayedHandler>(
|
||||
BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
|
||||
BOOST_ASIO_MOVE_ARG(CompletionToken) token)
|
||||
{
|
||||
return async_initiate<CompletionToken, void()>(
|
||||
detail::initiate_defer(), token);
|
||||
}
|
||||
|
||||
template <typename Executor, typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
|
||||
const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
|
||||
typename enable_if<is_executor<Executor>::value>::type*)
|
||||
{
|
||||
return async_initiate<CompletionToken, void()>(
|
||||
detail::initiate_defer(), token, ex);
|
||||
}
|
||||
|
||||
template <typename ExecutionContext, typename CompletionToken>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
|
||||
ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
|
||||
typename enable_if<is_convertible<
|
||||
ExecutionContext&, execution_context&>::value>::type*)
|
||||
{
|
||||
return (defer)(ctx.get_executor(),
|
||||
BOOST_ASIO_MOVE_CAST(CompletionToken)(token));
|
||||
}
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_IMPL_DEFER_HPP
|
||||
158
linx64/include/boost/asio/impl/deferred.hpp
Normal file
158
linx64/include/boost/asio/impl/deferred.hpp
Normal file
@@ -0,0 +1,158 @@
|
||||
//
|
||||
// impl/deferred.hpp
|
||||
// ~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2023 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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_ASIO_IMPL_DEFERRED_HPP
|
||||
#define BOOST_ASIO_IMPL_DEFERRED_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename Signature>
|
||||
class async_result<deferred_t, Signature>
|
||||
{
|
||||
public:
|
||||
template <typename Initiation, typename... InitArgs>
|
||||
static deferred_async_operation<Signature, Initiation, InitArgs...>
|
||||
initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
deferred_t, BOOST_ASIO_MOVE_ARG(InitArgs)... args)
|
||||
{
|
||||
return deferred_async_operation<
|
||||
Signature, Initiation, InitArgs...>(
|
||||
deferred_init_tag{},
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation),
|
||||
BOOST_ASIO_MOVE_CAST(InitArgs)(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Signatures>
|
||||
class async_result<deferred_t, Signatures...>
|
||||
{
|
||||
public:
|
||||
template <typename Initiation, typename... InitArgs>
|
||||
static deferred_async_operation<
|
||||
deferred_signatures<Signatures...>, Initiation, InitArgs...>
|
||||
initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
deferred_t, BOOST_ASIO_MOVE_ARG(InitArgs)... args)
|
||||
{
|
||||
return deferred_async_operation<
|
||||
deferred_signatures<Signatures...>, Initiation, InitArgs...>(
|
||||
deferred_init_tag{},
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation),
|
||||
BOOST_ASIO_MOVE_CAST(InitArgs)(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Function, typename Signature>
|
||||
class async_result<deferred_function<Function>, Signature>
|
||||
{
|
||||
public:
|
||||
template <typename Initiation, typename... InitArgs>
|
||||
static auto initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
deferred_function<Function> token,
|
||||
BOOST_ASIO_MOVE_ARG(InitArgs)... init_args)
|
||||
-> decltype(
|
||||
deferred_sequence<
|
||||
deferred_async_operation<
|
||||
Signature, Initiation, InitArgs...>,
|
||||
Function>(deferred_init_tag{},
|
||||
deferred_async_operation<
|
||||
Signature, Initiation, InitArgs...>(
|
||||
deferred_init_tag{},
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation),
|
||||
BOOST_ASIO_MOVE_CAST(InitArgs)(init_args)...),
|
||||
BOOST_ASIO_MOVE_CAST(Function)(token.function_)))
|
||||
{
|
||||
return deferred_sequence<
|
||||
deferred_async_operation<
|
||||
Signature, Initiation, InitArgs...>,
|
||||
Function>(deferred_init_tag{},
|
||||
deferred_async_operation<
|
||||
Signature, Initiation, InitArgs...>(
|
||||
deferred_init_tag{},
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation),
|
||||
BOOST_ASIO_MOVE_CAST(InitArgs)(init_args)...),
|
||||
BOOST_ASIO_MOVE_CAST(Function)(token.function_));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Function, typename... Signatures>
|
||||
class async_result<deferred_function<Function>, Signatures...>
|
||||
{
|
||||
public:
|
||||
template <typename Initiation, typename... InitArgs>
|
||||
static auto initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
deferred_function<Function> token,
|
||||
BOOST_ASIO_MOVE_ARG(InitArgs)... init_args)
|
||||
-> decltype(
|
||||
deferred_sequence<
|
||||
deferred_async_operation<
|
||||
deferred_signatures<Signatures...>, Initiation, InitArgs...>,
|
||||
Function>(deferred_init_tag{},
|
||||
deferred_async_operation<
|
||||
deferred_signatures<Signatures...>, Initiation, InitArgs...>(
|
||||
deferred_init_tag{},
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation),
|
||||
BOOST_ASIO_MOVE_CAST(InitArgs)(init_args)...),
|
||||
BOOST_ASIO_MOVE_CAST(Function)(token.function_)))
|
||||
{
|
||||
return deferred_sequence<
|
||||
deferred_async_operation<
|
||||
deferred_signatures<Signatures...>, Initiation, InitArgs...>,
|
||||
Function>(deferred_init_tag{},
|
||||
deferred_async_operation<
|
||||
deferred_signatures<Signatures...>, Initiation, InitArgs...>(
|
||||
deferred_init_tag{},
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation),
|
||||
BOOST_ASIO_MOVE_CAST(InitArgs)(init_args)...),
|
||||
BOOST_ASIO_MOVE_CAST(Function)(token.function_));
|
||||
}
|
||||
};
|
||||
|
||||
template <template <typename, typename> class Associator,
|
||||
typename Handler, typename Tail, typename DefaultCandidate>
|
||||
struct associator<Associator,
|
||||
detail::deferred_sequence_handler<Handler, Tail>,
|
||||
DefaultCandidate>
|
||||
: Associator<Handler, DefaultCandidate>
|
||||
{
|
||||
static typename Associator<Handler, DefaultCandidate>::type
|
||||
get(const detail::deferred_sequence_handler<Handler, Tail>& h)
|
||||
BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return Associator<Handler, DefaultCandidate>::get(h.handler_);
|
||||
}
|
||||
|
||||
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
|
||||
typename Associator<Handler, DefaultCandidate>::type)
|
||||
get(const detail::deferred_sequence_handler<Handler, Tail>& h,
|
||||
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
|
||||
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
|
||||
Associator<Handler, DefaultCandidate>::get(h.handler_, c)))
|
||||
{
|
||||
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_IMPL_DEFERRED_HPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/detached.hpp
|
||||
// ~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
//
|
||||
// impl/dispatch.hpp
|
||||
// ~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_ASIO_IMPL_DISPATCH_HPP
|
||||
#define BOOST_ASIO_IMPL_DISPATCH_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/detail/work_dispatcher.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
struct initiate_dispatch
|
||||
{
|
||||
template <typename CompletionHandler>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) const
|
||||
{
|
||||
typedef typename decay<CompletionHandler>::type DecayedHandler;
|
||||
|
||||
typename associated_executor<DecayedHandler>::type ex(
|
||||
(get_associated_executor)(handler));
|
||||
|
||||
typename associated_allocator<DecayedHandler>::type alloc(
|
||||
(get_associated_allocator)(handler));
|
||||
|
||||
ex.dispatch(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
|
||||
}
|
||||
|
||||
template <typename CompletionHandler, typename Executor>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
|
||||
BOOST_ASIO_MOVE_ARG(Executor) ex) const
|
||||
{
|
||||
typedef typename decay<CompletionHandler>::type DecayedHandler;
|
||||
|
||||
typename associated_allocator<DecayedHandler>::type alloc(
|
||||
(get_associated_allocator)(handler));
|
||||
|
||||
ex.dispatch(detail::work_dispatcher<DecayedHandler>(
|
||||
BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch(
|
||||
BOOST_ASIO_MOVE_ARG(CompletionToken) token)
|
||||
{
|
||||
return async_initiate<CompletionToken, void()>(
|
||||
detail::initiate_dispatch(), token);
|
||||
}
|
||||
|
||||
template <typename Executor, typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch(
|
||||
const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
|
||||
typename enable_if<is_executor<Executor>::value>::type*)
|
||||
{
|
||||
return async_initiate<CompletionToken, void()>(
|
||||
detail::initiate_dispatch(), token, ex);
|
||||
}
|
||||
|
||||
template <typename ExecutionContext, typename CompletionToken>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch(
|
||||
ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
|
||||
typename enable_if<is_convertible<
|
||||
ExecutionContext&, execution_context&>::value>::type*)
|
||||
{
|
||||
return (dispatch)(ctx.get_executor(),
|
||||
BOOST_ASIO_MOVE_CAST(CompletionToken)(token));
|
||||
}
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_IMPL_DISPATCH_HPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/error.ipp
|
||||
// ~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/execution_context.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/execution_context.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/executor.hpp
|
||||
// ~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -16,11 +16,12 @@
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
||||
|
||||
#include <boost/asio/detail/atomic_count.hpp>
|
||||
#include <boost/asio/detail/executor_function.hpp>
|
||||
#include <boost/asio/detail/global.hpp>
|
||||
#include <boost/asio/detail/memory.hpp>
|
||||
#include <boost/asio/detail/recycling_allocator.hpp>
|
||||
#include <boost/asio/executor.hpp>
|
||||
#include <boost/asio/system_executor.hpp>
|
||||
|
||||
@@ -31,99 +32,7 @@ namespace asio {
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
// Lightweight, move-only function object wrapper.
|
||||
class executor::function
|
||||
{
|
||||
public:
|
||||
template <typename F, typename Alloc>
|
||||
explicit function(F f, const Alloc& a)
|
||||
{
|
||||
// Allocate and construct an operation to wrap the function.
|
||||
typedef detail::executor_function<F, Alloc> func_type;
|
||||
typename func_type::ptr p = {
|
||||
detail::addressof(a), func_type::ptr::allocate(a), 0 };
|
||||
func_ = new (p.v) func_type(BOOST_ASIO_MOVE_CAST(F)(f), a);
|
||||
p.v = 0;
|
||||
}
|
||||
|
||||
function(function&& other) BOOST_ASIO_NOEXCEPT
|
||||
: func_(other.func_)
|
||||
{
|
||||
other.func_ = 0;
|
||||
}
|
||||
|
||||
~function()
|
||||
{
|
||||
if (func_)
|
||||
func_->destroy();
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
if (func_)
|
||||
{
|
||||
detail::executor_function_base* func = func_;
|
||||
func_ = 0;
|
||||
func->complete();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
detail::executor_function_base* func_;
|
||||
};
|
||||
|
||||
#else // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
// Not so lightweight, copyable function object wrapper.
|
||||
class executor::function
|
||||
{
|
||||
public:
|
||||
template <typename F, typename Alloc>
|
||||
explicit function(const F& f, const Alloc&)
|
||||
: impl_(new impl<F>(f))
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
impl_->invoke_(impl_.get());
|
||||
}
|
||||
|
||||
private:
|
||||
// Base class for polymorphic function implementations.
|
||||
struct impl_base
|
||||
{
|
||||
void (*invoke_)(impl_base*);
|
||||
};
|
||||
|
||||
// Polymorphic function implementation.
|
||||
template <typename F>
|
||||
struct impl : impl_base
|
||||
{
|
||||
impl(const F& f)
|
||||
: function_(f)
|
||||
{
|
||||
invoke_ = &function::invoke<F>;
|
||||
}
|
||||
|
||||
F function_;
|
||||
};
|
||||
|
||||
// Helper to invoke a function.
|
||||
template <typename F>
|
||||
static void invoke(impl_base* i)
|
||||
{
|
||||
static_cast<impl<F>*>(i)->function_();
|
||||
}
|
||||
|
||||
detail::shared_ptr<impl_base> impl_;
|
||||
};
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
// Default polymorphic allocator implementation.
|
||||
// Default polymorphic executor implementation.
|
||||
template <typename Executor, typename Allocator>
|
||||
class executor::impl
|
||||
: public executor::impl_base
|
||||
@@ -149,13 +58,13 @@ public:
|
||||
|
||||
impl_base* clone() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
++ref_count_;
|
||||
detail::ref_count_up(ref_count_);
|
||||
return const_cast<impl_base*>(static_cast<const impl_base*>(this));
|
||||
}
|
||||
|
||||
void destroy() BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
if (--ref_count_ == 0)
|
||||
if (detail::ref_count_down(ref_count_))
|
||||
{
|
||||
allocator_type alloc(allocator_);
|
||||
impl* p = this;
|
||||
@@ -247,7 +156,7 @@ private:
|
||||
};
|
||||
};
|
||||
|
||||
// Polymorphic allocator specialisation for system_executor.
|
||||
// Polymorphic executor specialisation for system_executor.
|
||||
template <typename Allocator>
|
||||
class executor::impl<system_executor, Allocator>
|
||||
: public executor::impl_base
|
||||
@@ -290,17 +199,20 @@ public:
|
||||
|
||||
void dispatch(BOOST_ASIO_MOVE_ARG(function) f)
|
||||
{
|
||||
executor_.dispatch(BOOST_ASIO_MOVE_CAST(function)(f), allocator_);
|
||||
executor_.dispatch(BOOST_ASIO_MOVE_CAST(function)(f),
|
||||
std::allocator<void>());
|
||||
}
|
||||
|
||||
void post(BOOST_ASIO_MOVE_ARG(function) f)
|
||||
{
|
||||
executor_.post(BOOST_ASIO_MOVE_CAST(function)(f), allocator_);
|
||||
executor_.post(BOOST_ASIO_MOVE_CAST(function)(f),
|
||||
std::allocator<void>());
|
||||
}
|
||||
|
||||
void defer(BOOST_ASIO_MOVE_ARG(function) f)
|
||||
{
|
||||
executor_.defer(BOOST_ASIO_MOVE_CAST(function)(f), allocator_);
|
||||
executor_.defer(BOOST_ASIO_MOVE_CAST(function)(f),
|
||||
std::allocator<void>());
|
||||
}
|
||||
|
||||
type_id_result_type target_type() const BOOST_ASIO_NOEXCEPT
|
||||
@@ -325,7 +237,6 @@ public:
|
||||
|
||||
private:
|
||||
system_executor executor_;
|
||||
Allocator allocator_;
|
||||
};
|
||||
|
||||
template <typename Executor>
|
||||
@@ -386,4 +297,6 @@ const Executor* executor::target() const BOOST_ASIO_NOEXCEPT
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
||||
|
||||
#endif // BOOST_ASIO_IMPL_EXECUTOR_HPP
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/executor.ipp
|
||||
// ~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -16,6 +16,9 @@
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
||||
|
||||
#include <boost/asio/executor.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
@@ -37,4 +40,6 @@ const char* bad_executor::what() const BOOST_ASIO_NOEXCEPT_OR_NOTHROW
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
||||
|
||||
#endif // BOOST_ASIO_IMPL_EXECUTOR_IPP
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/handler_alloc_hook.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -16,6 +16,7 @@
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <boost/asio/detail/memory.hpp>
|
||||
#include <boost/asio/detail/thread_context.hpp>
|
||||
#include <boost/asio/detail/thread_info_base.hpp>
|
||||
#include <boost/asio/handler_alloc_hook.hpp>
|
||||
@@ -25,24 +26,33 @@
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
void* asio_handler_allocate(std::size_t size, ...)
|
||||
asio_handler_allocate_is_deprecated
|
||||
asio_handler_allocate(std::size_t size, ...)
|
||||
{
|
||||
#if !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
(void)size;
|
||||
return asio_handler_allocate_is_no_longer_used();
|
||||
#elif !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)
|
||||
return detail::thread_info_base::allocate(
|
||||
detail::thread_context::thread_call_stack::top(), size);
|
||||
detail::thread_context::top_of_thread_call_stack(), size);
|
||||
#else // !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)
|
||||
return ::operator new(size);
|
||||
return aligned_new(BOOST_ASIO_DEFAULT_ALIGN, size);
|
||||
#endif // !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)
|
||||
}
|
||||
|
||||
void asio_handler_deallocate(void* pointer, std::size_t size, ...)
|
||||
asio_handler_deallocate_is_deprecated
|
||||
asio_handler_deallocate(void* pointer, std::size_t size, ...)
|
||||
{
|
||||
#if !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
(void)pointer;
|
||||
(void)size;
|
||||
return asio_handler_deallocate_is_no_longer_used();
|
||||
#elif !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)
|
||||
detail::thread_info_base::deallocate(
|
||||
detail::thread_context::thread_call_stack::top(), pointer, size);
|
||||
detail::thread_context::top_of_thread_call_stack(), pointer, size);
|
||||
#else // !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)
|
||||
(void)size;
|
||||
::operator delete(pointer);
|
||||
aligned_delete(pointer);
|
||||
#endif // !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/io_context.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -20,18 +20,17 @@
|
||||
#include <boost/asio/detail/fenced_block.hpp>
|
||||
#include <boost/asio/detail/handler_type_requirements.hpp>
|
||||
#include <boost/asio/detail/non_const_lvalue.hpp>
|
||||
#include <boost/asio/detail/recycling_allocator.hpp>
|
||||
#include <boost/asio/detail/service_registry.hpp>
|
||||
#include <boost/asio/detail/throw_error.hpp>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename Service>
|
||||
inline Service& use_service(io_context& ioc)
|
||||
{
|
||||
@@ -49,24 +48,8 @@ inline detail::io_context_impl& use_service<detail::io_context_impl>(
|
||||
return ioc.impl_;
|
||||
}
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_IOCP)
|
||||
# include <boost/asio/detail/win_iocp_io_context.hpp>
|
||||
#else
|
||||
# include <boost/asio/detail/scheduler.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
inline io_context::executor_type
|
||||
io_context::get_executor() BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
@@ -157,10 +140,10 @@ struct io_context::initiate_dispatch
|
||||
{
|
||||
// Allocate and construct an operation to wrap the handler.
|
||||
typedef detail::completion_handler<
|
||||
typename decay<LegacyCompletionHandler>::type> op;
|
||||
typename decay<LegacyCompletionHandler>::type, executor_type> op;
|
||||
typename op::ptr p = { detail::addressof(handler2.value),
|
||||
op::ptr::allocate(handler2.value), 0 };
|
||||
p.p = new (p.v) op(handler2.value);
|
||||
p.p = new (p.v) op(handler2.value, self->get_executor());
|
||||
|
||||
BOOST_ASIO_HANDLER_CREATION((*self, *p.p,
|
||||
"io_context", self, 0, "dispatch"));
|
||||
@@ -172,8 +155,11 @@ struct io_context::initiate_dispatch
|
||||
};
|
||||
|
||||
template <typename LegacyCompletionHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ())
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(LegacyCompletionHandler, void ())
|
||||
io_context::dispatch(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<LegacyCompletionHandler, void ()>(
|
||||
declval<initiate_dispatch>(), handler, this)))
|
||||
{
|
||||
return async_initiate<LegacyCompletionHandler, void ()>(
|
||||
initiate_dispatch(), handler, this);
|
||||
@@ -197,10 +183,10 @@ struct io_context::initiate_post
|
||||
|
||||
// Allocate and construct an operation to wrap the handler.
|
||||
typedef detail::completion_handler<
|
||||
typename decay<LegacyCompletionHandler>::type> op;
|
||||
typename decay<LegacyCompletionHandler>::type, executor_type> op;
|
||||
typename op::ptr p = { detail::addressof(handler2.value),
|
||||
op::ptr::allocate(handler2.value), 0 };
|
||||
p.p = new (p.v) op(handler2.value);
|
||||
p.p = new (p.v) op(handler2.value, self->get_executor());
|
||||
|
||||
BOOST_ASIO_HANDLER_CREATION((*self, *p.p,
|
||||
"io_context", self, 0, "post"));
|
||||
@@ -211,8 +197,11 @@ struct io_context::initiate_post
|
||||
};
|
||||
|
||||
template <typename LegacyCompletionHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ())
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(LegacyCompletionHandler, void ())
|
||||
io_context::post(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<LegacyCompletionHandler, void ()>(
|
||||
declval<initiate_post>(), handler, this)))
|
||||
{
|
||||
return async_initiate<LegacyCompletionHandler, void ()>(
|
||||
initiate_post(), handler, this);
|
||||
@@ -231,32 +220,138 @@ io_context::wrap(Handler handler)
|
||||
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
inline io_context&
|
||||
io_context::executor_type::context() const BOOST_ASIO_NOEXCEPT
|
||||
template <typename Allocator, uintptr_t Bits>
|
||||
io_context::basic_executor_type<Allocator, Bits>&
|
||||
io_context::basic_executor_type<Allocator, Bits>::operator=(
|
||||
const basic_executor_type& other) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return io_context_;
|
||||
if (this != &other)
|
||||
{
|
||||
static_cast<Allocator&>(*this) = static_cast<const Allocator&>(other);
|
||||
io_context* old_io_context = context_ptr();
|
||||
target_ = other.target_;
|
||||
if (Bits & outstanding_work_tracked)
|
||||
{
|
||||
if (context_ptr())
|
||||
context_ptr()->impl_.work_started();
|
||||
if (old_io_context)
|
||||
old_io_context->impl_.work_finished();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void
|
||||
io_context::executor_type::on_work_started() const BOOST_ASIO_NOEXCEPT
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
template <typename Allocator, uintptr_t Bits>
|
||||
io_context::basic_executor_type<Allocator, Bits>&
|
||||
io_context::basic_executor_type<Allocator, Bits>::operator=(
|
||||
basic_executor_type&& other) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
io_context_.impl_.work_started();
|
||||
if (this != &other)
|
||||
{
|
||||
static_cast<Allocator&>(*this) = static_cast<Allocator&&>(other);
|
||||
io_context* old_io_context = context_ptr();
|
||||
target_ = other.target_;
|
||||
if (Bits & outstanding_work_tracked)
|
||||
{
|
||||
other.target_ = 0;
|
||||
if (old_io_context)
|
||||
old_io_context->impl_.work_finished();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
template <typename Allocator, uintptr_t Bits>
|
||||
inline bool io_context::basic_executor_type<Allocator,
|
||||
Bits>::running_in_this_thread() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return context_ptr()->impl_.can_dispatch();
|
||||
}
|
||||
|
||||
inline void
|
||||
io_context::executor_type::on_work_finished() const BOOST_ASIO_NOEXCEPT
|
||||
template <typename Allocator, uintptr_t Bits>
|
||||
template <typename Function>
|
||||
void io_context::basic_executor_type<Allocator, Bits>::execute(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f) const
|
||||
{
|
||||
io_context_.impl_.work_finished();
|
||||
typedef typename decay<Function>::type function_type;
|
||||
|
||||
// Invoke immediately if the blocking.possibly property is enabled and we are
|
||||
// already inside the thread pool.
|
||||
if ((bits() & blocking_never) == 0 && context_ptr()->impl_.can_dispatch())
|
||||
{
|
||||
// Make a local, non-const copy of the function.
|
||||
function_type tmp(BOOST_ASIO_MOVE_CAST(Function)(f));
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_STD_EXCEPTION_PTR) \
|
||||
&& !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
try
|
||||
{
|
||||
#endif // defined(BOOST_ASIO_HAS_STD_EXCEPTION_PTR)
|
||||
// && !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
detail::fenced_block b(detail::fenced_block::full);
|
||||
boost_asio_handler_invoke_helpers::invoke(tmp, tmp);
|
||||
return;
|
||||
#if defined(BOOST_ASIO_HAS_STD_EXCEPTION_PTR) \
|
||||
&& !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
context_ptr()->impl_.capture_current_exception();
|
||||
return;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_STD_EXCEPTION_PTR)
|
||||
// && !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
}
|
||||
|
||||
// Allocate and construct an operation to wrap the function.
|
||||
typedef detail::executor_op<function_type, Allocator, detail::operation> op;
|
||||
typename op::ptr p = {
|
||||
detail::addressof(static_cast<const Allocator&>(*this)),
|
||||
op::ptr::allocate(static_cast<const Allocator&>(*this)), 0 };
|
||||
p.p = new (p.v) op(BOOST_ASIO_MOVE_CAST(Function)(f),
|
||||
static_cast<const Allocator&>(*this));
|
||||
|
||||
BOOST_ASIO_HANDLER_CREATION((*context_ptr(), *p.p,
|
||||
"io_context", context_ptr(), 0, "execute"));
|
||||
|
||||
context_ptr()->impl_.post_immediate_completion(p.p,
|
||||
(bits() & relationship_continuation) != 0);
|
||||
p.v = p.p = 0;
|
||||
}
|
||||
|
||||
template <typename Function, typename Allocator>
|
||||
void io_context::executor_type::dispatch(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, const Allocator& a) const
|
||||
#if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
||||
template <typename Allocator, uintptr_t Bits>
|
||||
inline io_context& io_context::basic_executor_type<
|
||||
Allocator, Bits>::context() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return *context_ptr();
|
||||
}
|
||||
|
||||
template <typename Allocator, uintptr_t Bits>
|
||||
inline void io_context::basic_executor_type<Allocator,
|
||||
Bits>::on_work_started() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
context_ptr()->impl_.work_started();
|
||||
}
|
||||
|
||||
template <typename Allocator, uintptr_t Bits>
|
||||
inline void io_context::basic_executor_type<Allocator,
|
||||
Bits>::on_work_finished() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
context_ptr()->impl_.work_finished();
|
||||
}
|
||||
|
||||
template <typename Allocator, uintptr_t Bits>
|
||||
template <typename Function, typename OtherAllocator>
|
||||
void io_context::basic_executor_type<Allocator, Bits>::dispatch(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const
|
||||
{
|
||||
typedef typename decay<Function>::type function_type;
|
||||
|
||||
// Invoke immediately if we are already inside the thread pool.
|
||||
if (io_context_.impl_.can_dispatch())
|
||||
if (context_ptr()->impl_.can_dispatch())
|
||||
{
|
||||
// Make a local, non-const copy of the function.
|
||||
function_type tmp(BOOST_ASIO_MOVE_CAST(Function)(f));
|
||||
@@ -267,58 +362,58 @@ void io_context::executor_type::dispatch(
|
||||
}
|
||||
|
||||
// Allocate and construct an operation to wrap the function.
|
||||
typedef detail::executor_op<function_type, Allocator, detail::operation> op;
|
||||
typedef detail::executor_op<function_type,
|
||||
OtherAllocator, detail::operation> op;
|
||||
typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };
|
||||
p.p = new (p.v) op(BOOST_ASIO_MOVE_CAST(Function)(f), a);
|
||||
|
||||
BOOST_ASIO_HANDLER_CREATION((this->context(), *p.p,
|
||||
"io_context", &this->context(), 0, "dispatch"));
|
||||
BOOST_ASIO_HANDLER_CREATION((*context_ptr(), *p.p,
|
||||
"io_context", context_ptr(), 0, "dispatch"));
|
||||
|
||||
io_context_.impl_.post_immediate_completion(p.p, false);
|
||||
context_ptr()->impl_.post_immediate_completion(p.p, false);
|
||||
p.v = p.p = 0;
|
||||
}
|
||||
|
||||
template <typename Function, typename Allocator>
|
||||
void io_context::executor_type::post(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, const Allocator& a) const
|
||||
template <typename Allocator, uintptr_t Bits>
|
||||
template <typename Function, typename OtherAllocator>
|
||||
void io_context::basic_executor_type<Allocator, Bits>::post(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const
|
||||
{
|
||||
typedef typename decay<Function>::type function_type;
|
||||
|
||||
// Allocate and construct an operation to wrap the function.
|
||||
typedef detail::executor_op<function_type, Allocator, detail::operation> op;
|
||||
typedef detail::executor_op<function_type,
|
||||
OtherAllocator, detail::operation> op;
|
||||
typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };
|
||||
p.p = new (p.v) op(BOOST_ASIO_MOVE_CAST(Function)(f), a);
|
||||
|
||||
BOOST_ASIO_HANDLER_CREATION((this->context(), *p.p,
|
||||
"io_context", &this->context(), 0, "post"));
|
||||
BOOST_ASIO_HANDLER_CREATION((*context_ptr(), *p.p,
|
||||
"io_context", context_ptr(), 0, "post"));
|
||||
|
||||
io_context_.impl_.post_immediate_completion(p.p, false);
|
||||
context_ptr()->impl_.post_immediate_completion(p.p, false);
|
||||
p.v = p.p = 0;
|
||||
}
|
||||
|
||||
template <typename Function, typename Allocator>
|
||||
void io_context::executor_type::defer(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, const Allocator& a) const
|
||||
template <typename Allocator, uintptr_t Bits>
|
||||
template <typename Function, typename OtherAllocator>
|
||||
void io_context::basic_executor_type<Allocator, Bits>::defer(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const
|
||||
{
|
||||
typedef typename decay<Function>::type function_type;
|
||||
|
||||
// Allocate and construct an operation to wrap the function.
|
||||
typedef detail::executor_op<function_type, Allocator, detail::operation> op;
|
||||
typedef detail::executor_op<function_type,
|
||||
OtherAllocator, detail::operation> op;
|
||||
typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };
|
||||
p.p = new (p.v) op(BOOST_ASIO_MOVE_CAST(Function)(f), a);
|
||||
|
||||
BOOST_ASIO_HANDLER_CREATION((this->context(), *p.p,
|
||||
"io_context", &this->context(), 0, "defer"));
|
||||
BOOST_ASIO_HANDLER_CREATION((*context_ptr(), *p.p,
|
||||
"io_context", context_ptr(), 0, "defer"));
|
||||
|
||||
io_context_.impl_.post_immediate_completion(p.p, true);
|
||||
context_ptr()->impl_.post_immediate_completion(p.p, true);
|
||||
p.v = p.p = 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
io_context::executor_type::running_in_this_thread() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return io_context_.impl_.can_dispatch();
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
inline io_context::work::work(boost::asio::io_context& io_context)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/io_context.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -55,6 +55,7 @@ io_context::impl_type& io_context::add_impl(io_context::impl_type* impl)
|
||||
|
||||
io_context::~io_context()
|
||||
{
|
||||
shutdown();
|
||||
}
|
||||
|
||||
io_context::count_type io_context::run()
|
||||
|
||||
51
linx64/include/boost/asio/impl/multiple_exceptions.ipp
Normal file
51
linx64/include/boost/asio/impl/multiple_exceptions.ipp
Normal file
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// impl/multiple_exceptions.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2023 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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_ASIO_IMPL_MULTIPLE_EXCEPTIONS_IPP
|
||||
#define BOOST_ASIO_IMPL_MULTIPLE_EXCEPTIONS_IPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <boost/asio/multiple_exceptions.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_STD_EXCEPTION_PTR)
|
||||
|
||||
multiple_exceptions::multiple_exceptions(
|
||||
std::exception_ptr first) BOOST_ASIO_NOEXCEPT
|
||||
: first_(BOOST_ASIO_MOVE_CAST(std::exception_ptr)(first))
|
||||
{
|
||||
}
|
||||
|
||||
const char* multiple_exceptions::what() const BOOST_ASIO_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
return "multiple exceptions";
|
||||
}
|
||||
|
||||
std::exception_ptr multiple_exceptions::first_exception() const
|
||||
{
|
||||
return first_;
|
||||
}
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_STD_EXCEPTION_PTR)
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_IMPL_MULTIPLE_EXCEPTIONS_IPP
|
||||
@@ -1,93 +0,0 @@
|
||||
//
|
||||
// impl/post.hpp
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_ASIO_IMPL_POST_HPP
|
||||
#define BOOST_ASIO_IMPL_POST_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/detail/work_dispatcher.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
struct initiate_post
|
||||
{
|
||||
template <typename CompletionHandler>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) const
|
||||
{
|
||||
typedef typename decay<CompletionHandler>::type DecayedHandler;
|
||||
|
||||
typename associated_executor<DecayedHandler>::type ex(
|
||||
(get_associated_executor)(handler));
|
||||
|
||||
typename associated_allocator<DecayedHandler>::type alloc(
|
||||
(get_associated_allocator)(handler));
|
||||
|
||||
ex.post(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
|
||||
}
|
||||
|
||||
template <typename CompletionHandler, typename Executor>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
|
||||
BOOST_ASIO_MOVE_ARG(Executor) ex) const
|
||||
{
|
||||
typedef typename decay<CompletionHandler>::type DecayedHandler;
|
||||
|
||||
typename associated_allocator<DecayedHandler>::type alloc(
|
||||
(get_associated_allocator)(handler));
|
||||
|
||||
ex.post(detail::work_dispatcher<DecayedHandler>(
|
||||
BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post(
|
||||
BOOST_ASIO_MOVE_ARG(CompletionToken) token)
|
||||
{
|
||||
return async_initiate<CompletionToken, void()>(
|
||||
detail::initiate_post(), token);
|
||||
}
|
||||
|
||||
template <typename Executor, typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post(
|
||||
const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
|
||||
typename enable_if<is_executor<Executor>::value>::type*)
|
||||
{
|
||||
return async_initiate<CompletionToken, void()>(
|
||||
detail::initiate_post(), token, ex);
|
||||
}
|
||||
|
||||
template <typename ExecutionContext, typename CompletionToken>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post(
|
||||
ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
|
||||
typename enable_if<is_convertible<
|
||||
ExecutionContext&, execution_context&>::value>::type*)
|
||||
{
|
||||
return (post)(ctx.get_executor(),
|
||||
BOOST_ASIO_MOVE_CAST(CompletionToken)(token));
|
||||
}
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_IMPL_POST_HPP
|
||||
227
linx64/include/boost/asio/impl/prepend.hpp
Normal file
227
linx64/include/boost/asio/impl/prepend.hpp
Normal file
@@ -0,0 +1,227 @@
|
||||
//
|
||||
// impl/prepend.hpp
|
||||
// ~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2023 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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_ASIO_IMPL_PREPEND_HPP
|
||||
#define BOOST_ASIO_IMPL_PREPEND_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#include <boost/asio/associator.hpp>
|
||||
#include <boost/asio/async_result.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>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
#include <boost/asio/detail/utility.hpp>
|
||||
#include <boost/asio/detail/variadic_templates.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
// Class to adapt a prepend_t as a completion handler.
|
||||
template <typename Handler, typename... Values>
|
||||
class prepend_handler
|
||||
{
|
||||
public:
|
||||
typedef void result_type;
|
||||
|
||||
template <typename H>
|
||||
prepend_handler(BOOST_ASIO_MOVE_ARG(H) handler, std::tuple<Values...> values)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(H)(handler)),
|
||||
values_(BOOST_ASIO_MOVE_CAST(std::tuple<Values...>)(values))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
this->invoke(
|
||||
index_sequence_for<Values...>{},
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
|
||||
template <std::size_t... I, typename... Args>
|
||||
void invoke(index_sequence<I...>, BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)(
|
||||
BOOST_ASIO_MOVE_CAST(Values)(std::get<I>(values_))...,
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
|
||||
//private:
|
||||
Handler handler_;
|
||||
std::tuple<Values...> values_;
|
||||
};
|
||||
|
||||
template <typename Handler>
|
||||
inline asio_handler_allocate_is_deprecated
|
||||
asio_handler_allocate(std::size_t size,
|
||||
prepend_handler<Handler>* this_handler)
|
||||
{
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
|
||||
return asio_handler_allocate_is_no_longer_used();
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
inline asio_handler_deallocate_is_deprecated
|
||||
asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
prepend_handler<Handler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_deallocate_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
inline bool asio_handler_is_continuation(
|
||||
prepend_handler<Handler>* this_handler)
|
||||
{
|
||||
return boost_asio_handler_cont_helpers::is_continuation(
|
||||
this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler>
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(Function& function,
|
||||
prepend_handler<Handler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler>
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(const Function& function,
|
||||
prepend_handler<Handler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Signature, typename... Values>
|
||||
struct prepend_signature;
|
||||
|
||||
template <typename R, typename... Args, typename... Values>
|
||||
struct prepend_signature<R(Args...), Values...>
|
||||
{
|
||||
typedef R type(Values..., typename decay<Args>::type...);
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename CompletionToken, typename... Values, typename Signature>
|
||||
struct async_result<
|
||||
prepend_t<CompletionToken, Values...>, Signature>
|
||||
: async_result<CompletionToken,
|
||||
typename detail::prepend_signature<
|
||||
Signature, Values...>::type>
|
||||
{
|
||||
typedef typename detail::prepend_signature<
|
||||
Signature, Values...>::type signature;
|
||||
|
||||
template <typename Initiation>
|
||||
struct init_wrapper
|
||||
{
|
||||
init_wrapper(Initiation init)
|
||||
: initiation_(BOOST_ASIO_MOVE_CAST(Initiation)(init))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Handler, typename... Args>
|
||||
void operator()(
|
||||
BOOST_ASIO_MOVE_ARG(Handler) handler,
|
||||
std::tuple<Values...> values,
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)(
|
||||
detail::prepend_handler<
|
||||
typename decay<Handler>::type, Values...>(
|
||||
BOOST_ASIO_MOVE_CAST(Handler)(handler),
|
||||
BOOST_ASIO_MOVE_CAST(std::tuple<Values...>)(values)),
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
|
||||
Initiation initiation_;
|
||||
};
|
||||
|
||||
template <typename Initiation, typename RawCompletionToken, typename... Args>
|
||||
static BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, signature,
|
||||
(async_initiate<CompletionToken, signature>(
|
||||
declval<init_wrapper<typename decay<Initiation>::type> >(),
|
||||
declval<CompletionToken&>(),
|
||||
declval<std::tuple<Values...> >(),
|
||||
declval<BOOST_ASIO_MOVE_ARG(Args)>()...)))
|
||||
initiate(
|
||||
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
return async_initiate<CompletionToken, signature>(
|
||||
init_wrapper<typename decay<Initiation>::type>(
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
|
||||
token.token_,
|
||||
BOOST_ASIO_MOVE_CAST(std::tuple<Values...>)(token.values_),
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <template <typename, typename> class Associator,
|
||||
typename Handler, typename... Values, typename DefaultCandidate>
|
||||
struct associator<Associator,
|
||||
detail::prepend_handler<Handler, Values...>, DefaultCandidate>
|
||||
: Associator<Handler, DefaultCandidate>
|
||||
{
|
||||
static typename Associator<Handler, DefaultCandidate>::type
|
||||
get(const detail::prepend_handler<Handler, Values...>& h) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return Associator<Handler, DefaultCandidate>::get(h.handler_);
|
||||
}
|
||||
|
||||
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
|
||||
typename Associator<Handler, DefaultCandidate>::type)
|
||||
get(const detail::prepend_handler<Handler, Values...>& h,
|
||||
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
|
||||
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
|
||||
Associator<Handler, DefaultCandidate>::get(h.handler_, c)))
|
||||
{
|
||||
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_IMPL_PREPEND_HPP
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
// impl/read_at.hpp
|
||||
// ~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -16,11 +16,10 @@
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/associator.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/completion_condition.hpp>
|
||||
#include <boost/asio/detail/array_fwd.hpp>
|
||||
#include <boost/asio/detail/base_from_cancellation_state.hpp>
|
||||
#include <boost/asio/detail/base_from_completion_cond.hpp>
|
||||
#include <boost/asio/detail/bind_handler.hpp>
|
||||
#include <boost/asio/detail/consuming_buffers.hpp>
|
||||
@@ -28,6 +27,7 @@
|
||||
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_cont_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_tracking.hpp>
|
||||
#include <boost/asio/detail/handler_type_requirements.hpp>
|
||||
#include <boost/asio/detail/non_const_lvalue.hpp>
|
||||
#include <boost/asio/detail/throw_error.hpp>
|
||||
@@ -61,7 +61,7 @@ namespace detail
|
||||
else
|
||||
break;
|
||||
}
|
||||
return tmp.total_consumed();;
|
||||
return tmp.total_consumed();
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
@@ -176,14 +176,16 @@ namespace detail
|
||||
typename MutableBufferSequence, typename MutableBufferIterator,
|
||||
typename CompletionCondition, typename ReadHandler>
|
||||
class read_at_op
|
||||
: detail::base_from_completion_cond<CompletionCondition>
|
||||
: public base_from_cancellation_state<ReadHandler>,
|
||||
base_from_completion_cond<CompletionCondition>
|
||||
{
|
||||
public:
|
||||
read_at_op(AsyncRandomAccessReadDevice& device,
|
||||
uint64_t offset, const MutableBufferSequence& buffers,
|
||||
CompletionCondition& completion_condition, ReadHandler& handler)
|
||||
: detail::base_from_completion_cond<
|
||||
CompletionCondition>(completion_condition),
|
||||
: base_from_cancellation_state<ReadHandler>(
|
||||
handler, enable_partial_cancellation()),
|
||||
base_from_completion_cond<CompletionCondition>(completion_condition),
|
||||
device_(device),
|
||||
offset_(offset),
|
||||
buffers_(buffers),
|
||||
@@ -194,7 +196,8 @@ namespace detail
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
read_at_op(const read_at_op& other)
|
||||
: detail::base_from_completion_cond<CompletionCondition>(other),
|
||||
: base_from_cancellation_state<ReadHandler>(other),
|
||||
base_from_completion_cond<CompletionCondition>(other),
|
||||
device_(other.device_),
|
||||
offset_(other.offset_),
|
||||
buffers_(other.buffers_),
|
||||
@@ -204,8 +207,11 @@ namespace detail
|
||||
}
|
||||
|
||||
read_at_op(read_at_op&& other)
|
||||
: detail::base_from_completion_cond<CompletionCondition>(
|
||||
BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
|
||||
: base_from_cancellation_state<ReadHandler>(
|
||||
BOOST_ASIO_MOVE_CAST(base_from_cancellation_state<
|
||||
ReadHandler>)(other)),
|
||||
base_from_completion_cond<CompletionCondition>(
|
||||
BOOST_ASIO_MOVE_CAST(base_from_completion_cond<
|
||||
CompletionCondition>)(other)),
|
||||
device_(other.device_),
|
||||
offset_(other.offset_),
|
||||
@@ -216,7 +222,7 @@ namespace detail
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
void operator()(const boost::system::error_code& ec,
|
||||
void operator()(boost::system::error_code ec,
|
||||
std::size_t bytes_transferred, int start = 0)
|
||||
{
|
||||
std::size_t max_size;
|
||||
@@ -224,19 +230,31 @@ namespace detail
|
||||
{
|
||||
case 1:
|
||||
max_size = this->check_for_completion(ec, buffers_.total_consumed());
|
||||
do
|
||||
for (;;)
|
||||
{
|
||||
device_.async_read_some_at(
|
||||
offset_ + buffers_.total_consumed(), buffers_.prepare(max_size),
|
||||
BOOST_ASIO_MOVE_CAST(read_at_op)(*this));
|
||||
{
|
||||
BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read_at"));
|
||||
device_.async_read_some_at(
|
||||
offset_ + buffers_.total_consumed(), buffers_.prepare(max_size),
|
||||
BOOST_ASIO_MOVE_CAST(read_at_op)(*this));
|
||||
}
|
||||
return; default:
|
||||
buffers_.consume(bytes_transferred);
|
||||
if ((!ec && bytes_transferred == 0) || buffers_.empty())
|
||||
break;
|
||||
max_size = this->check_for_completion(ec, buffers_.total_consumed());
|
||||
} while (max_size > 0);
|
||||
if (max_size == 0)
|
||||
break;
|
||||
if (this->cancelled() != cancellation_type::none)
|
||||
{
|
||||
ec = boost::asio::error::operation_aborted;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
handler_(ec, buffers_.total_consumed());
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(
|
||||
static_cast<const boost::system::error_code&>(ec),
|
||||
static_cast<const std::size_t&>(buffers_.total_consumed()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,23 +272,33 @@ namespace detail
|
||||
template <typename AsyncRandomAccessReadDevice,
|
||||
typename MutableBufferSequence, typename MutableBufferIterator,
|
||||
typename CompletionCondition, typename ReadHandler>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
inline asio_handler_allocate_is_deprecated
|
||||
asio_handler_allocate(std::size_t size,
|
||||
read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
|
||||
MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)
|
||||
{
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
|
||||
return asio_handler_allocate_is_no_longer_used();
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename AsyncRandomAccessReadDevice,
|
||||
typename MutableBufferSequence, typename MutableBufferIterator,
|
||||
typename CompletionCondition, typename ReadHandler>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
inline asio_handler_deallocate_is_deprecated
|
||||
asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
|
||||
MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_deallocate_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename AsyncRandomAccessReadDevice,
|
||||
@@ -288,29 +316,37 @@ namespace detail
|
||||
template <typename Function, typename AsyncRandomAccessReadDevice,
|
||||
typename MutableBufferSequence, typename MutableBufferIterator,
|
||||
typename CompletionCondition, typename ReadHandler>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(Function& function,
|
||||
read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
|
||||
MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Function, typename AsyncRandomAccessReadDevice,
|
||||
typename MutableBufferSequence, typename MutableBufferIterator,
|
||||
typename CompletionCondition, typename ReadHandler>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(const Function& function,
|
||||
read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
|
||||
MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename AsyncRandomAccessReadDevice,
|
||||
typename MutableBufferSequence, typename MutableBufferIterator,
|
||||
typename CompletionCondition, typename ReadHandler>
|
||||
inline void start_read_at_buffer_sequence_op(AsyncRandomAccessReadDevice& d,
|
||||
inline void start_read_at_op(AsyncRandomAccessReadDevice& d,
|
||||
uint64_t offset, const MutableBufferSequence& buffers,
|
||||
const MutableBufferIterator&, CompletionCondition& completion_condition,
|
||||
ReadHandler& handler)
|
||||
@@ -321,13 +357,26 @@ namespace detail
|
||||
boost::system::error_code(), 0, 1);
|
||||
}
|
||||
|
||||
struct initiate_async_read_at_buffer_sequence
|
||||
template <typename AsyncRandomAccessReadDevice>
|
||||
class initiate_async_read_at
|
||||
{
|
||||
template <typename ReadHandler, typename AsyncRandomAccessReadDevice,
|
||||
typename MutableBufferSequence, typename CompletionCondition>
|
||||
public:
|
||||
typedef typename AsyncRandomAccessReadDevice::executor_type executor_type;
|
||||
|
||||
explicit initiate_async_read_at(AsyncRandomAccessReadDevice& device)
|
||||
: device_(device)
|
||||
{
|
||||
}
|
||||
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return device_.get_executor();
|
||||
}
|
||||
|
||||
template <typename ReadHandler, typename MutableBufferSequence,
|
||||
typename CompletionCondition>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
|
||||
AsyncRandomAccessReadDevice* d, uint64_t offset,
|
||||
const MutableBufferSequence& buffers,
|
||||
uint64_t offset, const MutableBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
|
||||
{
|
||||
// If you get an error on the following line it means that your handler
|
||||
@@ -336,84 +385,93 @@ namespace detail
|
||||
|
||||
non_const_lvalue<ReadHandler> handler2(handler);
|
||||
non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
|
||||
start_read_at_buffer_sequence_op(*d, offset, buffers,
|
||||
start_read_at_op(device_, offset, buffers,
|
||||
boost::asio::buffer_sequence_begin(buffers),
|
||||
completion_cond2.value, handler2.value);
|
||||
}
|
||||
|
||||
private:
|
||||
AsyncRandomAccessReadDevice& device_;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename AsyncRandomAccessReadDevice,
|
||||
typename MutableBufferSequence, typename MutableBufferIterator,
|
||||
typename CompletionCondition, typename ReadHandler, typename Allocator>
|
||||
struct associated_allocator<
|
||||
template <template <typename, typename> class Associator,
|
||||
typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
|
||||
typename MutableBufferIterator, typename CompletionCondition,
|
||||
typename ReadHandler, typename DefaultCandidate>
|
||||
struct associator<Associator,
|
||||
detail::read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
|
||||
MutableBufferIterator, CompletionCondition, ReadHandler>,
|
||||
Allocator>
|
||||
MutableBufferIterator, CompletionCondition, ReadHandler>,
|
||||
DefaultCandidate>
|
||||
: Associator<ReadHandler, DefaultCandidate>
|
||||
{
|
||||
typedef typename associated_allocator<ReadHandler, Allocator>::type type;
|
||||
|
||||
static type get(
|
||||
const detail::read_at_op<AsyncRandomAccessReadDevice,
|
||||
MutableBufferSequence, MutableBufferIterator,
|
||||
CompletionCondition, ReadHandler>& h,
|
||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
||||
static typename Associator<ReadHandler, DefaultCandidate>::type
|
||||
get(const detail::read_at_op<AsyncRandomAccessReadDevice,
|
||||
MutableBufferSequence, MutableBufferIterator,
|
||||
CompletionCondition, ReadHandler>& h) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
|
||||
return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AsyncRandomAccessReadDevice,
|
||||
typename MutableBufferSequence, typename MutableBufferIterator,
|
||||
typename CompletionCondition, typename ReadHandler, typename Executor>
|
||||
struct associated_executor<
|
||||
detail::read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
|
||||
MutableBufferIterator, CompletionCondition, ReadHandler>,
|
||||
Executor>
|
||||
{
|
||||
typedef typename associated_executor<ReadHandler, Executor>::type type;
|
||||
|
||||
static type get(
|
||||
const detail::read_at_op<AsyncRandomAccessReadDevice,
|
||||
MutableBufferSequence, MutableBufferIterator,
|
||||
CompletionCondition, ReadHandler>& h,
|
||||
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
|
||||
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
|
||||
typename Associator<ReadHandler, DefaultCandidate>::type)
|
||||
get(const detail::read_at_op<AsyncRandomAccessReadDevice,
|
||||
MutableBufferSequence, MutableBufferIterator,
|
||||
CompletionCondition, ReadHandler>& h,
|
||||
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
|
||||
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
|
||||
Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))
|
||||
{
|
||||
return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
|
||||
return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
|
||||
typename CompletionCondition, typename ReadHandler>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
|
||||
template <typename AsyncRandomAccessReadDevice,
|
||||
typename MutableBufferSequence, typename CompletionCondition,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
std::size_t)) ReadToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
async_read_at(AsyncRandomAccessReadDevice& d,
|
||||
uint64_t offset, const MutableBufferSequence& buffers,
|
||||
CompletionCondition completion_condition,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
BOOST_ASIO_MOVE_ARG(ReadToken) token)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<ReadToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
declval<detail::initiate_async_read_at<AsyncRandomAccessReadDevice> >(),
|
||||
token, offset, buffers,
|
||||
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))
|
||||
{
|
||||
return async_initiate<ReadHandler,
|
||||
return async_initiate<ReadToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
detail::initiate_async_read_at_buffer_sequence(), handler, &d, offset,
|
||||
buffers, BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
|
||||
detail::initiate_async_read_at<AsyncRandomAccessReadDevice>(d),
|
||||
token, offset, buffers,
|
||||
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
|
||||
}
|
||||
|
||||
template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
|
||||
typename ReadHandler>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
std::size_t)) ReadToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
async_read_at(AsyncRandomAccessReadDevice& d,
|
||||
uint64_t offset, const MutableBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
BOOST_ASIO_MOVE_ARG(ReadToken) token)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<ReadToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
declval<detail::initiate_async_read_at<AsyncRandomAccessReadDevice> >(),
|
||||
token, offset, buffers, transfer_all())))
|
||||
{
|
||||
return async_initiate<ReadHandler,
|
||||
return async_initiate<ReadToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
detail::initiate_async_read_at_buffer_sequence(),
|
||||
handler, &d, offset, buffers, transfer_all());
|
||||
detail::initiate_async_read_at<AsyncRandomAccessReadDevice>(d),
|
||||
token, offset, buffers, transfer_all());
|
||||
}
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_EXTENSIONS)
|
||||
@@ -424,14 +482,16 @@ namespace detail
|
||||
template <typename AsyncRandomAccessReadDevice, typename Allocator,
|
||||
typename CompletionCondition, typename ReadHandler>
|
||||
class read_at_streambuf_op
|
||||
: detail::base_from_completion_cond<CompletionCondition>
|
||||
: public base_from_cancellation_state<ReadHandler>,
|
||||
base_from_completion_cond<CompletionCondition>
|
||||
{
|
||||
public:
|
||||
read_at_streambuf_op(AsyncRandomAccessReadDevice& device,
|
||||
uint64_t offset, basic_streambuf<Allocator>& streambuf,
|
||||
CompletionCondition& completion_condition, ReadHandler& handler)
|
||||
: detail::base_from_completion_cond<
|
||||
CompletionCondition>(completion_condition),
|
||||
: base_from_cancellation_state<ReadHandler>(
|
||||
handler, enable_partial_cancellation()),
|
||||
base_from_completion_cond<CompletionCondition>(completion_condition),
|
||||
device_(device),
|
||||
offset_(offset),
|
||||
streambuf_(streambuf),
|
||||
@@ -443,7 +503,8 @@ namespace detail
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
read_at_streambuf_op(const read_at_streambuf_op& other)
|
||||
: detail::base_from_completion_cond<CompletionCondition>(other),
|
||||
: base_from_cancellation_state<ReadHandler>(other),
|
||||
base_from_completion_cond<CompletionCondition>(other),
|
||||
device_(other.device_),
|
||||
offset_(other.offset_),
|
||||
streambuf_(other.streambuf_),
|
||||
@@ -454,8 +515,11 @@ namespace detail
|
||||
}
|
||||
|
||||
read_at_streambuf_op(read_at_streambuf_op&& other)
|
||||
: detail::base_from_completion_cond<CompletionCondition>(
|
||||
BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
|
||||
: base_from_cancellation_state<ReadHandler>(
|
||||
BOOST_ASIO_MOVE_CAST(base_from_cancellation_state<
|
||||
ReadHandler>)(other)),
|
||||
base_from_completion_cond<CompletionCondition>(
|
||||
BOOST_ASIO_MOVE_CAST(base_from_completion_cond<
|
||||
CompletionCondition>)(other)),
|
||||
device_(other.device_),
|
||||
offset_(other.offset_),
|
||||
@@ -467,7 +531,7 @@ namespace detail
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
void operator()(const boost::system::error_code& ec,
|
||||
void operator()(boost::system::error_code ec,
|
||||
std::size_t bytes_transferred, int start = 0)
|
||||
{
|
||||
std::size_t max_size, bytes_available;
|
||||
@@ -478,9 +542,12 @@ namespace detail
|
||||
bytes_available = read_size_helper(streambuf_, max_size);
|
||||
for (;;)
|
||||
{
|
||||
device_.async_read_some_at(offset_ + total_transferred_,
|
||||
streambuf_.prepare(bytes_available),
|
||||
BOOST_ASIO_MOVE_CAST(read_at_streambuf_op)(*this));
|
||||
{
|
||||
BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read_at"));
|
||||
device_.async_read_some_at(offset_ + total_transferred_,
|
||||
streambuf_.prepare(bytes_available),
|
||||
BOOST_ASIO_MOVE_CAST(read_at_streambuf_op)(*this));
|
||||
}
|
||||
return; default:
|
||||
total_transferred_ += bytes_transferred;
|
||||
streambuf_.commit(bytes_transferred);
|
||||
@@ -488,9 +555,16 @@ namespace detail
|
||||
bytes_available = read_size_helper(streambuf_, max_size);
|
||||
if ((!ec && bytes_transferred == 0) || bytes_available == 0)
|
||||
break;
|
||||
if (this->cancelled() != cancellation_type::none)
|
||||
{
|
||||
ec = boost::asio::error::operation_aborted;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
handler_(ec, static_cast<const std::size_t&>(total_transferred_));
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(
|
||||
static_cast<const boost::system::error_code&>(ec),
|
||||
static_cast<const std::size_t&>(total_transferred_));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,22 +579,32 @@ namespace detail
|
||||
|
||||
template <typename AsyncRandomAccessReadDevice, typename Allocator,
|
||||
typename CompletionCondition, typename ReadHandler>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
inline asio_handler_allocate_is_deprecated
|
||||
asio_handler_allocate(std::size_t size,
|
||||
read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
|
||||
CompletionCondition, ReadHandler>* this_handler)
|
||||
{
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
|
||||
return asio_handler_allocate_is_no_longer_used();
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename AsyncRandomAccessReadDevice, typename Allocator,
|
||||
typename CompletionCondition, typename ReadHandler>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
inline asio_handler_deallocate_is_deprecated
|
||||
asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
|
||||
CompletionCondition, ReadHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_deallocate_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename AsyncRandomAccessReadDevice, typename Allocator,
|
||||
@@ -536,31 +620,53 @@ namespace detail
|
||||
|
||||
template <typename Function, typename AsyncRandomAccessReadDevice,
|
||||
typename Allocator, typename CompletionCondition, typename ReadHandler>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(Function& function,
|
||||
read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
|
||||
CompletionCondition, ReadHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Function, typename AsyncRandomAccessReadDevice,
|
||||
typename Allocator, typename CompletionCondition, typename ReadHandler>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(const Function& function,
|
||||
read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
|
||||
CompletionCondition, ReadHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
struct initiate_async_read_at_streambuf
|
||||
template <typename AsyncRandomAccessReadDevice>
|
||||
class initiate_async_read_at_streambuf
|
||||
{
|
||||
template <typename ReadHandler, typename AsyncRandomAccessReadDevice,
|
||||
public:
|
||||
typedef typename AsyncRandomAccessReadDevice::executor_type executor_type;
|
||||
|
||||
explicit initiate_async_read_at_streambuf(
|
||||
AsyncRandomAccessReadDevice& device)
|
||||
: device_(device)
|
||||
{
|
||||
}
|
||||
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return device_.get_executor();
|
||||
}
|
||||
|
||||
template <typename ReadHandler,
|
||||
typename Allocator, typename CompletionCondition>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
|
||||
AsyncRandomAccessReadDevice* d, uint64_t offset,
|
||||
basic_streambuf<Allocator>* b,
|
||||
uint64_t offset, basic_streambuf<Allocator>* b,
|
||||
BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
|
||||
{
|
||||
// If you get an error on the following line it means that your handler
|
||||
@@ -571,79 +677,92 @@ namespace detail
|
||||
non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
|
||||
read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
|
||||
CompletionCondition, typename decay<ReadHandler>::type>(
|
||||
*d, offset, *b, completion_cond2.value, handler2.value)(
|
||||
device_, offset, *b, completion_cond2.value, handler2.value)(
|
||||
boost::system::error_code(), 0, 1);
|
||||
}
|
||||
|
||||
private:
|
||||
AsyncRandomAccessReadDevice& device_;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename AsyncRandomAccessReadDevice, typename Allocator,
|
||||
typename CompletionCondition, typename ReadHandler, typename Allocator1>
|
||||
struct associated_allocator<
|
||||
detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
|
||||
Allocator, CompletionCondition, ReadHandler>,
|
||||
Allocator1>
|
||||
{
|
||||
typedef typename associated_allocator<ReadHandler, Allocator1>::type type;
|
||||
|
||||
static type get(
|
||||
const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
|
||||
Allocator, CompletionCondition, ReadHandler>& h,
|
||||
const Allocator1& a = Allocator1()) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_allocator<ReadHandler, Allocator1>::get(h.handler_, a);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AsyncRandomAccessReadDevice, typename Executor,
|
||||
typename CompletionCondition, typename ReadHandler, typename Executor1>
|
||||
struct associated_executor<
|
||||
template <template <typename, typename> class Associator,
|
||||
typename AsyncRandomAccessReadDevice, typename Executor,
|
||||
typename CompletionCondition, typename ReadHandler,
|
||||
typename DefaultCandidate>
|
||||
struct associator<Associator,
|
||||
detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
|
||||
Executor, CompletionCondition, ReadHandler>,
|
||||
Executor1>
|
||||
DefaultCandidate>
|
||||
: Associator<ReadHandler, DefaultCandidate>
|
||||
{
|
||||
typedef typename associated_executor<ReadHandler, Executor1>::type type;
|
||||
|
||||
static type get(
|
||||
const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
|
||||
Executor, CompletionCondition, ReadHandler>& h,
|
||||
const Executor1& ex = Executor1()) BOOST_ASIO_NOEXCEPT
|
||||
static typename Associator<ReadHandler, DefaultCandidate>::type
|
||||
get(const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
|
||||
Executor, CompletionCondition, ReadHandler>& h) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_executor<ReadHandler, Executor1>::get(h.handler_, ex);
|
||||
return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);
|
||||
}
|
||||
|
||||
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
|
||||
typename Associator<ReadHandler, DefaultCandidate>::type)
|
||||
get(const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
|
||||
Executor, CompletionCondition, ReadHandler>& h,
|
||||
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
|
||||
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
|
||||
Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))
|
||||
{
|
||||
return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename AsyncRandomAccessReadDevice, typename Allocator,
|
||||
typename CompletionCondition, typename ReadHandler>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
|
||||
template <typename AsyncRandomAccessReadDevice,
|
||||
typename Allocator, typename CompletionCondition,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
std::size_t)) ReadToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
async_read_at(AsyncRandomAccessReadDevice& d,
|
||||
uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
|
||||
CompletionCondition completion_condition,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
BOOST_ASIO_MOVE_ARG(ReadToken) token)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<ReadToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
declval<detail::initiate_async_read_at_streambuf<
|
||||
AsyncRandomAccessReadDevice> >(),
|
||||
token, offset, &b,
|
||||
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))
|
||||
{
|
||||
return async_initiate<ReadHandler,
|
||||
return async_initiate<ReadToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
detail::initiate_async_read_at_streambuf(), handler, &d, offset,
|
||||
&b, BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
|
||||
detail::initiate_async_read_at_streambuf<AsyncRandomAccessReadDevice>(d),
|
||||
token, offset, &b,
|
||||
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
|
||||
}
|
||||
|
||||
template <typename AsyncRandomAccessReadDevice, typename Allocator,
|
||||
typename ReadHandler>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
std::size_t)) ReadToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
async_read_at(AsyncRandomAccessReadDevice& d,
|
||||
uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
BOOST_ASIO_MOVE_ARG(ReadToken) token)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<ReadToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
declval<detail::initiate_async_read_at_streambuf<
|
||||
AsyncRandomAccessReadDevice> >(),
|
||||
token, offset, &b, transfer_all())))
|
||||
{
|
||||
return async_initiate<ReadHandler,
|
||||
return async_initiate<ReadToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
detail::initiate_async_read_at_streambuf(),
|
||||
handler, &d, offset, &b, transfer_all());
|
||||
detail::initiate_async_read_at_streambuf<AsyncRandomAccessReadDevice>(d),
|
||||
token, offset, &b, transfer_all());
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
// impl/redirect_error.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -16,8 +16,7 @@
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associator.hpp>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_cont_helpers.hpp>
|
||||
@@ -56,7 +55,7 @@ public:
|
||||
|
||||
void operator()()
|
||||
{
|
||||
handler_();
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)();
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
@@ -67,7 +66,8 @@ public:
|
||||
>::type
|
||||
operator()(BOOST_ASIO_MOVE_ARG(Arg) arg, BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
handler_(BOOST_ASIO_MOVE_CAST(Arg)(arg),
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)(
|
||||
BOOST_ASIO_MOVE_CAST(Arg)(arg),
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,8 @@ public:
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
ec_ = ec;
|
||||
handler_(BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)(
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
|
||||
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
@@ -87,13 +88,14 @@ public:
|
||||
>::type
|
||||
operator()(BOOST_ASIO_MOVE_ARG(Arg) arg)
|
||||
{
|
||||
handler_(BOOST_ASIO_MOVE_CAST(Arg)(arg));
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)(
|
||||
BOOST_ASIO_MOVE_CAST(Arg)(arg));
|
||||
}
|
||||
|
||||
void operator()(const boost::system::error_code& ec)
|
||||
{
|
||||
ec_ = ec;
|
||||
handler_();
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)();
|
||||
}
|
||||
|
||||
#define BOOST_ASIO_PRIVATE_REDIRECT_ERROR_DEF(n) \
|
||||
@@ -103,7 +105,8 @@ public:
|
||||
>::type \
|
||||
operator()(BOOST_ASIO_MOVE_ARG(Arg) arg, BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||
{ \
|
||||
handler_(BOOST_ASIO_MOVE_CAST(Arg)(arg), \
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)( \
|
||||
BOOST_ASIO_MOVE_CAST(Arg)(arg), \
|
||||
BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||
} \
|
||||
\
|
||||
@@ -112,7 +115,8 @@ public:
|
||||
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||
{ \
|
||||
ec_ = ec; \
|
||||
handler_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)( \
|
||||
BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||
} \
|
||||
/**/
|
||||
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_REDIRECT_ERROR_DEF)
|
||||
@@ -126,19 +130,29 @@ public:
|
||||
};
|
||||
|
||||
template <typename Handler>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
inline asio_handler_allocate_is_deprecated
|
||||
asio_handler_allocate(std::size_t size,
|
||||
redirect_error_handler<Handler>* this_handler)
|
||||
{
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
|
||||
return asio_handler_allocate_is_no_longer_used();
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
inline asio_handler_deallocate_is_deprecated
|
||||
asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
redirect_error_handler<Handler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_deallocate_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
@@ -150,19 +164,27 @@ inline bool asio_handler_is_continuation(
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(Function& function,
|
||||
redirect_error_handler<Handler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(const Function& function,
|
||||
redirect_error_handler<Handler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Signature>
|
||||
@@ -185,6 +207,78 @@ struct redirect_error_signature<R(const boost::system::error_code&, Args...)>
|
||||
typedef R type(Args...);
|
||||
};
|
||||
|
||||
# if defined(BOOST_ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct redirect_error_signature<R(boost::system::error_code, Args...) &>
|
||||
{
|
||||
typedef R type(Args...) &;
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct redirect_error_signature<R(const boost::system::error_code&, Args...) &>
|
||||
{
|
||||
typedef R type(Args...) &;
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct redirect_error_signature<R(boost::system::error_code, Args...) &&>
|
||||
{
|
||||
typedef R type(Args...) &&;
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct redirect_error_signature<R(const boost::system::error_code&, Args...) &&>
|
||||
{
|
||||
typedef R type(Args...) &&;
|
||||
};
|
||||
|
||||
# if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct redirect_error_signature<
|
||||
R(boost::system::error_code, Args...) noexcept>
|
||||
{
|
||||
typedef R type(Args...) & noexcept;
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct redirect_error_signature<
|
||||
R(const boost::system::error_code&, Args...) noexcept>
|
||||
{
|
||||
typedef R type(Args...) & noexcept;
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct redirect_error_signature<
|
||||
R(boost::system::error_code, Args...) & noexcept>
|
||||
{
|
||||
typedef R type(Args...) & noexcept;
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct redirect_error_signature<
|
||||
R(const boost::system::error_code&, Args...) & noexcept>
|
||||
{
|
||||
typedef R type(Args...) & noexcept;
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct redirect_error_signature<
|
||||
R(boost::system::error_code, Args...) && noexcept>
|
||||
{
|
||||
typedef R type(Args...) && noexcept;
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct redirect_error_signature<
|
||||
R(const boost::system::error_code&, Args...) && noexcept>
|
||||
{
|
||||
typedef R type(Args...) && noexcept;
|
||||
};
|
||||
|
||||
# endif // defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
|
||||
# endif // defined(BOOST_ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
|
||||
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
template <typename R>
|
||||
@@ -217,6 +311,161 @@ struct redirect_error_signature<R(const boost::system::error_code&)>
|
||||
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_REDIRECT_ERROR_DEF)
|
||||
#undef BOOST_ASIO_PRIVATE_REDIRECT_ERROR_DEF
|
||||
|
||||
# if defined(BOOST_ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
|
||||
|
||||
template <typename R>
|
||||
struct redirect_error_signature<R(boost::system::error_code) &>
|
||||
{
|
||||
typedef R type() &;
|
||||
};
|
||||
|
||||
template <typename R>
|
||||
struct redirect_error_signature<R(const boost::system::error_code&) &>
|
||||
{
|
||||
typedef R type() &;
|
||||
};
|
||||
|
||||
template <typename R>
|
||||
struct redirect_error_signature<R(boost::system::error_code) &&>
|
||||
{
|
||||
typedef R type() &&;
|
||||
};
|
||||
|
||||
template <typename R>
|
||||
struct redirect_error_signature<R(const boost::system::error_code&) &&>
|
||||
{
|
||||
typedef R type() &&;
|
||||
};
|
||||
|
||||
#define BOOST_ASIO_PRIVATE_REDIRECT_ERROR_DEF(n) \
|
||||
template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
struct redirect_error_signature< \
|
||||
R(boost::system::error_code, BOOST_ASIO_VARIADIC_TARGS(n)) &> \
|
||||
{ \
|
||||
typedef R type(BOOST_ASIO_VARIADIC_TARGS(n)) &; \
|
||||
}; \
|
||||
\
|
||||
template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
struct redirect_error_signature< \
|
||||
R(const boost::system::error_code&, BOOST_ASIO_VARIADIC_TARGS(n)) &> \
|
||||
{ \
|
||||
typedef R type(BOOST_ASIO_VARIADIC_TARGS(n)) &; \
|
||||
}; \
|
||||
\
|
||||
template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
struct redirect_error_signature< \
|
||||
R(boost::system::error_code, BOOST_ASIO_VARIADIC_TARGS(n)) &&> \
|
||||
{ \
|
||||
typedef R type(BOOST_ASIO_VARIADIC_TARGS(n)) &&; \
|
||||
}; \
|
||||
\
|
||||
template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
struct redirect_error_signature< \
|
||||
R(const boost::system::error_code&, BOOST_ASIO_VARIADIC_TARGS(n)) &&> \
|
||||
{ \
|
||||
typedef R type(BOOST_ASIO_VARIADIC_TARGS(n)) &&; \
|
||||
}; \
|
||||
/**/
|
||||
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_REDIRECT_ERROR_DEF)
|
||||
#undef BOOST_ASIO_PRIVATE_REDIRECT_ERROR_DEF
|
||||
|
||||
# if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
|
||||
|
||||
template <typename R>
|
||||
struct redirect_error_signature<
|
||||
R(boost::system::error_code) noexcept>
|
||||
{
|
||||
typedef R type() noexcept;
|
||||
};
|
||||
|
||||
template <typename R>
|
||||
struct redirect_error_signature<
|
||||
R(const boost::system::error_code&) noexcept>
|
||||
{
|
||||
typedef R type() noexcept;
|
||||
};
|
||||
|
||||
template <typename R>
|
||||
struct redirect_error_signature<
|
||||
R(boost::system::error_code) & noexcept>
|
||||
{
|
||||
typedef R type() & noexcept;
|
||||
};
|
||||
|
||||
template <typename R>
|
||||
struct redirect_error_signature<
|
||||
R(const boost::system::error_code&) & noexcept>
|
||||
{
|
||||
typedef R type() & noexcept;
|
||||
};
|
||||
|
||||
template <typename R>
|
||||
struct redirect_error_signature<
|
||||
R(boost::system::error_code) && noexcept>
|
||||
{
|
||||
typedef R type() && noexcept;
|
||||
};
|
||||
|
||||
template <typename R>
|
||||
struct redirect_error_signature<
|
||||
R(const boost::system::error_code&) && noexcept>
|
||||
{
|
||||
typedef R type() && noexcept;
|
||||
};
|
||||
|
||||
#define BOOST_ASIO_PRIVATE_REDIRECT_ERROR_DEF(n) \
|
||||
template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
struct redirect_error_signature< \
|
||||
R(boost::system::error_code, BOOST_ASIO_VARIADIC_TARGS(n)) noexcept> \
|
||||
{ \
|
||||
typedef R type(BOOST_ASIO_VARIADIC_TARGS(n)) noexcept; \
|
||||
}; \
|
||||
\
|
||||
template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
struct redirect_error_signature< \
|
||||
R(const boost::system::error_code&, \
|
||||
BOOST_ASIO_VARIADIC_TARGS(n)) noexcept> \
|
||||
{ \
|
||||
typedef R type(BOOST_ASIO_VARIADIC_TARGS(n)) noexcept; \
|
||||
}; \
|
||||
\
|
||||
template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
struct redirect_error_signature< \
|
||||
R(boost::system::error_code, \
|
||||
BOOST_ASIO_VARIADIC_TARGS(n)) & noexcept> \
|
||||
{ \
|
||||
typedef R type(BOOST_ASIO_VARIADIC_TARGS(n)) & noexcept; \
|
||||
}; \
|
||||
\
|
||||
template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
struct redirect_error_signature< \
|
||||
R(const boost::system::error_code&, \
|
||||
BOOST_ASIO_VARIADIC_TARGS(n)) & noexcept> \
|
||||
{ \
|
||||
typedef R type(BOOST_ASIO_VARIADIC_TARGS(n)) & noexcept; \
|
||||
}; \
|
||||
\
|
||||
template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
struct redirect_error_signature< \
|
||||
R(boost::system::error_code, \
|
||||
BOOST_ASIO_VARIADIC_TARGS(n)) && noexcept> \
|
||||
{ \
|
||||
typedef R type(BOOST_ASIO_VARIADIC_TARGS(n)) && noexcept; \
|
||||
}; \
|
||||
\
|
||||
template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
struct redirect_error_signature< \
|
||||
R(const boost::system::error_code&, \
|
||||
BOOST_ASIO_VARIADIC_TARGS(n)) && noexcept> \
|
||||
{ \
|
||||
typedef R type(BOOST_ASIO_VARIADIC_TARGS(n)) && noexcept; \
|
||||
}; \
|
||||
/**/
|
||||
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_REDIRECT_ERROR_DEF)
|
||||
#undef BOOST_ASIO_PRIVATE_REDIRECT_ERROR_DEF
|
||||
|
||||
# endif // defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
|
||||
# endif // defined(BOOST_ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
|
||||
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
} // namespace detail
|
||||
@@ -225,29 +474,26 @@ struct redirect_error_signature<R(const boost::system::error_code&)>
|
||||
|
||||
template <typename CompletionToken, typename Signature>
|
||||
struct async_result<redirect_error_t<CompletionToken>, Signature>
|
||||
: async_result<CompletionToken,
|
||||
typename detail::redirect_error_signature<Signature>::type>
|
||||
{
|
||||
typedef typename async_result<CompletionToken,
|
||||
typename detail::redirect_error_signature<Signature>::type>
|
||||
::return_type return_type;
|
||||
|
||||
template <typename Initiation>
|
||||
struct init_wrapper
|
||||
{
|
||||
template <typename Init>
|
||||
init_wrapper(boost::system::error_code& ec, BOOST_ASIO_MOVE_ARG(Init) init)
|
||||
: ec_(ec),
|
||||
initiation_(BOOST_ASIO_MOVE_CAST(Init)(init))
|
||||
explicit init_wrapper(boost::system::error_code& ec)
|
||||
: ec_(ec)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
template <typename Handler, typename... Args>
|
||||
template <typename Handler, typename Initiation, typename... Args>
|
||||
void operator()(
|
||||
BOOST_ASIO_MOVE_ARG(Handler) handler,
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args) const
|
||||
{
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)(
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
|
||||
detail::redirect_error_handler<
|
||||
typename decay<Handler>::type>(
|
||||
ec_, BOOST_ASIO_MOVE_CAST(Handler)(handler)),
|
||||
@@ -256,23 +502,26 @@ struct async_result<redirect_error_t<CompletionToken>, Signature>
|
||||
|
||||
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
template <typename Handler>
|
||||
template <typename Handler, typename Initiation>
|
||||
void operator()(
|
||||
BOOST_ASIO_MOVE_ARG(Handler) handler)
|
||||
BOOST_ASIO_MOVE_ARG(Handler) handler,
|
||||
BOOST_ASIO_MOVE_ARG(Initiation) initiation) const
|
||||
{
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)(
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
|
||||
detail::redirect_error_handler<
|
||||
typename decay<Handler>::type>(
|
||||
ec_, BOOST_ASIO_MOVE_CAST(Handler)(handler)));
|
||||
}
|
||||
|
||||
#define BOOST_ASIO_PRIVATE_INIT_WRAPPER_DEF(n) \
|
||||
template <typename Handler, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
template <typename Handler, typename Initiation, \
|
||||
BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
void operator()( \
|
||||
BOOST_ASIO_MOVE_ARG(Handler) handler, \
|
||||
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||
BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
|
||||
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \
|
||||
{ \
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)( \
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( \
|
||||
detail::redirect_error_handler< \
|
||||
typename decay<Handler>::type>( \
|
||||
ec_, BOOST_ASIO_MOVE_CAST(Handler)(handler)), \
|
||||
@@ -285,51 +534,67 @@ struct async_result<redirect_error_t<CompletionToken>, Signature>
|
||||
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
boost::system::error_code& ec_;
|
||||
Initiation initiation_;
|
||||
};
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
template <typename Initiation, typename RawCompletionToken, typename... Args>
|
||||
static return_type initiate(
|
||||
static BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken,
|
||||
typename detail::redirect_error_signature<Signature>::type,
|
||||
(async_initiate<CompletionToken,
|
||||
typename detail::redirect_error_signature<Signature>::type>(
|
||||
declval<init_wrapper>(), declval<CompletionToken&>(),
|
||||
declval<Initiation>(), declval<BOOST_ASIO_MOVE_ARG(Args)>()...)))
|
||||
initiate(
|
||||
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
return async_initiate<CompletionToken,
|
||||
typename detail::redirect_error_signature<Signature>::type>(
|
||||
init_wrapper<typename decay<Initiation>::type>(
|
||||
token.ec_, BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
|
||||
token.token_, BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
init_wrapper(token.ec_), token.token_,
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation),
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
|
||||
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
template <typename Initiation, typename RawCompletionToken>
|
||||
static return_type initiate(
|
||||
static BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken,
|
||||
typename detail::redirect_error_signature<Signature>::type,
|
||||
(async_initiate<CompletionToken,
|
||||
typename detail::redirect_error_signature<Signature>::type>(
|
||||
declval<init_wrapper>(), declval<CompletionToken&>(),
|
||||
declval<Initiation>())))
|
||||
initiate(
|
||||
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token)
|
||||
{
|
||||
return async_initiate<CompletionToken,
|
||||
typename detail::redirect_error_signature<Signature>::type>(
|
||||
init_wrapper<typename decay<Initiation>::type>(
|
||||
token.ec_, BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
|
||||
token.token_);
|
||||
init_wrapper(token.ec_), token.token_,
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation));
|
||||
}
|
||||
|
||||
#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
|
||||
template <typename Initiation, typename RawCompletionToken, \
|
||||
BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
static return_type initiate( \
|
||||
static BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, \
|
||||
typename detail::redirect_error_signature<Signature>::type, \
|
||||
(async_initiate<CompletionToken, \
|
||||
typename detail::redirect_error_signature<Signature>::type>( \
|
||||
declval<init_wrapper>(), declval<CompletionToken&>(), \
|
||||
declval<Initiation>(), BOOST_ASIO_VARIADIC_DECLVAL(n)))) \
|
||||
initiate( \
|
||||
BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
|
||||
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token, \
|
||||
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||
{ \
|
||||
return async_initiate<CompletionToken, \
|
||||
typename detail::redirect_error_signature<Signature>::type>( \
|
||||
init_wrapper<typename decay<Initiation>::type>( \
|
||||
token.ec_, BOOST_ASIO_MOVE_CAST(Initiation)(initiation)), \
|
||||
token.token_, BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||
init_wrapper(token.ec_), token.token_, \
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation), \
|
||||
BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||
} \
|
||||
/**/
|
||||
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF)
|
||||
@@ -338,29 +603,26 @@ struct async_result<redirect_error_t<CompletionToken>, Signature>
|
||||
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
};
|
||||
|
||||
template <typename Handler, typename Executor>
|
||||
struct associated_executor<detail::redirect_error_handler<Handler>, Executor>
|
||||
template <template <typename, typename> class Associator,
|
||||
typename Handler, typename DefaultCandidate>
|
||||
struct associator<Associator,
|
||||
detail::redirect_error_handler<Handler>, DefaultCandidate>
|
||||
: Associator<Handler, DefaultCandidate>
|
||||
{
|
||||
typedef typename associated_executor<Handler, Executor>::type type;
|
||||
|
||||
static type get(
|
||||
const detail::redirect_error_handler<Handler>& h,
|
||||
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
|
||||
static typename Associator<Handler, DefaultCandidate>::type
|
||||
get(const detail::redirect_error_handler<Handler>& h) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_executor<Handler, Executor>::get(h.handler_, ex);
|
||||
return Associator<Handler, DefaultCandidate>::get(h.handler_);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Handler, typename Allocator>
|
||||
struct associated_allocator<detail::redirect_error_handler<Handler>, Allocator>
|
||||
{
|
||||
typedef typename associated_allocator<Handler, Allocator>::type type;
|
||||
|
||||
static type get(
|
||||
const detail::redirect_error_handler<Handler>& h,
|
||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
||||
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
|
||||
typename Associator<Handler, DefaultCandidate>::type)
|
||||
get(const detail::redirect_error_handler<Handler>& h,
|
||||
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
|
||||
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
|
||||
Associator<Handler, DefaultCandidate>::get(h.handler_, c)))
|
||||
{
|
||||
return associated_allocator<Handler, Allocator>::get(h.handler_, a);
|
||||
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/serial_port_base.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/serial_port_base.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
// impl/src.hpp
|
||||
// ~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -19,11 +19,16 @@
|
||||
# error Do not compile Asio library source with BOOST_ASIO_HEADER_ONLY defined
|
||||
#endif
|
||||
|
||||
#include <boost/asio/impl/any_completion_executor.ipp>
|
||||
#include <boost/asio/impl/any_io_executor.ipp>
|
||||
#include <boost/asio/impl/cancellation_signal.ipp>
|
||||
#include <boost/asio/impl/connect_pipe.ipp>
|
||||
#include <boost/asio/impl/error.ipp>
|
||||
#include <boost/asio/impl/execution_context.ipp>
|
||||
#include <boost/asio/impl/executor.ipp>
|
||||
#include <boost/asio/impl/handler_alloc_hook.ipp>
|
||||
#include <boost/asio/impl/io_context.ipp>
|
||||
#include <boost/asio/impl/multiple_exceptions.ipp>
|
||||
#include <boost/asio/impl/serial_port_base.ipp>
|
||||
#include <boost/asio/impl/system_context.ipp>
|
||||
#include <boost/asio/impl/thread_pool.ipp>
|
||||
@@ -33,15 +38,19 @@
|
||||
#include <boost/asio/detail/impl/epoll_reactor.ipp>
|
||||
#include <boost/asio/detail/impl/eventfd_select_interrupter.ipp>
|
||||
#include <boost/asio/detail/impl/handler_tracking.ipp>
|
||||
#include <boost/asio/detail/impl/io_uring_descriptor_service.ipp>
|
||||
#include <boost/asio/detail/impl/io_uring_file_service.ipp>
|
||||
#include <boost/asio/detail/impl/io_uring_socket_service_base.ipp>
|
||||
#include <boost/asio/detail/impl/io_uring_service.ipp>
|
||||
#include <boost/asio/detail/impl/kqueue_reactor.ipp>
|
||||
#include <boost/asio/detail/impl/null_event.ipp>
|
||||
#include <boost/asio/detail/impl/pipe_select_interrupter.ipp>
|
||||
#include <boost/asio/detail/impl/posix_event.ipp>
|
||||
#include <boost/asio/detail/impl/posix_mutex.ipp>
|
||||
#include <boost/asio/detail/impl/posix_serial_port_service.ipp>
|
||||
#include <boost/asio/detail/impl/posix_thread.ipp>
|
||||
#include <boost/asio/detail/impl/posix_tss_ptr.ipp>
|
||||
#include <boost/asio/detail/impl/reactive_descriptor_service.ipp>
|
||||
#include <boost/asio/detail/impl/reactive_serial_port_service.ipp>
|
||||
#include <boost/asio/detail/impl/reactive_socket_service_base.ipp>
|
||||
#include <boost/asio/detail/impl/resolver_service_base.ipp>
|
||||
#include <boost/asio/detail/impl/scheduler.ipp>
|
||||
@@ -52,9 +61,11 @@
|
||||
#include <boost/asio/detail/impl/socket_select_interrupter.ipp>
|
||||
#include <boost/asio/detail/impl/strand_executor_service.ipp>
|
||||
#include <boost/asio/detail/impl/strand_service.ipp>
|
||||
#include <boost/asio/detail/impl/thread_context.ipp>
|
||||
#include <boost/asio/detail/impl/throw_error.ipp>
|
||||
#include <boost/asio/detail/impl/timer_queue_ptime.ipp>
|
||||
#include <boost/asio/detail/impl/timer_queue_set.ipp>
|
||||
#include <boost/asio/detail/impl/win_iocp_file_service.ipp>
|
||||
#include <boost/asio/detail/impl/win_iocp_handle_service.ipp>
|
||||
#include <boost/asio/detail/impl/win_iocp_io_context.ipp>
|
||||
#include <boost/asio/detail/impl/win_iocp_serial_port_service.ipp>
|
||||
@@ -68,6 +79,9 @@
|
||||
#include <boost/asio/detail/impl/winrt_ssocket_service_base.ipp>
|
||||
#include <boost/asio/detail/impl/winrt_timer_scheduler.ipp>
|
||||
#include <boost/asio/detail/impl/winsock_init.ipp>
|
||||
#include <boost/asio/execution/impl/bad_executor.ipp>
|
||||
#include <boost/asio/execution/impl/receiver_invocation_error.ipp>
|
||||
#include <boost/asio/experimental/impl/channel_error.ipp>
|
||||
#include <boost/asio/generic/detail/impl/endpoint.ipp>
|
||||
#include <boost/asio/ip/impl/address.ipp>
|
||||
#include <boost/asio/ip/impl/address_v4.ipp>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/system_context.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/system_context.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -29,8 +29,19 @@ struct system_context::thread_function
|
||||
|
||||
void operator()()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
scheduler_->run(ec);
|
||||
#if !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
try
|
||||
{
|
||||
#endif// !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
boost::system::error_code ec;
|
||||
scheduler_->run(ec);
|
||||
#if !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::terminate();
|
||||
}
|
||||
#endif// !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -40,8 +51,9 @@ system_context::system_context()
|
||||
scheduler_.work_started();
|
||||
|
||||
thread_function f = { &scheduler_ };
|
||||
std::size_t num_threads = detail::thread::hardware_concurrency() * 2;
|
||||
threads_.create_threads(f, num_threads ? num_threads : 2);
|
||||
num_threads_ = detail::thread::hardware_concurrency() * 2;
|
||||
num_threads_ = num_threads_ ? num_threads_ : 2;
|
||||
threads_.create_threads(f, num_threads_);
|
||||
}
|
||||
|
||||
system_context::~system_context()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/system_executor.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
#include <boost/asio/detail/executor_op.hpp>
|
||||
#include <boost/asio/detail/global.hpp>
|
||||
#include <boost/asio/detail/recycling_allocator.hpp>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
#include <boost/asio/system_context.hpp>
|
||||
|
||||
@@ -26,29 +25,128 @@
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
inline system_context& system_executor::context() const BOOST_ASIO_NOEXCEPT
|
||||
template <typename Blocking, typename Relationship, typename Allocator>
|
||||
inline system_context&
|
||||
basic_system_executor<Blocking, Relationship, Allocator>::query(
|
||||
execution::context_t) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return detail::global<system_context>();
|
||||
}
|
||||
|
||||
template <typename Function, typename Allocator>
|
||||
void system_executor::dispatch(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, const Allocator&) const
|
||||
template <typename Blocking, typename Relationship, typename Allocator>
|
||||
inline std::size_t
|
||||
basic_system_executor<Blocking, Relationship, Allocator>::query(
|
||||
execution::occupancy_t) const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return detail::global<system_context>().num_threads_;
|
||||
}
|
||||
|
||||
template <typename Blocking, typename Relationship, typename Allocator>
|
||||
template <typename Function>
|
||||
inline void
|
||||
basic_system_executor<Blocking, Relationship, Allocator>::do_execute(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, execution::blocking_t::possibly_t) const
|
||||
{
|
||||
// Obtain a non-const instance of the function.
|
||||
detail::non_const_lvalue<Function> f2(f);
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
try
|
||||
{
|
||||
#endif// !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
detail::fenced_block b(detail::fenced_block::full);
|
||||
boost_asio_handler_invoke_helpers::invoke(f2.value, f2.value);
|
||||
#if !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::terminate();
|
||||
}
|
||||
#endif// !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
}
|
||||
|
||||
template <typename Blocking, typename Relationship, typename Allocator>
|
||||
template <typename Function>
|
||||
inline void
|
||||
basic_system_executor<Blocking, Relationship, Allocator>::do_execute(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, execution::blocking_t::always_t) const
|
||||
{
|
||||
// Obtain a non-const instance of the function.
|
||||
detail::non_const_lvalue<Function> f2(f);
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
try
|
||||
{
|
||||
#endif// !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
detail::fenced_block b(detail::fenced_block::full);
|
||||
boost_asio_handler_invoke_helpers::invoke(f2.value, f2.value);
|
||||
#if !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::terminate();
|
||||
}
|
||||
#endif// !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
}
|
||||
|
||||
template <typename Blocking, typename Relationship, typename Allocator>
|
||||
template <typename Function>
|
||||
void basic_system_executor<Blocking, Relationship, Allocator>::do_execute(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, execution::blocking_t::never_t) const
|
||||
{
|
||||
system_context& ctx = detail::global<system_context>();
|
||||
|
||||
// Allocate and construct an operation to wrap the function.
|
||||
typedef typename decay<Function>::type function_type;
|
||||
typedef detail::executor_op<function_type, Allocator> op;
|
||||
typename op::ptr p = { detail::addressof(allocator_),
|
||||
op::ptr::allocate(allocator_), 0 };
|
||||
p.p = new (p.v) op(BOOST_ASIO_MOVE_CAST(Function)(f), allocator_);
|
||||
|
||||
if (is_same<Relationship, execution::relationship_t::continuation_t>::value)
|
||||
{
|
||||
BOOST_ASIO_HANDLER_CREATION((ctx, *p.p,
|
||||
"system_executor", &ctx, 0, "execute(blk=never,rel=cont)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASIO_HANDLER_CREATION((ctx, *p.p,
|
||||
"system_executor", &ctx, 0, "execute(blk=never,rel=fork)"));
|
||||
}
|
||||
|
||||
ctx.scheduler_.post_immediate_completion(p.p,
|
||||
is_same<Relationship, execution::relationship_t::continuation_t>::value);
|
||||
p.v = p.p = 0;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
||||
template <typename Blocking, typename Relationship, typename Allocator>
|
||||
inline system_context& basic_system_executor<
|
||||
Blocking, Relationship, Allocator>::context() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return detail::global<system_context>();
|
||||
}
|
||||
|
||||
template <typename Blocking, typename Relationship, typename Allocator>
|
||||
template <typename Function, typename OtherAllocator>
|
||||
void basic_system_executor<Blocking, Relationship, Allocator>::dispatch(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, const OtherAllocator&) const
|
||||
{
|
||||
typename decay<Function>::type tmp(BOOST_ASIO_MOVE_CAST(Function)(f));
|
||||
boost_asio_handler_invoke_helpers::invoke(tmp, tmp);
|
||||
}
|
||||
|
||||
template <typename Function, typename Allocator>
|
||||
void system_executor::post(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, const Allocator& a) const
|
||||
template <typename Blocking, typename Relationship, typename Allocator>
|
||||
template <typename Function, typename OtherAllocator>
|
||||
void basic_system_executor<Blocking, Relationship, Allocator>::post(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const
|
||||
{
|
||||
typedef typename decay<Function>::type function_type;
|
||||
|
||||
system_context& ctx = detail::global<system_context>();
|
||||
|
||||
// Allocate and construct an operation to wrap the function.
|
||||
typedef detail::executor_op<function_type, Allocator> op;
|
||||
typedef detail::executor_op<function_type, OtherAllocator> op;
|
||||
typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };
|
||||
p.p = new (p.v) op(BOOST_ASIO_MOVE_CAST(Function)(f), a);
|
||||
|
||||
@@ -59,16 +157,17 @@ void system_executor::post(
|
||||
p.v = p.p = 0;
|
||||
}
|
||||
|
||||
template <typename Function, typename Allocator>
|
||||
void system_executor::defer(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, const Allocator& a) const
|
||||
template <typename Blocking, typename Relationship, typename Allocator>
|
||||
template <typename Function, typename OtherAllocator>
|
||||
void basic_system_executor<Blocking, Relationship, Allocator>::defer(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const
|
||||
{
|
||||
typedef typename decay<Function>::type function_type;
|
||||
|
||||
system_context& ctx = detail::global<system_context>();
|
||||
|
||||
// Allocate and construct an operation to wrap the function.
|
||||
typedef detail::executor_op<function_type, Allocator> op;
|
||||
typedef detail::executor_op<function_type, OtherAllocator> op;
|
||||
typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };
|
||||
p.p = new (p.v) op(BOOST_ASIO_MOVE_CAST(Function)(f), a);
|
||||
|
||||
@@ -78,6 +177,7 @@ void system_executor::defer(
|
||||
ctx.scheduler_.post_immediate_completion(p.p, true);
|
||||
p.v = p.p = 0;
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/thread_pool.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -15,9 +15,11 @@
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/blocking_executor_op.hpp>
|
||||
#include <boost/asio/detail/bulk_executor_op.hpp>
|
||||
#include <boost/asio/detail/executor_op.hpp>
|
||||
#include <boost/asio/detail/fenced_block.hpp>
|
||||
#include <boost/asio/detail/recycling_allocator.hpp>
|
||||
#include <boost/asio/detail/non_const_lvalue.hpp>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
#include <boost/asio/execution_context.hpp>
|
||||
|
||||
@@ -32,32 +34,260 @@ thread_pool::get_executor() BOOST_ASIO_NOEXCEPT
|
||||
return executor_type(*this);
|
||||
}
|
||||
|
||||
inline thread_pool&
|
||||
thread_pool::executor_type::context() const BOOST_ASIO_NOEXCEPT
|
||||
inline thread_pool::executor_type
|
||||
thread_pool::executor() BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return pool_;
|
||||
return executor_type(*this);
|
||||
}
|
||||
|
||||
inline void
|
||||
thread_pool::executor_type::on_work_started() const BOOST_ASIO_NOEXCEPT
|
||||
inline thread_pool::scheduler_type
|
||||
thread_pool::scheduler() BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
pool_.scheduler_.work_started();
|
||||
return scheduler_type(*this);
|
||||
}
|
||||
|
||||
inline void thread_pool::executor_type::on_work_finished()
|
||||
const BOOST_ASIO_NOEXCEPT
|
||||
template <typename Allocator, unsigned int Bits>
|
||||
thread_pool::basic_executor_type<Allocator, Bits>&
|
||||
thread_pool::basic_executor_type<Allocator, Bits>::operator=(
|
||||
const basic_executor_type& other) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
pool_.scheduler_.work_finished();
|
||||
if (this != &other)
|
||||
{
|
||||
thread_pool* old_thread_pool = pool_;
|
||||
pool_ = other.pool_;
|
||||
allocator_ = other.allocator_;
|
||||
bits_ = other.bits_;
|
||||
if (Bits & outstanding_work_tracked)
|
||||
{
|
||||
if (pool_)
|
||||
pool_->scheduler_.work_started();
|
||||
if (old_thread_pool)
|
||||
old_thread_pool->scheduler_.work_finished();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Function, typename Allocator>
|
||||
void thread_pool::executor_type::dispatch(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, const Allocator& a) const
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
template <typename Allocator, unsigned int Bits>
|
||||
thread_pool::basic_executor_type<Allocator, Bits>&
|
||||
thread_pool::basic_executor_type<Allocator, Bits>::operator=(
|
||||
basic_executor_type&& other) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
thread_pool* old_thread_pool = pool_;
|
||||
pool_ = other.pool_;
|
||||
allocator_ = std::move(other.allocator_);
|
||||
bits_ = other.bits_;
|
||||
if (Bits & outstanding_work_tracked)
|
||||
{
|
||||
other.pool_ = 0;
|
||||
if (old_thread_pool)
|
||||
old_thread_pool->scheduler_.work_finished();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
template <typename Allocator, unsigned int Bits>
|
||||
inline bool thread_pool::basic_executor_type<Allocator,
|
||||
Bits>::running_in_this_thread() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return pool_->scheduler_.can_dispatch();
|
||||
}
|
||||
|
||||
template <typename Allocator, unsigned int Bits>
|
||||
template <typename Function>
|
||||
void thread_pool::basic_executor_type<Allocator,
|
||||
Bits>::do_execute(BOOST_ASIO_MOVE_ARG(Function) f, false_type) const
|
||||
{
|
||||
typedef typename decay<Function>::type function_type;
|
||||
|
||||
// Invoke immediately if the blocking.possibly property is enabled and we are
|
||||
// already inside the thread pool.
|
||||
if ((bits_ & blocking_never) == 0 && pool_->scheduler_.can_dispatch())
|
||||
{
|
||||
// Make a local, non-const copy of the function.
|
||||
function_type tmp(BOOST_ASIO_MOVE_CAST(Function)(f));
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_STD_EXCEPTION_PTR) \
|
||||
&& !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
try
|
||||
{
|
||||
#endif // defined(BOOST_ASIO_HAS_STD_EXCEPTION_PTR)
|
||||
// && !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
detail::fenced_block b(detail::fenced_block::full);
|
||||
boost_asio_handler_invoke_helpers::invoke(tmp, tmp);
|
||||
return;
|
||||
#if defined(BOOST_ASIO_HAS_STD_EXCEPTION_PTR) \
|
||||
&& !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
pool_->scheduler_.capture_current_exception();
|
||||
return;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_STD_EXCEPTION_PTR)
|
||||
// && !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
}
|
||||
|
||||
// Allocate and construct an operation to wrap the function.
|
||||
typedef detail::executor_op<function_type, Allocator> op;
|
||||
typename op::ptr p = { detail::addressof(allocator_),
|
||||
op::ptr::allocate(allocator_), 0 };
|
||||
p.p = new (p.v) op(BOOST_ASIO_MOVE_CAST(Function)(f), allocator_);
|
||||
|
||||
if ((bits_ & relationship_continuation) != 0)
|
||||
{
|
||||
BOOST_ASIO_HANDLER_CREATION((*pool_, *p.p,
|
||||
"thread_pool", pool_, 0, "execute(blk=never,rel=cont)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASIO_HANDLER_CREATION((*pool_, *p.p,
|
||||
"thread_pool", pool_, 0, "execute(blk=never,rel=fork)"));
|
||||
}
|
||||
|
||||
pool_->scheduler_.post_immediate_completion(p.p,
|
||||
(bits_ & relationship_continuation) != 0);
|
||||
p.v = p.p = 0;
|
||||
}
|
||||
|
||||
template <typename Allocator, unsigned int Bits>
|
||||
template <typename Function>
|
||||
void thread_pool::basic_executor_type<Allocator,
|
||||
Bits>::do_execute(BOOST_ASIO_MOVE_ARG(Function) f, true_type) const
|
||||
{
|
||||
// Obtain a non-const instance of the function.
|
||||
detail::non_const_lvalue<Function> f2(f);
|
||||
|
||||
// Invoke immediately if we are already inside the thread pool.
|
||||
if (pool_->scheduler_.can_dispatch())
|
||||
{
|
||||
#if !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
try
|
||||
{
|
||||
#endif // !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
detail::fenced_block b(detail::fenced_block::full);
|
||||
boost_asio_handler_invoke_helpers::invoke(f2.value, f2.value);
|
||||
return;
|
||||
#if !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::terminate();
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
}
|
||||
|
||||
// Construct an operation to wrap the function.
|
||||
typedef typename decay<Function>::type function_type;
|
||||
detail::blocking_executor_op<function_type> op(f2.value);
|
||||
|
||||
BOOST_ASIO_HANDLER_CREATION((*pool_, op,
|
||||
"thread_pool", pool_, 0, "execute(blk=always)"));
|
||||
|
||||
pool_->scheduler_.post_immediate_completion(&op, false);
|
||||
op.wait();
|
||||
}
|
||||
|
||||
template <typename Allocator, unsigned int Bits>
|
||||
template <typename Function>
|
||||
void thread_pool::basic_executor_type<Allocator, Bits>::do_bulk_execute(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, std::size_t n, false_type) const
|
||||
{
|
||||
typedef typename decay<Function>::type function_type;
|
||||
typedef detail::bulk_executor_op<function_type, Allocator> op;
|
||||
|
||||
// Allocate and construct operations to wrap the function.
|
||||
detail::op_queue<detail::scheduler_operation> ops;
|
||||
for (std::size_t i = 0; i < n; ++i)
|
||||
{
|
||||
typename op::ptr p = { detail::addressof(allocator_),
|
||||
op::ptr::allocate(allocator_), 0 };
|
||||
p.p = new (p.v) op(BOOST_ASIO_MOVE_CAST(Function)(f), allocator_, i);
|
||||
ops.push(p.p);
|
||||
|
||||
if ((bits_ & relationship_continuation) != 0)
|
||||
{
|
||||
BOOST_ASIO_HANDLER_CREATION((*pool_, *p.p,
|
||||
"thread_pool", pool_, 0, "bulk_execute(blk=never,rel=cont)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASIO_HANDLER_CREATION((*pool_, *p.p,
|
||||
"thread_pool", pool_, 0, "bulk)execute(blk=never,rel=fork)"));
|
||||
}
|
||||
|
||||
p.v = p.p = 0;
|
||||
}
|
||||
|
||||
pool_->scheduler_.post_immediate_completions(n,
|
||||
ops, (bits_ & relationship_continuation) != 0);
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
struct thread_pool_always_blocking_function_adapter
|
||||
{
|
||||
typename decay<Function>::type* f;
|
||||
std::size_t n;
|
||||
|
||||
void operator()()
|
||||
{
|
||||
for (std::size_t i = 0; i < n; ++i)
|
||||
{
|
||||
(*f)(i);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Allocator, unsigned int Bits>
|
||||
template <typename Function>
|
||||
void thread_pool::basic_executor_type<Allocator, Bits>::do_bulk_execute(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, std::size_t n, true_type) const
|
||||
{
|
||||
// Obtain a non-const instance of the function.
|
||||
detail::non_const_lvalue<Function> f2(f);
|
||||
|
||||
thread_pool_always_blocking_function_adapter<Function>
|
||||
adapter = { detail::addressof(f2.value), n };
|
||||
|
||||
this->do_execute(adapter, true_type());
|
||||
}
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
||||
template <typename Allocator, unsigned int Bits>
|
||||
inline thread_pool& thread_pool::basic_executor_type<
|
||||
Allocator, Bits>::context() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return *pool_;
|
||||
}
|
||||
|
||||
template <typename Allocator, unsigned int Bits>
|
||||
inline void thread_pool::basic_executor_type<Allocator,
|
||||
Bits>::on_work_started() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
pool_->scheduler_.work_started();
|
||||
}
|
||||
|
||||
template <typename Allocator, unsigned int Bits>
|
||||
inline void thread_pool::basic_executor_type<Allocator,
|
||||
Bits>::on_work_finished() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
pool_->scheduler_.work_finished();
|
||||
}
|
||||
|
||||
template <typename Allocator, unsigned int Bits>
|
||||
template <typename Function, typename OtherAllocator>
|
||||
void thread_pool::basic_executor_type<Allocator, Bits>::dispatch(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const
|
||||
{
|
||||
typedef typename decay<Function>::type function_type;
|
||||
|
||||
// Invoke immediately if we are already inside the thread pool.
|
||||
if (pool_.scheduler_.can_dispatch())
|
||||
if (pool_->scheduler_.can_dispatch())
|
||||
{
|
||||
// Make a local, non-const copy of the function.
|
||||
function_type tmp(BOOST_ASIO_MOVE_CAST(Function)(f));
|
||||
@@ -68,58 +298,55 @@ void thread_pool::executor_type::dispatch(
|
||||
}
|
||||
|
||||
// Allocate and construct an operation to wrap the function.
|
||||
typedef detail::executor_op<function_type, Allocator> op;
|
||||
typedef detail::executor_op<function_type, OtherAllocator> op;
|
||||
typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };
|
||||
p.p = new (p.v) op(BOOST_ASIO_MOVE_CAST(Function)(f), a);
|
||||
|
||||
BOOST_ASIO_HANDLER_CREATION((pool_, *p.p,
|
||||
"thread_pool", &this->context(), 0, "dispatch"));
|
||||
BOOST_ASIO_HANDLER_CREATION((*pool_, *p.p,
|
||||
"thread_pool", pool_, 0, "dispatch"));
|
||||
|
||||
pool_.scheduler_.post_immediate_completion(p.p, false);
|
||||
pool_->scheduler_.post_immediate_completion(p.p, false);
|
||||
p.v = p.p = 0;
|
||||
}
|
||||
|
||||
template <typename Function, typename Allocator>
|
||||
void thread_pool::executor_type::post(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, const Allocator& a) const
|
||||
template <typename Allocator, unsigned int Bits>
|
||||
template <typename Function, typename OtherAllocator>
|
||||
void thread_pool::basic_executor_type<Allocator, Bits>::post(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const
|
||||
{
|
||||
typedef typename decay<Function>::type function_type;
|
||||
|
||||
// Allocate and construct an operation to wrap the function.
|
||||
typedef detail::executor_op<function_type, Allocator> op;
|
||||
typedef detail::executor_op<function_type, OtherAllocator> op;
|
||||
typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };
|
||||
p.p = new (p.v) op(BOOST_ASIO_MOVE_CAST(Function)(f), a);
|
||||
|
||||
BOOST_ASIO_HANDLER_CREATION((pool_, *p.p,
|
||||
"thread_pool", &this->context(), 0, "post"));
|
||||
BOOST_ASIO_HANDLER_CREATION((*pool_, *p.p,
|
||||
"thread_pool", pool_, 0, "post"));
|
||||
|
||||
pool_.scheduler_.post_immediate_completion(p.p, false);
|
||||
pool_->scheduler_.post_immediate_completion(p.p, false);
|
||||
p.v = p.p = 0;
|
||||
}
|
||||
|
||||
template <typename Function, typename Allocator>
|
||||
void thread_pool::executor_type::defer(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, const Allocator& a) const
|
||||
template <typename Allocator, unsigned int Bits>
|
||||
template <typename Function, typename OtherAllocator>
|
||||
void thread_pool::basic_executor_type<Allocator, Bits>::defer(
|
||||
BOOST_ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const
|
||||
{
|
||||
typedef typename decay<Function>::type function_type;
|
||||
|
||||
// Allocate and construct an operation to wrap the function.
|
||||
typedef detail::executor_op<function_type, Allocator> op;
|
||||
typedef detail::executor_op<function_type, OtherAllocator> op;
|
||||
typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };
|
||||
p.p = new (p.v) op(BOOST_ASIO_MOVE_CAST(Function)(f), a);
|
||||
|
||||
BOOST_ASIO_HANDLER_CREATION((pool_, *p.p,
|
||||
"thread_pool", &this->context(), 0, "defer"));
|
||||
BOOST_ASIO_HANDLER_CREATION((*pool_, *p.p,
|
||||
"thread_pool", pool_, 0, "defer"));
|
||||
|
||||
pool_.scheduler_.post_immediate_completion(p.p, true);
|
||||
pool_->scheduler_.post_immediate_completion(p.p, true);
|
||||
p.v = p.p = 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
thread_pool::executor_type::running_in_this_thread() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return pool_.scheduler_.can_dispatch();
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/thread_pool.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -16,7 +16,9 @@
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <stdexcept>
|
||||
#include <boost/asio/thread_pool.hpp>
|
||||
#include <boost/asio/detail/throw_exception.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
@@ -29,35 +31,75 @@ struct thread_pool::thread_function
|
||||
|
||||
void operator()()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
scheduler_->run(ec);
|
||||
#if !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
try
|
||||
{
|
||||
#endif// !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
boost::system::error_code ec;
|
||||
scheduler_->run(ec);
|
||||
#if !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::terminate();
|
||||
}
|
||||
#endif// !defined(BOOST_ASIO_NO_EXCEPTIONS)
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
||||
namespace detail {
|
||||
|
||||
inline long default_thread_pool_size()
|
||||
{
|
||||
std::size_t num_threads = thread::hardware_concurrency() * 2;
|
||||
num_threads = num_threads == 0 ? 2 : num_threads;
|
||||
return static_cast<long>(num_threads);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
thread_pool::thread_pool()
|
||||
: scheduler_(add_scheduler(new detail::scheduler(*this, 0, false)))
|
||||
: scheduler_(add_scheduler(new detail::scheduler(*this, 0, false))),
|
||||
num_threads_(detail::default_thread_pool_size())
|
||||
{
|
||||
scheduler_.work_started();
|
||||
|
||||
thread_function f = { &scheduler_ };
|
||||
std::size_t num_threads = detail::thread::hardware_concurrency() * 2;
|
||||
threads_.create_threads(f, num_threads ? num_threads : 2);
|
||||
threads_.create_threads(f, static_cast<std::size_t>(num_threads_));
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
||||
|
||||
namespace detail {
|
||||
|
||||
inline long clamp_thread_pool_size(std::size_t n)
|
||||
{
|
||||
if (n > 0x7FFFFFFF)
|
||||
{
|
||||
std::out_of_range ex("thread pool size");
|
||||
boost::asio::detail::throw_exception(ex);
|
||||
}
|
||||
return static_cast<long>(n & 0x7FFFFFFF);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
thread_pool::thread_pool(std::size_t num_threads)
|
||||
: scheduler_(add_scheduler(new detail::scheduler(
|
||||
*this, num_threads == 1 ? 1 : 0, false)))
|
||||
*this, num_threads == 1 ? 1 : 0, false))),
|
||||
num_threads_(detail::clamp_thread_pool_size(num_threads))
|
||||
{
|
||||
scheduler_.work_started();
|
||||
|
||||
thread_function f = { &scheduler_ };
|
||||
threads_.create_threads(f, num_threads);
|
||||
threads_.create_threads(f, static_cast<std::size_t>(num_threads_));
|
||||
}
|
||||
|
||||
thread_pool::~thread_pool()
|
||||
{
|
||||
stop();
|
||||
join();
|
||||
shutdown();
|
||||
}
|
||||
|
||||
void thread_pool::stop()
|
||||
@@ -65,13 +107,20 @@ void thread_pool::stop()
|
||||
scheduler_.stop();
|
||||
}
|
||||
|
||||
void thread_pool::attach()
|
||||
{
|
||||
++num_threads_;
|
||||
thread_function f = { &scheduler_ };
|
||||
f();
|
||||
}
|
||||
|
||||
void thread_pool::join()
|
||||
{
|
||||
if (!threads_.empty())
|
||||
{
|
||||
if (num_threads_)
|
||||
scheduler_.work_finished();
|
||||
|
||||
if (!threads_.empty())
|
||||
threads_.join();
|
||||
}
|
||||
}
|
||||
|
||||
detail::scheduler& thread_pool::add_scheduler(detail::scheduler* s)
|
||||
@@ -81,6 +130,12 @@ detail::scheduler& thread_pool::add_scheduler(detail::scheduler* s)
|
||||
return *scoped_impl.release();
|
||||
}
|
||||
|
||||
void thread_pool::wait()
|
||||
{
|
||||
scheduler_.work_finished();
|
||||
threads_.join();
|
||||
}
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/use_awaitable.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/cancellation_signal.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
@@ -33,8 +34,9 @@ public:
|
||||
typedef awaitable<T, Executor> awaitable_type;
|
||||
|
||||
// Construct from the entry point of a new thread of execution.
|
||||
awaitable_handler_base(awaitable<void, Executor> a, const Executor& ex)
|
||||
: awaitable_thread<Executor>(std::move(a), ex)
|
||||
awaitable_handler_base(awaitable<awaitable_thread_entry_point, Executor> a,
|
||||
const Executor& ex, cancellation_slot pcs, cancellation_state cs)
|
||||
: awaitable_thread<Executor>(std::move(a), ex, pcs, cs)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -47,7 +49,8 @@ public:
|
||||
protected:
|
||||
awaitable_frame<T, Executor>* frame() noexcept
|
||||
{
|
||||
return static_cast<awaitable_frame<T, Executor>*>(this->top_of_stack_);
|
||||
return static_cast<awaitable_frame<T, Executor>*>(
|
||||
this->entry_point()->top_of_stack_);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -55,7 +58,7 @@ template <typename, typename...>
|
||||
class awaitable_handler;
|
||||
|
||||
template <typename Executor>
|
||||
class awaitable_handler<Executor, void>
|
||||
class awaitable_handler<Executor>
|
||||
: public awaitable_handler_base<Executor, void>
|
||||
{
|
||||
public:
|
||||
@@ -65,6 +68,7 @@ public:
|
||||
{
|
||||
this->frame()->attach_thread(this);
|
||||
this->frame()->return_void();
|
||||
this->frame()->clear_cancellation_slot();
|
||||
this->frame()->pop_frame();
|
||||
this->pump();
|
||||
}
|
||||
@@ -84,6 +88,7 @@ public:
|
||||
this->frame()->set_error(ec);
|
||||
else
|
||||
this->frame()->return_void();
|
||||
this->frame()->clear_cancellation_slot();
|
||||
this->frame()->pop_frame();
|
||||
this->pump();
|
||||
}
|
||||
@@ -103,6 +108,7 @@ public:
|
||||
this->frame()->set_except(ex);
|
||||
else
|
||||
this->frame()->return_void();
|
||||
this->frame()->clear_cancellation_slot();
|
||||
this->frame()->pop_frame();
|
||||
this->pump();
|
||||
}
|
||||
@@ -120,6 +126,7 @@ public:
|
||||
{
|
||||
this->frame()->attach_thread(this);
|
||||
this->frame()->return_value(std::forward<Arg>(arg));
|
||||
this->frame()->clear_cancellation_slot();
|
||||
this->frame()->pop_frame();
|
||||
this->pump();
|
||||
}
|
||||
@@ -140,6 +147,7 @@ public:
|
||||
this->frame()->set_error(ec);
|
||||
else
|
||||
this->frame()->return_value(std::forward<Arg>(arg));
|
||||
this->frame()->clear_cancellation_slot();
|
||||
this->frame()->pop_frame();
|
||||
this->pump();
|
||||
}
|
||||
@@ -160,6 +168,7 @@ public:
|
||||
this->frame()->set_except(ex);
|
||||
else
|
||||
this->frame()->return_value(std::forward<Arg>(arg));
|
||||
this->frame()->clear_cancellation_slot();
|
||||
this->frame()->pop_frame();
|
||||
this->pump();
|
||||
}
|
||||
@@ -178,6 +187,7 @@ public:
|
||||
{
|
||||
this->frame()->attach_thread(this);
|
||||
this->frame()->return_values(std::forward<Args>(args)...);
|
||||
this->frame()->clear_cancellation_slot();
|
||||
this->frame()->pop_frame();
|
||||
this->pump();
|
||||
}
|
||||
@@ -199,6 +209,7 @@ public:
|
||||
this->frame()->set_error(ec);
|
||||
else
|
||||
this->frame()->return_values(std::forward<Args>(args)...);
|
||||
this->frame()->clear_cancellation_slot();
|
||||
this->frame()->pop_frame();
|
||||
this->pump();
|
||||
}
|
||||
@@ -220,6 +231,7 @@ public:
|
||||
this->frame()->set_except(ex);
|
||||
else
|
||||
this->frame()->return_values(std::forward<Args>(args)...);
|
||||
this->frame()->clear_cancellation_slot();
|
||||
this->frame()->pop_frame();
|
||||
this->pump();
|
||||
}
|
||||
@@ -229,6 +241,19 @@ public:
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
template <typename T>
|
||||
T dummy_return()
|
||||
{
|
||||
return std::move(*static_cast<T*>(nullptr));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void dummy_return()
|
||||
{
|
||||
}
|
||||
#endif // defined(_MSC_VER)
|
||||
|
||||
template <typename Executor, typename R, typename... Args>
|
||||
class async_result<use_awaitable_t<Executor>, R(Args...)>
|
||||
{
|
||||
@@ -237,28 +262,28 @@ public:
|
||||
Executor, typename decay<Args>::type...> handler_type;
|
||||
typedef typename handler_type::awaitable_type return_type;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
template <typename T>
|
||||
static T dummy_return()
|
||||
template <typename Initiation, typename... InitArgs>
|
||||
#if defined(__APPLE_CC__) && (__clang_major__ == 13)
|
||||
__attribute__((noinline))
|
||||
#endif // defined(__APPLE_CC__) && (__clang_major__ == 13)
|
||||
static handler_type* do_init(
|
||||
detail::awaitable_frame_base<Executor>* frame, Initiation& initiation,
|
||||
use_awaitable_t<Executor> u, InitArgs&... args)
|
||||
{
|
||||
return std::move(*static_cast<T*>(nullptr));
|
||||
(void)u;
|
||||
BOOST_ASIO_HANDLER_LOCATION((u.file_name_, u.line_, u.function_name_));
|
||||
handler_type handler(frame->detach_thread());
|
||||
std::move(initiation)(std::move(handler), std::move(args)...);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <>
|
||||
static void dummy_return()
|
||||
{
|
||||
}
|
||||
#endif // defined(_MSC_VER)
|
||||
|
||||
template <typename Initiation, typename... InitArgs>
|
||||
static return_type initiate(Initiation initiation,
|
||||
use_awaitable_t<Executor>, InitArgs... args)
|
||||
use_awaitable_t<Executor> u, InitArgs... args)
|
||||
{
|
||||
co_await [&](auto* frame)
|
||||
co_await [&] (auto* frame)
|
||||
{
|
||||
handler_type handler(frame->detach_thread());
|
||||
std::move(initiation)(std::move(handler), std::move(args)...);
|
||||
return static_cast<handler_type*>(nullptr);
|
||||
return do_init(frame, initiation, u, args...);
|
||||
};
|
||||
|
||||
for (;;) {} // Never reached.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/use_future.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -19,7 +19,9 @@
|
||||
#include <tuple>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/detail/memory.hpp>
|
||||
#include <boost/asio/dispatch.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/asio/execution.hpp>
|
||||
#include <boost/asio/packaged_task.hpp>
|
||||
#include <boost/system/system_error.hpp>
|
||||
#include <boost/asio/system_executor.hpp>
|
||||
@@ -201,7 +203,7 @@ private:
|
||||
|
||||
// An executor that adapts the system_executor to capture any exeption thrown
|
||||
// by a submitted function object and save it into a promise.
|
||||
template <typename T>
|
||||
template <typename T, typename Blocking = execution::blocking_t::possibly_t>
|
||||
class promise_executor
|
||||
{
|
||||
public:
|
||||
@@ -210,6 +212,42 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
execution_context& query(execution::context_t) const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return boost::asio::query(system_executor(), execution::context);
|
||||
}
|
||||
|
||||
static BOOST_ASIO_CONSTEXPR Blocking query(execution::blocking_t)
|
||||
{
|
||||
return Blocking();
|
||||
}
|
||||
|
||||
promise_executor<T, execution::blocking_t::possibly_t>
|
||||
require(execution::blocking_t::possibly_t) const
|
||||
{
|
||||
return promise_executor<T, execution::blocking_t::possibly_t>(p_);
|
||||
}
|
||||
|
||||
promise_executor<T, execution::blocking_t::never_t>
|
||||
require(execution::blocking_t::never_t) const
|
||||
{
|
||||
return promise_executor<T, execution::blocking_t::never_t>(p_);
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void execute(BOOST_ASIO_MOVE_ARG(F) f) const
|
||||
{
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
boost::asio::require(system_executor(), Blocking()).execute(
|
||||
promise_invoker<T, F>(p_, BOOST_ASIO_MOVE_CAST(F)(f)));
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
execution::execute(
|
||||
boost::asio::require(system_executor(), Blocking()),
|
||||
promise_invoker<T, F>(p_, BOOST_ASIO_MOVE_CAST(F)(f)));
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
||||
execution_context& context() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return system_executor().context();
|
||||
@@ -237,6 +275,7 @@ public:
|
||||
system_executor().defer(
|
||||
promise_invoker<T, F>(p_, BOOST_ASIO_MOVE_CAST(F)(f)), a);
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
||||
|
||||
friend bool operator==(const promise_executor& a,
|
||||
const promise_executor& b) BOOST_ASIO_NOEXCEPT
|
||||
@@ -578,7 +617,7 @@ class promise_handler_selector<void(std::exception_ptr, Arg...)>
|
||||
: public promise_handler_ex_n< \
|
||||
std::tuple<Arg, BOOST_ASIO_VARIADIC_TARGS(n)> > {}; \
|
||||
/**/
|
||||
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_PROMISE_SELECTOR_DEF)
|
||||
BOOST_ASIO_VARIADIC_GENERATE_5(BOOST_ASIO_PRIVATE_PROMISE_SELECTOR_DEF)
|
||||
#undef BOOST_ASIO_PRIVATE_PROMISE_SELECTOR_DEF
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
@@ -608,13 +647,36 @@ private:
|
||||
Allocator allocator_;
|
||||
};
|
||||
|
||||
template <typename Function>
|
||||
struct promise_function_wrapper
|
||||
{
|
||||
explicit promise_function_wrapper(Function& f)
|
||||
: function_(BOOST_ASIO_MOVE_CAST(Function)(f))
|
||||
{
|
||||
}
|
||||
|
||||
explicit promise_function_wrapper(const Function& f)
|
||||
: function_(f)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
function_();
|
||||
}
|
||||
|
||||
Function function_;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
template <typename Function, typename Signature, typename Allocator>
|
||||
inline void asio_handler_invoke(Function& f,
|
||||
promise_handler<Signature, Allocator>* h)
|
||||
{
|
||||
typename promise_handler<Signature, Allocator>::executor_type
|
||||
ex(h->get_executor());
|
||||
ex.dispatch(BOOST_ASIO_MOVE_CAST(Function)(f), std::allocator<void>());
|
||||
boost::asio::dispatch(ex, promise_function_wrapper<Function>(f));
|
||||
}
|
||||
|
||||
template <typename Function, typename Signature, typename Allocator>
|
||||
@@ -623,9 +685,11 @@ inline void asio_handler_invoke(const Function& f,
|
||||
{
|
||||
typename promise_handler<Signature, Allocator>::executor_type
|
||||
ex(h->get_executor());
|
||||
ex.dispatch(f, std::allocator<void>());
|
||||
boost::asio::dispatch(ex, promise_function_wrapper<Function>(f));
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
// Helper base class for async_result specialisation.
|
||||
template <typename Signature, typename Allocator>
|
||||
class promise_async_result
|
||||
@@ -720,6 +784,8 @@ private:
|
||||
Allocator allocator_;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
template <typename Function,
|
||||
typename Function1, typename Allocator, typename Result>
|
||||
inline void asio_handler_invoke(Function& f,
|
||||
@@ -727,7 +793,7 @@ inline void asio_handler_invoke(Function& f,
|
||||
{
|
||||
typename packaged_handler<Function1, Allocator, Result>::executor_type
|
||||
ex(h->get_executor());
|
||||
ex.dispatch(BOOST_ASIO_MOVE_CAST(Function)(f), std::allocator<void>());
|
||||
boost::asio::dispatch(ex, promise_function_wrapper<Function>(f));
|
||||
}
|
||||
|
||||
template <typename Function,
|
||||
@@ -737,9 +803,11 @@ inline void asio_handler_invoke(const Function& f,
|
||||
{
|
||||
typename packaged_handler<Function1, Allocator, Result>::executor_type
|
||||
ex(h->get_executor());
|
||||
ex.dispatch(f, std::allocator<void>());
|
||||
boost::asio::dispatch(ex, promise_function_wrapper<Function>(f));
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
// Helper base class for async_result specialisation.
|
||||
template <typename Function, typename Allocator, typename Result>
|
||||
class packaged_async_result
|
||||
@@ -879,6 +947,104 @@ public:
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
namespace traits {
|
||||
|
||||
#if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
|
||||
|
||||
template <typename T, typename Blocking>
|
||||
struct equality_comparable<
|
||||
boost::asio::detail::promise_executor<T, Blocking> >
|
||||
{
|
||||
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
|
||||
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
|
||||
|
||||
#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
|
||||
|
||||
template <typename T, typename Blocking, typename Function>
|
||||
struct execute_member<
|
||||
boost::asio::detail::promise_executor<T, Blocking>, Function>
|
||||
{
|
||||
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
|
||||
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
|
||||
typedef void result_type;
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
|
||||
|
||||
#if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
|
||||
|
||||
template <typename T, typename Blocking, typename Property>
|
||||
struct query_static_constexpr_member<
|
||||
boost::asio::detail::promise_executor<T, Blocking>,
|
||||
Property,
|
||||
typename boost::asio::enable_if<
|
||||
boost::asio::is_convertible<
|
||||
Property,
|
||||
boost::asio::execution::blocking_t
|
||||
>::value
|
||||
>::type
|
||||
>
|
||||
{
|
||||
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
|
||||
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
|
||||
typedef Blocking result_type;
|
||||
|
||||
static BOOST_ASIO_CONSTEXPR result_type value() BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return Blocking();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
|
||||
|
||||
#if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
|
||||
|
||||
template <typename T, typename Blocking>
|
||||
struct query_member<
|
||||
boost::asio::detail::promise_executor<T, Blocking>,
|
||||
execution::context_t
|
||||
>
|
||||
{
|
||||
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
|
||||
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
|
||||
typedef boost::asio::system_context& result_type;
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
|
||||
|
||||
#if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
|
||||
|
||||
template <typename T, typename Blocking>
|
||||
struct require_member<
|
||||
boost::asio::detail::promise_executor<T, Blocking>,
|
||||
execution::blocking_t::possibly_t
|
||||
>
|
||||
{
|
||||
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
|
||||
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
|
||||
typedef boost::asio::detail::promise_executor<T,
|
||||
execution::blocking_t::possibly_t> result_type;
|
||||
};
|
||||
|
||||
template <typename T, typename Blocking>
|
||||
struct require_member<
|
||||
boost::asio::detail::promise_executor<T, Blocking>,
|
||||
execution::blocking_t::never_t
|
||||
>
|
||||
{
|
||||
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
|
||||
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
|
||||
typedef boost::asio::detail::promise_executor<T,
|
||||
execution::blocking_t::never_t> result_type;
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
|
||||
|
||||
} // namespace traits
|
||||
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
} // namespace asio
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
// impl/write_at.hpp
|
||||
// ~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 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)
|
||||
@@ -15,11 +15,10 @@
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/associator.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/completion_condition.hpp>
|
||||
#include <boost/asio/detail/array_fwd.hpp>
|
||||
#include <boost/asio/detail/base_from_cancellation_state.hpp>
|
||||
#include <boost/asio/detail/base_from_completion_cond.hpp>
|
||||
#include <boost/asio/detail/bind_handler.hpp>
|
||||
#include <boost/asio/detail/consuming_buffers.hpp>
|
||||
@@ -27,6 +26,7 @@
|
||||
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_cont_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_tracking.hpp>
|
||||
#include <boost/asio/detail/handler_type_requirements.hpp>
|
||||
#include <boost/asio/detail/non_const_lvalue.hpp>
|
||||
#include <boost/asio/detail/throw_error.hpp>
|
||||
@@ -59,7 +59,7 @@ namespace detail
|
||||
else
|
||||
break;
|
||||
}
|
||||
return tmp.total_consumed();;
|
||||
return tmp.total_consumed();
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
@@ -161,14 +161,16 @@ namespace detail
|
||||
typename ConstBufferSequence, typename ConstBufferIterator,
|
||||
typename CompletionCondition, typename WriteHandler>
|
||||
class write_at_op
|
||||
: detail::base_from_completion_cond<CompletionCondition>
|
||||
: public base_from_cancellation_state<WriteHandler>,
|
||||
base_from_completion_cond<CompletionCondition>
|
||||
{
|
||||
public:
|
||||
write_at_op(AsyncRandomAccessWriteDevice& device,
|
||||
uint64_t offset, const ConstBufferSequence& buffers,
|
||||
CompletionCondition& completion_condition, WriteHandler& handler)
|
||||
: detail::base_from_completion_cond<
|
||||
CompletionCondition>(completion_condition),
|
||||
: base_from_cancellation_state<WriteHandler>(
|
||||
handler, enable_partial_cancellation()),
|
||||
base_from_completion_cond<CompletionCondition>(completion_condition),
|
||||
device_(device),
|
||||
offset_(offset),
|
||||
buffers_(buffers),
|
||||
@@ -179,7 +181,8 @@ namespace detail
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
write_at_op(const write_at_op& other)
|
||||
: detail::base_from_completion_cond<CompletionCondition>(other),
|
||||
: base_from_cancellation_state<WriteHandler>(other),
|
||||
base_from_completion_cond<CompletionCondition>(other),
|
||||
device_(other.device_),
|
||||
offset_(other.offset_),
|
||||
buffers_(other.buffers_),
|
||||
@@ -189,8 +192,11 @@ namespace detail
|
||||
}
|
||||
|
||||
write_at_op(write_at_op&& other)
|
||||
: detail::base_from_completion_cond<CompletionCondition>(
|
||||
BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
|
||||
: base_from_cancellation_state<WriteHandler>(
|
||||
BOOST_ASIO_MOVE_CAST(base_from_cancellation_state<
|
||||
WriteHandler>)(other)),
|
||||
base_from_completion_cond<CompletionCondition>(
|
||||
BOOST_ASIO_MOVE_CAST(base_from_completion_cond<
|
||||
CompletionCondition>)(other)),
|
||||
device_(other.device_),
|
||||
offset_(other.offset_),
|
||||
@@ -201,7 +207,7 @@ namespace detail
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
void operator()(const boost::system::error_code& ec,
|
||||
void operator()(boost::system::error_code ec,
|
||||
std::size_t bytes_transferred, int start = 0)
|
||||
{
|
||||
std::size_t max_size;
|
||||
@@ -209,19 +215,31 @@ namespace detail
|
||||
{
|
||||
case 1:
|
||||
max_size = this->check_for_completion(ec, buffers_.total_consumed());
|
||||
do
|
||||
for (;;)
|
||||
{
|
||||
device_.async_write_some_at(
|
||||
offset_ + buffers_.total_consumed(), buffers_.prepare(max_size),
|
||||
BOOST_ASIO_MOVE_CAST(write_at_op)(*this));
|
||||
{
|
||||
BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_write_at"));
|
||||
device_.async_write_some_at(
|
||||
offset_ + buffers_.total_consumed(), buffers_.prepare(max_size),
|
||||
BOOST_ASIO_MOVE_CAST(write_at_op)(*this));
|
||||
}
|
||||
return; default:
|
||||
buffers_.consume(bytes_transferred);
|
||||
if ((!ec && bytes_transferred == 0) || buffers_.empty())
|
||||
break;
|
||||
max_size = this->check_for_completion(ec, buffers_.total_consumed());
|
||||
} while (max_size > 0);
|
||||
if (max_size == 0)
|
||||
break;
|
||||
if (this->cancelled() != cancellation_type::none)
|
||||
{
|
||||
ec = boost::asio::error::operation_aborted;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
handler_(ec, buffers_.total_consumed());
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(
|
||||
static_cast<const boost::system::error_code&>(ec),
|
||||
static_cast<const std::size_t&>(buffers_.total_consumed()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,23 +257,33 @@ namespace detail
|
||||
template <typename AsyncRandomAccessWriteDevice,
|
||||
typename ConstBufferSequence, typename ConstBufferIterator,
|
||||
typename CompletionCondition, typename WriteHandler>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
inline asio_handler_allocate_is_deprecated
|
||||
asio_handler_allocate(std::size_t size,
|
||||
write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
|
||||
ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)
|
||||
{
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
|
||||
return asio_handler_allocate_is_no_longer_used();
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename AsyncRandomAccessWriteDevice,
|
||||
typename ConstBufferSequence, typename ConstBufferIterator,
|
||||
typename CompletionCondition, typename WriteHandler>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
inline asio_handler_deallocate_is_deprecated
|
||||
asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
|
||||
ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_deallocate_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename AsyncRandomAccessWriteDevice,
|
||||
@@ -273,29 +301,37 @@ namespace detail
|
||||
template <typename Function, typename AsyncRandomAccessWriteDevice,
|
||||
typename ConstBufferSequence, typename ConstBufferIterator,
|
||||
typename CompletionCondition, typename WriteHandler>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(Function& function,
|
||||
write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
|
||||
ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Function, typename AsyncRandomAccessWriteDevice,
|
||||
typename ConstBufferSequence, typename ConstBufferIterator,
|
||||
typename CompletionCondition, typename WriteHandler>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(const Function& function,
|
||||
write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
|
||||
ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename AsyncRandomAccessWriteDevice,
|
||||
typename ConstBufferSequence, typename ConstBufferIterator,
|
||||
typename CompletionCondition, typename WriteHandler>
|
||||
inline void start_write_at_buffer_sequence_op(AsyncRandomAccessWriteDevice& d,
|
||||
inline void start_write_at_op(AsyncRandomAccessWriteDevice& d,
|
||||
uint64_t offset, const ConstBufferSequence& buffers,
|
||||
const ConstBufferIterator&, CompletionCondition& completion_condition,
|
||||
WriteHandler& handler)
|
||||
@@ -306,13 +342,26 @@ namespace detail
|
||||
boost::system::error_code(), 0, 1);
|
||||
}
|
||||
|
||||
struct initiate_async_write_at_buffer_sequence
|
||||
template <typename AsyncRandomAccessWriteDevice>
|
||||
class initiate_async_write_at
|
||||
{
|
||||
template <typename WriteHandler, typename AsyncRandomAccessWriteDevice,
|
||||
typename ConstBufferSequence, typename CompletionCondition>
|
||||
public:
|
||||
typedef typename AsyncRandomAccessWriteDevice::executor_type executor_type;
|
||||
|
||||
explicit initiate_async_write_at(AsyncRandomAccessWriteDevice& device)
|
||||
: device_(device)
|
||||
{
|
||||
}
|
||||
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return device_.get_executor();
|
||||
}
|
||||
|
||||
template <typename WriteHandler, typename ConstBufferSequence,
|
||||
typename CompletionCondition>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
|
||||
AsyncRandomAccessWriteDevice* d, uint64_t offset,
|
||||
const ConstBufferSequence& buffers,
|
||||
uint64_t offset, const ConstBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
|
||||
{
|
||||
// If you get an error on the following line it means that your handler
|
||||
@@ -321,84 +370,95 @@ namespace detail
|
||||
|
||||
non_const_lvalue<WriteHandler> handler2(handler);
|
||||
non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
|
||||
start_write_at_buffer_sequence_op(*d, offset, buffers,
|
||||
start_write_at_op(device_, offset, buffers,
|
||||
boost::asio::buffer_sequence_begin(buffers),
|
||||
completion_cond2.value, handler2.value);
|
||||
}
|
||||
|
||||
private:
|
||||
AsyncRandomAccessWriteDevice& device_;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename AsyncRandomAccessWriteDevice,
|
||||
typename ConstBufferSequence, typename ConstBufferIterator,
|
||||
typename CompletionCondition, typename WriteHandler, typename Allocator>
|
||||
struct associated_allocator<
|
||||
template <template <typename, typename> class Associator,
|
||||
typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
|
||||
typename ConstBufferIterator, typename CompletionCondition,
|
||||
typename WriteHandler, typename DefaultCandidate>
|
||||
struct associator<Associator,
|
||||
detail::write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
|
||||
ConstBufferIterator, CompletionCondition, WriteHandler>,
|
||||
Allocator>
|
||||
DefaultCandidate>
|
||||
: Associator<WriteHandler, DefaultCandidate>
|
||||
{
|
||||
typedef typename associated_allocator<WriteHandler, Allocator>::type type;
|
||||
|
||||
static type get(
|
||||
const detail::write_at_op<AsyncRandomAccessWriteDevice,
|
||||
static typename Associator<WriteHandler, DefaultCandidate>::type
|
||||
get(const detail::write_at_op<AsyncRandomAccessWriteDevice,
|
||||
ConstBufferSequence, ConstBufferIterator,
|
||||
CompletionCondition, WriteHandler>& h,
|
||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
||||
CompletionCondition, WriteHandler>& h) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_allocator<WriteHandler, Allocator>::get(h.handler_, a);
|
||||
return Associator<WriteHandler, DefaultCandidate>::get(h.handler_);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AsyncRandomAccessWriteDevice,
|
||||
typename ConstBufferSequence, typename ConstBufferIterator,
|
||||
typename CompletionCondition, typename WriteHandler, typename Executor>
|
||||
struct associated_executor<
|
||||
detail::write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
|
||||
ConstBufferIterator, CompletionCondition, WriteHandler>,
|
||||
Executor>
|
||||
{
|
||||
typedef typename associated_executor<WriteHandler, Executor>::type type;
|
||||
|
||||
static type get(
|
||||
const detail::write_at_op<AsyncRandomAccessWriteDevice,
|
||||
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
|
||||
typename Associator<WriteHandler, DefaultCandidate>::type)
|
||||
get(const detail::write_at_op<AsyncRandomAccessWriteDevice,
|
||||
ConstBufferSequence, ConstBufferIterator,
|
||||
CompletionCondition, WriteHandler>& h,
|
||||
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
|
||||
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
|
||||
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
|
||||
Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)))
|
||||
{
|
||||
return associated_executor<WriteHandler, Executor>::get(h.handler_, ex);
|
||||
return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
|
||||
typename CompletionCondition, typename WriteHandler>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
|
||||
template <typename AsyncRandomAccessWriteDevice,
|
||||
typename ConstBufferSequence, typename CompletionCondition,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
std::size_t)) WriteToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
async_write_at(AsyncRandomAccessWriteDevice& d,
|
||||
uint64_t offset, const ConstBufferSequence& buffers,
|
||||
CompletionCondition completion_condition,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
BOOST_ASIO_MOVE_ARG(WriteToken) token)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<WriteToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
declval<detail::initiate_async_write_at<
|
||||
AsyncRandomAccessWriteDevice> >(),
|
||||
token, offset, buffers,
|
||||
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))
|
||||
{
|
||||
return async_initiate<WriteHandler,
|
||||
return async_initiate<WriteToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
detail::initiate_async_write_at_buffer_sequence(), handler, &d, offset,
|
||||
buffers, BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
|
||||
detail::initiate_async_write_at<AsyncRandomAccessWriteDevice>(d),
|
||||
token, offset, buffers,
|
||||
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
|
||||
}
|
||||
|
||||
template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
|
||||
typename WriteHandler>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
std::size_t)) WriteToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
async_write_at(AsyncRandomAccessWriteDevice& d,
|
||||
uint64_t offset, const ConstBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
BOOST_ASIO_MOVE_ARG(WriteToken) token)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<WriteToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
declval<detail::initiate_async_write_at<
|
||||
AsyncRandomAccessWriteDevice> >(),
|
||||
token, offset, buffers, transfer_all())))
|
||||
{
|
||||
return async_initiate<WriteHandler,
|
||||
return async_initiate<WriteToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
detail::initiate_async_write_at_buffer_sequence(),
|
||||
handler, &d, offset, buffers, transfer_all());
|
||||
detail::initiate_async_write_at<AsyncRandomAccessWriteDevice>(d),
|
||||
token, offset, buffers, transfer_all());
|
||||
}
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_EXTENSIONS)
|
||||
@@ -436,7 +496,7 @@ namespace detail
|
||||
const std::size_t bytes_transferred)
|
||||
{
|
||||
streambuf_.consume(bytes_transferred);
|
||||
handler_(ec, bytes_transferred);
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec, bytes_transferred);
|
||||
}
|
||||
|
||||
//private:
|
||||
@@ -445,19 +505,29 @@ namespace detail
|
||||
};
|
||||
|
||||
template <typename Allocator, typename WriteHandler>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
inline asio_handler_allocate_is_deprecated
|
||||
asio_handler_allocate(std::size_t size,
|
||||
write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
|
||||
{
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
|
||||
return asio_handler_allocate_is_no_longer_used();
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Allocator, typename WriteHandler>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
inline asio_handler_deallocate_is_deprecated
|
||||
asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_deallocate_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Allocator, typename WriteHandler>
|
||||
@@ -469,28 +539,50 @@ namespace detail
|
||||
}
|
||||
|
||||
template <typename Function, typename Allocator, typename WriteHandler>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(Function& function,
|
||||
write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Function, typename Allocator, typename WriteHandler>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(const Function& function,
|
||||
write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
struct initiate_async_write_at_streambuf
|
||||
template <typename AsyncRandomAccessWriteDevice>
|
||||
class initiate_async_write_at_streambuf
|
||||
{
|
||||
template <typename WriteHandler, typename AsyncRandomAccessWriteDevice,
|
||||
public:
|
||||
typedef typename AsyncRandomAccessWriteDevice::executor_type executor_type;
|
||||
|
||||
explicit initiate_async_write_at_streambuf(
|
||||
AsyncRandomAccessWriteDevice& device)
|
||||
: device_(device)
|
||||
{
|
||||
}
|
||||
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return device_.get_executor();
|
||||
}
|
||||
|
||||
template <typename WriteHandler,
|
||||
typename Allocator, typename CompletionCondition>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
|
||||
AsyncRandomAccessWriteDevice* d, uint64_t offset,
|
||||
basic_streambuf<Allocator>* b,
|
||||
uint64_t offset, basic_streambuf<Allocator>* b,
|
||||
BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_condition) const
|
||||
{
|
||||
// If you get an error on the following line it means that your handler
|
||||
@@ -498,75 +590,92 @@ namespace detail
|
||||
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
|
||||
|
||||
non_const_lvalue<WriteHandler> handler2(handler);
|
||||
async_write_at(*d, offset, b->data(),
|
||||
async_write_at(device_, offset, b->data(),
|
||||
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition),
|
||||
write_at_streambuf_op<Allocator, typename decay<WriteHandler>::type>(
|
||||
*b, handler2.value));
|
||||
}
|
||||
|
||||
private:
|
||||
AsyncRandomAccessWriteDevice& device_;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename Allocator, typename WriteHandler, typename Allocator1>
|
||||
struct associated_allocator<
|
||||
detail::write_at_streambuf_op<Allocator, WriteHandler>,
|
||||
Allocator1>
|
||||
{
|
||||
typedef typename associated_allocator<WriteHandler, Allocator1>::type type;
|
||||
|
||||
static type get(
|
||||
const detail::write_at_streambuf_op<Allocator, WriteHandler>& h,
|
||||
const Allocator1& a = Allocator1()) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_allocator<WriteHandler, Allocator1>::get(h.handler_, a);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Executor, typename WriteHandler, typename Executor1>
|
||||
struct associated_executor<
|
||||
template <template <typename, typename> class Associator,
|
||||
typename Executor, typename WriteHandler, typename DefaultCandidate>
|
||||
struct associator<Associator,
|
||||
detail::write_at_streambuf_op<Executor, WriteHandler>,
|
||||
Executor1>
|
||||
DefaultCandidate>
|
||||
: Associator<WriteHandler, DefaultCandidate>
|
||||
{
|
||||
typedef typename associated_executor<WriteHandler, Executor1>::type type;
|
||||
|
||||
static type get(
|
||||
const detail::write_at_streambuf_op<Executor, WriteHandler>& h,
|
||||
const Executor1& ex = Executor1()) BOOST_ASIO_NOEXCEPT
|
||||
static typename Associator<WriteHandler, DefaultCandidate>::type
|
||||
get(const detail::write_at_streambuf_op<Executor, WriteHandler>& h)
|
||||
BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_executor<WriteHandler, Executor1>::get(h.handler_, ex);
|
||||
return Associator<WriteHandler, DefaultCandidate>::get(h.handler_);
|
||||
}
|
||||
|
||||
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
|
||||
typename Associator<WriteHandler, DefaultCandidate>::type)
|
||||
get(const detail::write_at_streambuf_op<Executor, WriteHandler>& h,
|
||||
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
|
||||
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
|
||||
Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)))
|
||||
{
|
||||
return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename AsyncRandomAccessWriteDevice, typename Allocator,
|
||||
typename CompletionCondition, typename WriteHandler>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
|
||||
template <typename AsyncRandomAccessWriteDevice,
|
||||
typename Allocator, typename CompletionCondition,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
std::size_t)) WriteToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
async_write_at(AsyncRandomAccessWriteDevice& d,
|
||||
uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
|
||||
CompletionCondition completion_condition,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
BOOST_ASIO_MOVE_ARG(WriteToken) token)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<WriteToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
declval<detail::initiate_async_write_at_streambuf<
|
||||
AsyncRandomAccessWriteDevice> >(),
|
||||
token, offset, &b,
|
||||
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))
|
||||
{
|
||||
return async_initiate<WriteHandler,
|
||||
return async_initiate<WriteToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
detail::initiate_async_write_at_streambuf(), handler, &d, offset,
|
||||
&b, BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
|
||||
detail::initiate_async_write_at_streambuf<
|
||||
AsyncRandomAccessWriteDevice>(d),
|
||||
token, offset, &b,
|
||||
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
|
||||
}
|
||||
|
||||
template <typename AsyncRandomAccessWriteDevice, typename Allocator,
|
||||
typename WriteHandler>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
std::size_t)) WriteToken>
|
||||
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
async_write_at(AsyncRandomAccessWriteDevice& d,
|
||||
uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
BOOST_ASIO_MOVE_ARG(WriteToken) token)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<WriteToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
declval<detail::initiate_async_write_at_streambuf<
|
||||
AsyncRandomAccessWriteDevice> >(),
|
||||
token, offset, &b, transfer_all())))
|
||||
{
|
||||
return async_initiate<WriteHandler,
|
||||
return async_initiate<WriteToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
detail::initiate_async_write_at_streambuf(),
|
||||
handler, &d, offset, &b, transfer_all());
|
||||
detail::initiate_async_write_at_streambuf<
|
||||
AsyncRandomAccessWriteDevice>(d),
|
||||
token, offset, &b, transfer_all());
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
|
||||
|
||||
Reference in New Issue
Block a user