updated boost on windows
This commit is contained in:
133
winx64/include/boost/asio/associated_allocator.hpp
Normal file
133
winx64/include/boost/asio/associated_allocator.hpp
Normal file
@@ -0,0 +1,133 @@
|
||||
//
|
||||
// associated_allocator.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_ASSOCIATED_ALLOCATOR_HPP
|
||||
#define BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <memory>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
template <typename>
|
||||
struct associated_allocator_check
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template <typename T, typename E, typename = void>
|
||||
struct associated_allocator_impl
|
||||
{
|
||||
typedef E type;
|
||||
|
||||
static type get(const T&, const E& e) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return e;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename E>
|
||||
struct associated_allocator_impl<T, E,
|
||||
typename associated_allocator_check<typename T::allocator_type>::type>
|
||||
{
|
||||
typedef typename T::allocator_type type;
|
||||
|
||||
static type get(const T& t, const E&) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return t.get_allocator();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// Traits type used to obtain the allocator associated with an object.
|
||||
/**
|
||||
* A program may specialise this traits type if the @c T template parameter in
|
||||
* the specialisation is a user-defined type. The template parameter @c
|
||||
* Allocator shall be a type meeting the Allocator requirements.
|
||||
*
|
||||
* Specialisations shall meet the following requirements, where @c t is a const
|
||||
* reference to an object of type @c T, and @c a is an object of type @c
|
||||
* Allocator.
|
||||
*
|
||||
* @li Provide a nested typedef @c type that identifies a type meeting the
|
||||
* Allocator requirements.
|
||||
*
|
||||
* @li Provide a noexcept static member function named @c get, callable as @c
|
||||
* get(t) and with return type @c type.
|
||||
*
|
||||
* @li Provide a noexcept static member function named @c get, callable as @c
|
||||
* get(t,a) and with return type @c type.
|
||||
*/
|
||||
template <typename T, typename Allocator = std::allocator<void> >
|
||||
struct associated_allocator
|
||||
{
|
||||
/// If @c T has a nested type @c allocator_type, <tt>T::allocator_type</tt>.
|
||||
/// Otherwise @c Allocator.
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
typedef see_below type;
|
||||
#else // defined(GENERATING_DOCUMENTATION)
|
||||
typedef typename detail::associated_allocator_impl<T, Allocator>::type type;
|
||||
#endif // defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// If @c T has a nested type @c allocator_type, returns
|
||||
/// <tt>t.get_allocator()</tt>. Otherwise returns @c a.
|
||||
static type get(const T& t,
|
||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return detail::associated_allocator_impl<T, Allocator>::get(t, a);
|
||||
}
|
||||
};
|
||||
|
||||
/// Helper function to obtain an object's associated allocator.
|
||||
/**
|
||||
* @returns <tt>associated_allocator<T>::get(t)</tt>
|
||||
*/
|
||||
template <typename T>
|
||||
inline typename associated_allocator<T>::type
|
||||
get_associated_allocator(const T& t) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_allocator<T>::get(t);
|
||||
}
|
||||
|
||||
/// Helper function to obtain an object's associated allocator.
|
||||
/**
|
||||
* @returns <tt>associated_allocator<T, Allocator>::get(t, a)</tt>
|
||||
*/
|
||||
template <typename T, typename Allocator>
|
||||
inline typename associated_allocator<T, Allocator>::type
|
||||
get_associated_allocator(const T& t, const Allocator& a) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_allocator<T, Allocator>::get(t, a);
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
|
||||
|
||||
template <typename T, typename Allocator = std::allocator<void> >
|
||||
using associated_allocator_t
|
||||
= typename associated_allocator<T, Allocator>::type;
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP
|
||||
151
winx64/include/boost/asio/associated_executor.hpp
Normal file
151
winx64/include/boost/asio/associated_executor.hpp
Normal file
@@ -0,0 +1,151 @@
|
||||
//
|
||||
// associated_executor.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_ASSOCIATED_EXECUTOR_HPP
|
||||
#define BOOST_ASIO_ASSOCIATED_EXECUTOR_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/type_traits.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 associated_executor_check
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template <typename T, typename E, typename = void>
|
||||
struct associated_executor_impl
|
||||
{
|
||||
typedef E type;
|
||||
|
||||
static type get(const T&, const E& e) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return e;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename E>
|
||||
struct associated_executor_impl<T, E,
|
||||
typename associated_executor_check<typename T::executor_type>::type>
|
||||
{
|
||||
typedef typename T::executor_type type;
|
||||
|
||||
static type get(const T& t, const E&) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return t.get_executor();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// Traits type used to obtain the executor associated with an object.
|
||||
/**
|
||||
* A program may specialise this traits type if the @c T template parameter in
|
||||
* the specialisation is a user-defined type. The template parameter @c
|
||||
* Executor shall be a type meeting the Executor requirements.
|
||||
*
|
||||
* Specialisations shall meet the following requirements, where @c t is a const
|
||||
* reference to an object of type @c T, and @c e is an object of type @c
|
||||
* Executor.
|
||||
*
|
||||
* @li Provide a nested typedef @c type that identifies a type meeting the
|
||||
* Executor requirements.
|
||||
*
|
||||
* @li Provide a noexcept static member function named @c get, callable as @c
|
||||
* get(t) and with return type @c type.
|
||||
*
|
||||
* @li Provide a noexcept static member function named @c get, callable as @c
|
||||
* get(t,e) and with return type @c type.
|
||||
*/
|
||||
template <typename T, typename Executor = system_executor>
|
||||
struct associated_executor
|
||||
{
|
||||
/// If @c T has a nested type @c executor_type, <tt>T::executor_type</tt>.
|
||||
/// Otherwise @c Executor.
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
typedef see_below type;
|
||||
#else // defined(GENERATING_DOCUMENTATION)
|
||||
typedef typename detail::associated_executor_impl<T, Executor>::type type;
|
||||
#endif // defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// If @c T has a nested type @c executor_type, returns
|
||||
/// <tt>t.get_executor()</tt>. Otherwise returns @c ex.
|
||||
static type get(const T& t,
|
||||
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return detail::associated_executor_impl<T, Executor>::get(t, ex);
|
||||
}
|
||||
};
|
||||
|
||||
/// Helper function to obtain an object's associated executor.
|
||||
/**
|
||||
* @returns <tt>associated_executor<T>::get(t)</tt>
|
||||
*/
|
||||
template <typename T>
|
||||
inline typename associated_executor<T>::type
|
||||
get_associated_executor(const T& t) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_executor<T>::get(t);
|
||||
}
|
||||
|
||||
/// Helper function to obtain an object's associated executor.
|
||||
/**
|
||||
* @returns <tt>associated_executor<T, Executor>::get(t, ex)</tt>
|
||||
*/
|
||||
template <typename T, typename Executor>
|
||||
inline typename associated_executor<T, Executor>::type
|
||||
get_associated_executor(const T& t, const Executor& ex,
|
||||
typename enable_if<is_executor<
|
||||
Executor>::value>::type* = 0) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_executor<T, Executor>::get(t, ex);
|
||||
}
|
||||
|
||||
/// Helper function to obtain an object's associated executor.
|
||||
/**
|
||||
* @returns <tt>associated_executor<T, typename
|
||||
* ExecutionContext::executor_type>::get(t, ctx.get_executor())</tt>
|
||||
*/
|
||||
template <typename T, typename ExecutionContext>
|
||||
inline typename associated_executor<T,
|
||||
typename ExecutionContext::executor_type>::type
|
||||
get_associated_executor(const T& t, ExecutionContext& ctx,
|
||||
typename enable_if<is_convertible<ExecutionContext&,
|
||||
execution_context&>::value>::type* = 0) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_executor<T,
|
||||
typename ExecutionContext::executor_type>::get(t, ctx.get_executor());
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
|
||||
|
||||
template <typename T, typename Executor = system_executor>
|
||||
using associated_executor_t = typename associated_executor<T, Executor>::type;
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_ASSOCIATED_EXECUTOR_HPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// async_result.hpp
|
||||
// ~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -16,7 +16,8 @@
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <boost/asio/handler_type.hpp>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
#include <boost/asio/detail/variadic_templates.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
@@ -25,72 +26,333 @@ namespace asio {
|
||||
|
||||
/// An interface for customising the behaviour of an initiating function.
|
||||
/**
|
||||
* This template may be specialised for user-defined handler types.
|
||||
* The async_result traits class is used for determining:
|
||||
*
|
||||
* @li the concrete completion handler type to be called at the end of the
|
||||
* asynchronous operation;
|
||||
*
|
||||
* @li the initiating function return type; and
|
||||
*
|
||||
* @li how the return value of the initiating function is obtained.
|
||||
*
|
||||
* The trait allows the handler and return types to be determined at the point
|
||||
* where the specific completion handler signature is known.
|
||||
*
|
||||
* This template may be specialised for user-defined completion token types.
|
||||
* The primary template assumes that the CompletionToken is the completion
|
||||
* handler.
|
||||
*/
|
||||
template <typename Handler>
|
||||
template <typename CompletionToken, typename Signature>
|
||||
class async_result
|
||||
{
|
||||
public:
|
||||
/// The concrete completion handler type for the specific signature.
|
||||
typedef CompletionToken completion_handler_type;
|
||||
|
||||
/// The return type of the initiating function.
|
||||
typedef void type;
|
||||
typedef void return_type;
|
||||
|
||||
/// Construct an async result from a given handler.
|
||||
/**
|
||||
* When using a specalised async_result, the constructor has an opportunity
|
||||
* to initialise some state associated with the handler, which is then
|
||||
* returned from the initiating function.
|
||||
* to initialise some state associated with the completion handler, which is
|
||||
* then returned from the initiating function.
|
||||
*/
|
||||
explicit async_result(Handler&)
|
||||
explicit async_result(completion_handler_type& h)
|
||||
{
|
||||
(void)h;
|
||||
}
|
||||
|
||||
/// Obtain the value to be returned from the initiating function.
|
||||
type get()
|
||||
return_type get()
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \
|
||||
|| defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Initiate the asynchronous operation that will produce the result, and
|
||||
/// obtain the value to be returned from the initiating function.
|
||||
template <typename Initiation, typename RawCompletionToken, typename... Args>
|
||||
static return_type initiate(
|
||||
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
|
||||
BOOST_ASIO_MOVE_CAST(RawCompletionToken)(token),
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
|
||||
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
// || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename Initiation, typename RawCompletionToken>
|
||||
static return_type initiate(
|
||||
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token)
|
||||
{
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
|
||||
BOOST_ASIO_MOVE_CAST(RawCompletionToken)(token));
|
||||
}
|
||||
|
||||
#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
|
||||
template <typename Initiation, typename RawCompletionToken, \
|
||||
BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
static return_type initiate( \
|
||||
BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
|
||||
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token, \
|
||||
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||
{ \
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( \
|
||||
BOOST_ASIO_MOVE_CAST(RawCompletionToken)(token), \
|
||||
BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||
} \
|
||||
/**/
|
||||
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF)
|
||||
#undef BOOST_ASIO_PRIVATE_INITIATE_DEF
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
// || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
private:
|
||||
async_result(const async_result&) BOOST_ASIO_DELETED;
|
||||
async_result& operator=(const async_result&) BOOST_ASIO_DELETED;
|
||||
};
|
||||
|
||||
/// Helper template to deduce the handler type from a CompletionToken, capture
|
||||
/// a local copy of the handler, and then create an async_result for the
|
||||
/// handler.
|
||||
template <typename CompletionToken, typename Signature>
|
||||
struct async_completion
|
||||
{
|
||||
/// The real handler type to be used for the asynchronous operation.
|
||||
typedef typename boost::asio::async_result<
|
||||
typename decay<CompletionToken>::type,
|
||||
Signature>::completion_handler_type completion_handler_type;
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
/// Constructor.
|
||||
/**
|
||||
* The constructor creates the concrete completion handler and makes the link
|
||||
* between the handler and the asynchronous result.
|
||||
*/
|
||||
explicit async_completion(CompletionToken& token)
|
||||
: completion_handler(static_cast<typename conditional<
|
||||
is_same<CompletionToken, completion_handler_type>::value,
|
||||
completion_handler_type&, CompletionToken&&>::type>(token)),
|
||||
result(completion_handler)
|
||||
{
|
||||
}
|
||||
#else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
explicit async_completion(typename decay<CompletionToken>::type& token)
|
||||
: completion_handler(token),
|
||||
result(completion_handler)
|
||||
{
|
||||
}
|
||||
|
||||
explicit async_completion(const typename decay<CompletionToken>::type& token)
|
||||
: completion_handler(token),
|
||||
result(completion_handler)
|
||||
{
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// A copy of, or reference to, a real handler object.
|
||||
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
typename conditional<
|
||||
is_same<CompletionToken, completion_handler_type>::value,
|
||||
completion_handler_type&, completion_handler_type>::type completion_handler;
|
||||
#else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
completion_handler_type completion_handler;
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// The result of the asynchronous operation's initiating function.
|
||||
async_result<typename decay<CompletionToken>::type, Signature> result;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Helper template to deduce the true type of a handler, capture a local copy
|
||||
// of the handler, and then create an async_result for the handler.
|
||||
template <typename Handler, typename Signature>
|
||||
struct async_result_init
|
||||
template <typename CompletionToken, typename Signature>
|
||||
struct async_result_helper
|
||||
: async_result<typename decay<CompletionToken>::type, Signature>
|
||||
{
|
||||
explicit async_result_init(BOOST_ASIO_MOVE_ARG(Handler) orig_handler)
|
||||
: handler(BOOST_ASIO_MOVE_CAST(Handler)(orig_handler)),
|
||||
result(handler)
|
||||
{
|
||||
}
|
||||
|
||||
typename handler_type<Handler, Signature>::type handler;
|
||||
async_result<typename handler_type<Handler, Signature>::type> result;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Signature>
|
||||
struct async_result_type_helper
|
||||
struct async_result_memfns_base
|
||||
{
|
||||
void initiate();
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct async_result_memfns_derived
|
||||
: T, async_result_memfns_base
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T, T>
|
||||
struct async_result_memfns_check
|
||||
{
|
||||
};
|
||||
|
||||
template <typename>
|
||||
char (&async_result_initiate_memfn_helper(...))[2];
|
||||
|
||||
template <typename T>
|
||||
char async_result_initiate_memfn_helper(
|
||||
async_result_memfns_check<
|
||||
void (async_result_memfns_base::*)(),
|
||||
&async_result_memfns_derived<T>::initiate>*);
|
||||
|
||||
template <typename CompletionToken, typename Signature>
|
||||
struct async_result_has_initiate_memfn
|
||||
: integral_constant<bool, sizeof(async_result_initiate_memfn_helper<
|
||||
async_result<typename decay<CompletionToken>::type, Signature>
|
||||
>(0)) != 1>
|
||||
{
|
||||
typedef typename async_result<
|
||||
typename handler_type<Handler, Signature>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
# define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \
|
||||
void_or_deduced
|
||||
#elif defined(_MSC_VER) && (_MSC_VER < 1500)
|
||||
# define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \
|
||||
typename ::boost::asio::detail::async_result_helper< \
|
||||
ct, sig>::return_type
|
||||
#define BOOST_ASIO_HANDLER_TYPE(ct, sig) \
|
||||
typename ::boost::asio::detail::async_result_helper< \
|
||||
ct, sig>::completion_handler_type
|
||||
#else
|
||||
# define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \
|
||||
typename ::boost::asio::async_result< \
|
||||
typename ::boost::asio::decay<ct>::type, sig>::return_type
|
||||
#define BOOST_ASIO_HANDLER_TYPE(ct, sig) \
|
||||
typename ::boost::asio::async_result< \
|
||||
typename ::boost::asio::decay<ct>::type, sig>::completion_handler_type
|
||||
#endif
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename CompletionToken, typename Signature,
|
||||
typename Initiation, typename... Args>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)
|
||||
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken),
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args);
|
||||
|
||||
#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
template <typename CompletionToken, typename Signature,
|
||||
typename Initiation, typename... Args>
|
||||
inline typename enable_if<
|
||||
detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
|
||||
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
return async_result<typename decay<CompletionToken>::type,
|
||||
Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation),
|
||||
BOOST_ASIO_MOVE_CAST(CompletionToken)(token),
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
|
||||
template <typename CompletionToken, typename Signature,
|
||||
typename Initiation, typename... Args>
|
||||
inline typename enable_if<
|
||||
!detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
|
||||
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
async_completion<CompletionToken, Signature> completion(token);
|
||||
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
|
||||
BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(CompletionToken,
|
||||
Signature))(completion.completion_handler),
|
||||
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
|
||||
return completion.result.get();
|
||||
}
|
||||
|
||||
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
template <typename CompletionToken, typename Signature, typename Initiation>
|
||||
inline typename enable_if<
|
||||
detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
|
||||
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
|
||||
{
|
||||
return async_result<typename decay<CompletionToken>::type,
|
||||
Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation),
|
||||
BOOST_ASIO_MOVE_CAST(CompletionToken)(token));
|
||||
}
|
||||
|
||||
template <typename CompletionToken, typename Signature, typename Initiation>
|
||||
inline typename enable_if<
|
||||
!detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
|
||||
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
|
||||
{
|
||||
async_completion<CompletionToken, Signature> completion(token);
|
||||
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
|
||||
BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(CompletionToken,
|
||||
Signature))(completion.completion_handler));
|
||||
|
||||
return completion.result.get();
|
||||
}
|
||||
|
||||
#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
|
||||
template <typename CompletionToken, typename Signature, \
|
||||
typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
inline typename enable_if< \
|
||||
detail::async_result_has_initiate_memfn< \
|
||||
CompletionToken, Signature>::value, \
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type \
|
||||
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
|
||||
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
|
||||
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||
{ \
|
||||
return async_result<typename decay<CompletionToken>::type, \
|
||||
Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation), \
|
||||
BOOST_ASIO_MOVE_CAST(CompletionToken)(token), \
|
||||
BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||
} \
|
||||
\
|
||||
template <typename CompletionToken, typename Signature, \
|
||||
typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
inline typename enable_if< \
|
||||
!detail::async_result_has_initiate_memfn< \
|
||||
CompletionToken, Signature>::value, \
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type \
|
||||
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
|
||||
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
|
||||
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||
{ \
|
||||
async_completion<CompletionToken, Signature> completion(token); \
|
||||
\
|
||||
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( \
|
||||
BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(CompletionToken, \
|
||||
Signature))(completion.completion_handler), \
|
||||
BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||
\
|
||||
return completion.result.get(); \
|
||||
} \
|
||||
/**/
|
||||
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF)
|
||||
#undef BOOST_ASIO_PRIVATE_INITIATE_DEF
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
# define BOOST_ASIO_INITFN_RESULT_TYPE(h, sig) \
|
||||
void_or_deduced
|
||||
#elif defined(_MSC_VER) && (_MSC_VER < 1500)
|
||||
# define BOOST_ASIO_INITFN_RESULT_TYPE(h, sig) \
|
||||
typename ::boost::asio::detail::async_result_type_helper<h, sig>::type
|
||||
#else
|
||||
# define BOOST_ASIO_INITFN_RESULT_TYPE(h, sig) \
|
||||
typename ::boost::asio::async_result< \
|
||||
typename ::boost::asio::handler_type<h, sig>::type>::type
|
||||
#endif
|
||||
|
||||
#endif // BOOST_ASIO_ASYNC_RESULT_HPP
|
||||
|
||||
125
winx64/include/boost/asio/awaitable.hpp
Normal file
125
winx64/include/boost/asio/awaitable.hpp
Normal file
@@ -0,0 +1,125 @@
|
||||
//
|
||||
// awaitable.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_AWAITABLE_HPP
|
||||
#define BOOST_ASIO_AWAITABLE_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_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
#include <experimental/coroutine>
|
||||
#include <boost/asio/executor.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
using std::experimental::coroutine_handle;
|
||||
using std::experimental::suspend_always;
|
||||
|
||||
template <typename> class awaitable_thread;
|
||||
template <typename, typename> class awaitable_frame;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// The return type of a coroutine or asynchronous operation.
|
||||
template <typename T, typename Executor = executor>
|
||||
class awaitable
|
||||
{
|
||||
public:
|
||||
/// The type of the awaited value.
|
||||
typedef T value_type;
|
||||
|
||||
/// The executor type that will be used for the coroutine.
|
||||
typedef Executor executor_type;
|
||||
|
||||
/// Default constructor.
|
||||
constexpr awaitable() noexcept
|
||||
: frame_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
/// Move constructor.
|
||||
awaitable(awaitable&& other) noexcept
|
||||
: frame_(std::exchange(other.frame_, nullptr))
|
||||
{
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
~awaitable()
|
||||
{
|
||||
if (frame_)
|
||||
frame_->destroy();
|
||||
}
|
||||
|
||||
/// Checks if the awaitable refers to a future result.
|
||||
bool valid() const noexcept
|
||||
{
|
||||
return !!frame_;
|
||||
}
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
// Support for co_await keyword.
|
||||
bool await_ready() const noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Support for co_await keyword.
|
||||
template <class U>
|
||||
void await_suspend(
|
||||
detail::coroutine_handle<detail::awaitable_frame<U, Executor>> h)
|
||||
{
|
||||
frame_->push_frame(&h.promise());
|
||||
}
|
||||
|
||||
// Support for co_await keyword.
|
||||
T await_resume()
|
||||
{
|
||||
return frame_->get();
|
||||
}
|
||||
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
private:
|
||||
template <typename> friend class detail::awaitable_thread;
|
||||
template <typename, typename> friend class detail::awaitable_frame;
|
||||
|
||||
// Not copy constructible or copy assignable.
|
||||
awaitable(const awaitable&) = delete;
|
||||
awaitable& operator=(const awaitable&) = delete;
|
||||
|
||||
// Construct the awaitable from a coroutine's frame object.
|
||||
explicit awaitable(detail::awaitable_frame<T, Executor>* a)
|
||||
: frame_(a)
|
||||
{
|
||||
}
|
||||
|
||||
detail::awaitable_frame<T, Executor>* frame_;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#include <boost/asio/impl/awaitable.hpp>
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
#endif // BOOST_ASIO_AWAITABLE_HPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// basic_datagram_socket.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -18,8 +18,8 @@
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <cstddef>
|
||||
#include <boost/asio/basic_socket.hpp>
|
||||
#include <boost/asio/datagram_socket_service.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>
|
||||
@@ -29,6 +29,15 @@
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
#if !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL)
|
||||
#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL
|
||||
|
||||
// Forward declaration with defaulted arguments.
|
||||
template <typename Protocol, typename Executor = executor>
|
||||
class basic_datagram_socket;
|
||||
|
||||
#endif // !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL)
|
||||
|
||||
/// Provides datagram-oriented socket functionality.
|
||||
/**
|
||||
* The basic_datagram_socket class template provides asynchronous and blocking
|
||||
@@ -38,18 +47,29 @@ namespace asio {
|
||||
* @e Distinct @e objects: Safe.@n
|
||||
* @e Shared @e objects: Unsafe.
|
||||
*/
|
||||
template <typename Protocol,
|
||||
typename DatagramSocketService = datagram_socket_service<Protocol> >
|
||||
template <typename Protocol, typename Executor>
|
||||
class basic_datagram_socket
|
||||
: public basic_socket<Protocol, DatagramSocketService>
|
||||
: public basic_socket<Protocol, Executor>
|
||||
{
|
||||
public:
|
||||
/// (Deprecated: Use native_handle_type.) The native representation of a
|
||||
/// socket.
|
||||
typedef typename DatagramSocketService::native_handle_type native_type;
|
||||
/// The type of the executor associated with the object.
|
||||
typedef Executor executor_type;
|
||||
|
||||
/// Rebinds the socket type to another executor.
|
||||
template <typename Executor1>
|
||||
struct rebind_executor
|
||||
{
|
||||
/// The socket type when rebound to the specified executor.
|
||||
typedef basic_datagram_socket<Protocol, Executor1> other;
|
||||
};
|
||||
|
||||
/// The native representation of a socket.
|
||||
typedef typename DatagramSocketService::native_handle_type native_handle_type;
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
typedef implementation_defined native_handle_type;
|
||||
#else
|
||||
typedef typename basic_socket<Protocol,
|
||||
Executor>::native_handle_type native_handle_type;
|
||||
#endif
|
||||
|
||||
/// The protocol type.
|
||||
typedef Protocol protocol_type;
|
||||
@@ -62,12 +82,29 @@ public:
|
||||
* This constructor creates a datagram socket without opening it. The open()
|
||||
* function must be called before data can be sent or received on the socket.
|
||||
*
|
||||
* @param io_service The io_service object that the datagram socket will use
|
||||
* to dispatch handlers for any asynchronous operations performed on the
|
||||
* socket.
|
||||
* @param ex The I/O executor that the socket will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*/
|
||||
explicit basic_datagram_socket(boost::asio::io_service& io_service)
|
||||
: basic_socket<Protocol, DatagramSocketService>(io_service)
|
||||
explicit basic_datagram_socket(const executor_type& ex)
|
||||
: basic_socket<Protocol, Executor>(ex)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a basic_datagram_socket without opening it.
|
||||
/**
|
||||
* This constructor creates a datagram socket without opening it. The open()
|
||||
* function must be called before data can be sent or received on the socket.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the socket will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the socket.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
explicit basic_datagram_socket(ExecutionContext& context,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(context)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -75,17 +112,37 @@ public:
|
||||
/**
|
||||
* This constructor creates and opens a datagram socket.
|
||||
*
|
||||
* @param io_service The io_service object that the datagram socket will use
|
||||
* to dispatch handlers for any asynchronous operations performed on the
|
||||
* socket.
|
||||
* @param ex The I/O executor that the socket will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
basic_datagram_socket(boost::asio::io_service& io_service,
|
||||
const protocol_type& protocol)
|
||||
: basic_socket<Protocol, DatagramSocketService>(io_service, protocol)
|
||||
basic_datagram_socket(const executor_type& ex, const protocol_type& protocol)
|
||||
: basic_socket<Protocol, Executor>(ex, protocol)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct and open a basic_datagram_socket.
|
||||
/**
|
||||
* This constructor creates and opens a datagram socket.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the socket will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_datagram_socket(ExecutionContext& context,
|
||||
const protocol_type& protocol,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(context, protocol)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -96,18 +153,42 @@ public:
|
||||
* to the specified endpoint on the local machine. The protocol used is the
|
||||
* protocol associated with the given endpoint.
|
||||
*
|
||||
* @param io_service The io_service object that the datagram socket will use
|
||||
* to dispatch handlers for any asynchronous operations performed on the
|
||||
* socket.
|
||||
* @param ex The I/O executor that the socket will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*
|
||||
* @param endpoint An endpoint on the local machine to which the datagram
|
||||
* socket will be bound.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
basic_datagram_socket(boost::asio::io_service& io_service,
|
||||
const endpoint_type& endpoint)
|
||||
: basic_socket<Protocol, DatagramSocketService>(io_service, endpoint)
|
||||
basic_datagram_socket(const executor_type& ex, const endpoint_type& endpoint)
|
||||
: basic_socket<Protocol, Executor>(ex, endpoint)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a basic_datagram_socket, opening it and binding it to the given
|
||||
/// local endpoint.
|
||||
/**
|
||||
* This constructor creates a datagram socket and automatically opens it bound
|
||||
* to the specified endpoint on the local machine. The protocol used is the
|
||||
* protocol associated with the given endpoint.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the socket will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the socket.
|
||||
*
|
||||
* @param endpoint An endpoint on the local machine to which the datagram
|
||||
* socket will be bound.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_datagram_socket(ExecutionContext& context,
|
||||
const endpoint_type& endpoint,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(context, endpoint)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -116,9 +197,8 @@ public:
|
||||
* This constructor creates a datagram socket object to hold an existing
|
||||
* native socket.
|
||||
*
|
||||
* @param io_service The io_service object that the datagram socket will use
|
||||
* to dispatch handlers for any asynchronous operations performed on the
|
||||
* socket.
|
||||
* @param ex The I/O executor that the socket will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
@@ -126,10 +206,34 @@ public:
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
basic_datagram_socket(boost::asio::io_service& io_service,
|
||||
basic_datagram_socket(const executor_type& ex,
|
||||
const protocol_type& protocol, const native_handle_type& native_socket)
|
||||
: basic_socket<Protocol, DatagramSocketService>(
|
||||
io_service, protocol, native_socket)
|
||||
: basic_socket<Protocol, Executor>(ex, protocol, native_socket)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a basic_datagram_socket on an existing native socket.
|
||||
/**
|
||||
* This constructor creates a datagram socket object to hold an existing
|
||||
* native socket.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the socket will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @param native_socket The new underlying socket implementation.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_datagram_socket(ExecutionContext& context,
|
||||
const protocol_type& protocol, const native_handle_type& native_socket,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -142,11 +246,11 @@ public:
|
||||
* will occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_datagram_socket(io_service&) constructor.
|
||||
* constructed using the @c basic_datagram_socket(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
basic_datagram_socket(basic_datagram_socket&& other)
|
||||
: basic_socket<Protocol, DatagramSocketService>(
|
||||
BOOST_ASIO_MOVE_CAST(basic_datagram_socket)(other))
|
||||
: basic_socket<Protocol, Executor>(std::move(other))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -159,12 +263,12 @@ public:
|
||||
* will occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_datagram_socket(io_service&) constructor.
|
||||
* constructed using the @c basic_datagram_socket(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
basic_datagram_socket& operator=(basic_datagram_socket&& other)
|
||||
{
|
||||
basic_socket<Protocol, DatagramSocketService>::operator=(
|
||||
BOOST_ASIO_MOVE_CAST(basic_datagram_socket)(other));
|
||||
basic_socket<Protocol, Executor>::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -177,15 +281,16 @@ public:
|
||||
* will occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_datagram_socket(io_service&) constructor.
|
||||
* constructed using the @c basic_datagram_socket(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
template <typename Protocol1, typename DatagramSocketService1>
|
||||
basic_datagram_socket(
|
||||
basic_datagram_socket<Protocol1, DatagramSocketService1>&& other,
|
||||
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
|
||||
: basic_socket<Protocol, DatagramSocketService>(
|
||||
BOOST_ASIO_MOVE_CAST2(basic_datagram_socket<
|
||||
Protocol1, DatagramSocketService1>)(other))
|
||||
template <typename Protocol1, typename Executor1>
|
||||
basic_datagram_socket(basic_datagram_socket<Protocol1, Executor1>&& other,
|
||||
typename enable_if<
|
||||
is_convertible<Protocol1, Protocol>::value
|
||||
&& is_convertible<Executor1, Executor>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(std::move(other))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -199,20 +304,30 @@ public:
|
||||
* will occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_datagram_socket(io_service&) constructor.
|
||||
* constructed using the @c basic_datagram_socket(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
template <typename Protocol1, typename DatagramSocketService1>
|
||||
typename enable_if<is_convertible<Protocol1, Protocol>::value,
|
||||
basic_datagram_socket>::type& operator=(
|
||||
basic_datagram_socket<Protocol1, DatagramSocketService1>&& other)
|
||||
template <typename Protocol1, typename Executor1>
|
||||
typename enable_if<
|
||||
is_convertible<Protocol1, Protocol>::value
|
||||
&& is_convertible<Executor1, Executor>::value,
|
||||
basic_datagram_socket&
|
||||
>::type operator=(basic_datagram_socket<Protocol1, Executor1>&& other)
|
||||
{
|
||||
basic_socket<Protocol, DatagramSocketService>::operator=(
|
||||
BOOST_ASIO_MOVE_CAST2(basic_datagram_socket<
|
||||
Protocol1, DatagramSocketService1>)(other));
|
||||
basic_socket<Protocol, Executor>::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Destroys the socket.
|
||||
/**
|
||||
* This function destroys the socket, cancelling any outstanding asynchronous
|
||||
* operations associated with the socket as if by calling @c cancel.
|
||||
*/
|
||||
~basic_datagram_socket()
|
||||
{
|
||||
}
|
||||
|
||||
/// Send some data on a connected socket.
|
||||
/**
|
||||
* This function is used to send data on the datagram socket. The function
|
||||
@@ -239,8 +354,8 @@ public:
|
||||
std::size_t send(const ConstBufferSequence& buffers)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().send(
|
||||
this->get_implementation(), buffers, 0, ec);
|
||||
std::size_t s = this->impl_.get_service().send(
|
||||
this->impl_.get_implementation(), buffers, 0, ec);
|
||||
boost::asio::detail::throw_error(ec, "send");
|
||||
return s;
|
||||
}
|
||||
@@ -267,8 +382,8 @@ public:
|
||||
socket_base::message_flags flags)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().send(
|
||||
this->get_implementation(), buffers, flags, ec);
|
||||
std::size_t s = this->impl_.get_service().send(
|
||||
this->impl_.get_implementation(), buffers, flags, ec);
|
||||
boost::asio::detail::throw_error(ec, "send");
|
||||
return s;
|
||||
}
|
||||
@@ -294,8 +409,8 @@ public:
|
||||
std::size_t send(const ConstBufferSequence& buffers,
|
||||
socket_base::message_flags flags, boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().send(
|
||||
this->get_implementation(), buffers, flags, ec);
|
||||
return this->impl_.get_service().send(
|
||||
this->impl_.get_implementation(), buffers, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous send on a connected socket.
|
||||
@@ -316,9 +431,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes sent.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @note The async_send operation can only be used with a connected socket.
|
||||
* Use the async_send_to function to send data on an unconnected datagram
|
||||
@@ -339,12 +454,10 @@ public:
|
||||
async_send(const ConstBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
// 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;
|
||||
|
||||
return this->get_service().async_send(this->get_implementation(),
|
||||
buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
return async_initiate<WriteHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_send(), handler, this,
|
||||
buffers, socket_base::message_flags(0));
|
||||
}
|
||||
|
||||
/// Start an asynchronous send on a connected socket.
|
||||
@@ -367,9 +480,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes sent.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @note The async_send operation can only be used with a connected socket.
|
||||
* Use the async_send_to function to send data on an unconnected datagram
|
||||
@@ -382,12 +495,9 @@ public:
|
||||
socket_base::message_flags flags,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
// 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;
|
||||
|
||||
return this->get_service().async_send(this->get_implementation(),
|
||||
buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
return async_initiate<WriteHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_send(), handler, this, buffers, flags);
|
||||
}
|
||||
|
||||
/// Send a datagram to the specified endpoint.
|
||||
@@ -420,8 +530,8 @@ public:
|
||||
const endpoint_type& destination)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().send_to(
|
||||
this->get_implementation(), buffers, destination, 0, ec);
|
||||
std::size_t s = this->impl_.get_service().send_to(
|
||||
this->impl_.get_implementation(), buffers, destination, 0, ec);
|
||||
boost::asio::detail::throw_error(ec, "send_to");
|
||||
return s;
|
||||
}
|
||||
@@ -447,8 +557,8 @@ public:
|
||||
const endpoint_type& destination, socket_base::message_flags flags)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().send_to(
|
||||
this->get_implementation(), buffers, destination, flags, ec);
|
||||
std::size_t s = this->impl_.get_service().send_to(
|
||||
this->impl_.get_implementation(), buffers, destination, flags, ec);
|
||||
boost::asio::detail::throw_error(ec, "send_to");
|
||||
return s;
|
||||
}
|
||||
@@ -474,7 +584,7 @@ public:
|
||||
const endpoint_type& destination, socket_base::message_flags flags,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().send_to(this->get_implementation(),
|
||||
return this->impl_.get_service().send_to(this->impl_.get_implementation(),
|
||||
buffers, destination, flags, ec);
|
||||
}
|
||||
|
||||
@@ -499,9 +609,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes sent.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @par Example
|
||||
* To send a single data buffer use the @ref buffer function as follows:
|
||||
@@ -522,13 +632,10 @@ public:
|
||||
const endpoint_type& destination,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
// 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;
|
||||
|
||||
return this->get_service().async_send_to(
|
||||
this->get_implementation(), buffers, destination, 0,
|
||||
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
return async_initiate<WriteHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_send_to(), handler, this, buffers,
|
||||
destination, socket_base::message_flags(0));
|
||||
}
|
||||
|
||||
/// Start an asynchronous send.
|
||||
@@ -554,9 +661,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes sent.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*/
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
|
||||
@@ -565,13 +672,9 @@ public:
|
||||
const endpoint_type& destination, socket_base::message_flags flags,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
// 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;
|
||||
|
||||
return this->get_service().async_send_to(
|
||||
this->get_implementation(), buffers, destination, flags,
|
||||
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
return async_initiate<WriteHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_send_to(), handler, this, buffers, destination, flags);
|
||||
}
|
||||
|
||||
/// Receive some data on a connected socket.
|
||||
@@ -602,8 +705,8 @@ public:
|
||||
std::size_t receive(const MutableBufferSequence& buffers)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().receive(
|
||||
this->get_implementation(), buffers, 0, ec);
|
||||
std::size_t s = this->impl_.get_service().receive(
|
||||
this->impl_.get_implementation(), buffers, 0, ec);
|
||||
boost::asio::detail::throw_error(ec, "receive");
|
||||
return s;
|
||||
}
|
||||
@@ -631,8 +734,8 @@ public:
|
||||
socket_base::message_flags flags)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().receive(
|
||||
this->get_implementation(), buffers, flags, ec);
|
||||
std::size_t s = this->impl_.get_service().receive(
|
||||
this->impl_.get_implementation(), buffers, flags, ec);
|
||||
boost::asio::detail::throw_error(ec, "receive");
|
||||
return s;
|
||||
}
|
||||
@@ -659,8 +762,8 @@ public:
|
||||
std::size_t receive(const MutableBufferSequence& buffers,
|
||||
socket_base::message_flags flags, boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().receive(
|
||||
this->get_implementation(), buffers, flags, ec);
|
||||
return this->impl_.get_service().receive(
|
||||
this->impl_.get_implementation(), buffers, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive on a connected socket.
|
||||
@@ -681,9 +784,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes received.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @note The async_receive operation can only be used with a connected socket.
|
||||
* Use the async_receive_from function to receive data on an unconnected
|
||||
@@ -705,12 +808,10 @@ public:
|
||||
async_receive(const MutableBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
// If you get an error on the following line it means that your handler does
|
||||
// not meet the documented type requirements for a ReadHandler.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
return this->get_service().async_receive(this->get_implementation(),
|
||||
buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
return async_initiate<ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_receive(), handler, this,
|
||||
buffers, socket_base::message_flags(0));
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive on a connected socket.
|
||||
@@ -733,9 +834,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes received.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @note The async_receive operation can only be used with a connected socket.
|
||||
* Use the async_receive_from function to receive data on an unconnected
|
||||
@@ -748,12 +849,9 @@ public:
|
||||
socket_base::message_flags flags,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
// If you get an error on the following line it means that your handler does
|
||||
// not meet the documented type requirements for a ReadHandler.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
return this->get_service().async_receive(this->get_implementation(),
|
||||
buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
return async_initiate<ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_receive(), handler, this, buffers, flags);
|
||||
}
|
||||
|
||||
/// Receive a datagram with the endpoint of the sender.
|
||||
@@ -787,8 +885,8 @@ public:
|
||||
endpoint_type& sender_endpoint)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().receive_from(
|
||||
this->get_implementation(), buffers, sender_endpoint, 0, ec);
|
||||
std::size_t s = this->impl_.get_service().receive_from(
|
||||
this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec);
|
||||
boost::asio::detail::throw_error(ec, "receive_from");
|
||||
return s;
|
||||
}
|
||||
@@ -814,8 +912,8 @@ public:
|
||||
endpoint_type& sender_endpoint, socket_base::message_flags flags)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().receive_from(
|
||||
this->get_implementation(), buffers, sender_endpoint, flags, ec);
|
||||
std::size_t s = this->impl_.get_service().receive_from(
|
||||
this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
|
||||
boost::asio::detail::throw_error(ec, "receive_from");
|
||||
return s;
|
||||
}
|
||||
@@ -841,8 +939,8 @@ public:
|
||||
endpoint_type& sender_endpoint, socket_base::message_flags flags,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().receive_from(this->get_implementation(),
|
||||
buffers, sender_endpoint, flags, ec);
|
||||
return this->impl_.get_service().receive_from(
|
||||
this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive.
|
||||
@@ -868,9 +966,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes received.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @par Example
|
||||
* To receive into a single data buffer use the @ref buffer function as
|
||||
@@ -888,13 +986,10 @@ public:
|
||||
endpoint_type& sender_endpoint,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
// If you get an error on the following line it means that your handler does
|
||||
// not meet the documented type requirements for a ReadHandler.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
return this->get_service().async_receive_from(
|
||||
this->get_implementation(), buffers, sender_endpoint, 0,
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
return async_initiate<ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_receive_from(), handler, this, buffers,
|
||||
&sender_endpoint, socket_base::message_flags(0));
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive.
|
||||
@@ -922,9 +1017,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes received.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*/
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
|
||||
@@ -933,14 +1028,85 @@ public:
|
||||
endpoint_type& sender_endpoint, socket_base::message_flags flags,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
// If you get an error on the following line it means that your handler does
|
||||
// not meet the documented type requirements for a ReadHandler.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
return this->get_service().async_receive_from(
|
||||
this->get_implementation(), buffers, sender_endpoint, flags,
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
return async_initiate<ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_receive_from(), handler,
|
||||
this, buffers, &sender_endpoint, flags);
|
||||
}
|
||||
|
||||
private:
|
||||
struct initiate_async_send
|
||||
{
|
||||
template <typename WriteHandler, typename ConstBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
|
||||
basic_datagram_socket* self, const ConstBufferSequence& buffers,
|
||||
socket_base::message_flags flags) 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;
|
||||
|
||||
detail::non_const_lvalue<WriteHandler> handler2(handler);
|
||||
self->impl_.get_service().async_send(
|
||||
self->impl_.get_implementation(), buffers, flags,
|
||||
handler2.value, self->impl_.get_implementation_executor());
|
||||
}
|
||||
};
|
||||
|
||||
struct initiate_async_send_to
|
||||
{
|
||||
template <typename WriteHandler, typename ConstBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
|
||||
basic_datagram_socket* self, const ConstBufferSequence& buffers,
|
||||
const endpoint_type& destination,
|
||||
socket_base::message_flags flags) 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;
|
||||
|
||||
detail::non_const_lvalue<WriteHandler> handler2(handler);
|
||||
self->impl_.get_service().async_send_to(
|
||||
self->impl_.get_implementation(), buffers, destination, flags,
|
||||
handler2.value, self->impl_.get_implementation_executor());
|
||||
}
|
||||
};
|
||||
|
||||
struct initiate_async_receive
|
||||
{
|
||||
template <typename ReadHandler, typename MutableBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
|
||||
basic_datagram_socket* self, const MutableBufferSequence& buffers,
|
||||
socket_base::message_flags flags) 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.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
detail::non_const_lvalue<ReadHandler> handler2(handler);
|
||||
self->impl_.get_service().async_receive(
|
||||
self->impl_.get_implementation(), buffers, flags,
|
||||
handler2.value, self->impl_.get_implementation_executor());
|
||||
}
|
||||
};
|
||||
|
||||
struct initiate_async_receive_from
|
||||
{
|
||||
template <typename ReadHandler, typename MutableBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
|
||||
basic_datagram_socket* self, const MutableBufferSequence& buffers,
|
||||
endpoint_type* sender_endpoint, socket_base::message_flags flags) 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.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
detail::non_const_lvalue<ReadHandler> handler2(handler);
|
||||
self->impl_.get_service().async_receive_from(
|
||||
self->impl_.get_implementation(), buffers, *sender_endpoint, flags,
|
||||
handler2.value, self->impl_.get_implementation_executor());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// basic_deadline_timer.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -21,11 +21,15 @@
|
||||
|| defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/asio/basic_io_object.hpp>
|
||||
#include <boost/asio/deadline_timer_service.hpp>
|
||||
#include <boost/asio/detail/deadline_timer_service.hpp>
|
||||
#include <boost/asio/detail/handler_type_requirements.hpp>
|
||||
#include <boost/asio/detail/io_object_impl.hpp>
|
||||
#include <boost/asio/detail/non_const_lvalue.hpp>
|
||||
#include <boost/asio/detail/throw_error.hpp>
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/asio/execution_context.hpp>
|
||||
#include <boost/asio/executor.hpp>
|
||||
#include <boost/asio/time_traits.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
@@ -51,7 +55,7 @@ namespace asio {
|
||||
* Performing a blocking wait:
|
||||
* @code
|
||||
* // Construct a timer without setting an expiry time.
|
||||
* boost::asio::deadline_timer timer(io_service);
|
||||
* boost::asio::deadline_timer timer(my_context);
|
||||
*
|
||||
* // Set an expiry time relative to now.
|
||||
* timer.expires_from_now(boost::posix_time::seconds(5));
|
||||
@@ -74,7 +78,7 @@ namespace asio {
|
||||
* ...
|
||||
*
|
||||
* // Construct a timer with an absolute expiry time.
|
||||
* boost::asio::deadline_timer timer(io_service,
|
||||
* boost::asio::deadline_timer timer(my_context,
|
||||
* boost::posix_time::time_from_string("2005-12-07 23:59:59.000"));
|
||||
*
|
||||
* // Start an asynchronous wait.
|
||||
@@ -122,11 +126,13 @@ namespace asio {
|
||||
*/
|
||||
template <typename Time,
|
||||
typename TimeTraits = boost::asio::time_traits<Time>,
|
||||
typename TimerService = deadline_timer_service<Time, TimeTraits> >
|
||||
typename Executor = executor>
|
||||
class basic_deadline_timer
|
||||
: public basic_io_object<TimerService>
|
||||
{
|
||||
public:
|
||||
/// The type of the executor associated with the object.
|
||||
typedef Executor executor_type;
|
||||
|
||||
/// The time traits type.
|
||||
typedef TimeTraits traits_type;
|
||||
|
||||
@@ -142,11 +148,30 @@ public:
|
||||
* expires_at() or expires_from_now() functions must be called to set an
|
||||
* expiry time before the timer can be waited on.
|
||||
*
|
||||
* @param io_service The io_service object that the timer will use to dispatch
|
||||
* handlers for any asynchronous operations performed on the timer.
|
||||
* @param ex The I/O executor that the timer will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the timer.
|
||||
*/
|
||||
explicit basic_deadline_timer(boost::asio::io_service& io_service)
|
||||
: basic_io_object<TimerService>(io_service)
|
||||
explicit basic_deadline_timer(const executor_type& ex)
|
||||
: impl_(ex)
|
||||
{
|
||||
}
|
||||
|
||||
/// Constructor.
|
||||
/**
|
||||
* This constructor creates a timer without setting an expiry time. The
|
||||
* expires_at() or expires_from_now() functions must be called to set an
|
||||
* expiry time before the timer can be waited on.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the timer will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the timer.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
explicit basic_deadline_timer(ExecutionContext& context,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: impl_(context)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -154,18 +179,40 @@ public:
|
||||
/**
|
||||
* This constructor creates a timer and sets the expiry time.
|
||||
*
|
||||
* @param io_service The io_service object that the timer will use to dispatch
|
||||
* handlers for any asynchronous operations performed on the timer.
|
||||
* @param ex The I/O executor that the timer will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the timer.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer, expressed
|
||||
* as an absolute time.
|
||||
*/
|
||||
basic_deadline_timer(boost::asio::io_service& io_service,
|
||||
const time_type& expiry_time)
|
||||
: basic_io_object<TimerService>(io_service)
|
||||
basic_deadline_timer(const executor_type& ex, const time_type& expiry_time)
|
||||
: impl_(ex)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->service.expires_at(this->implementation, expiry_time, ec);
|
||||
impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_at");
|
||||
}
|
||||
|
||||
/// Constructor to set a particular expiry time as an absolute time.
|
||||
/**
|
||||
* This constructor creates a timer and sets the expiry time.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the timer will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the timer.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer, expressed
|
||||
* as an absolute time.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_deadline_timer(ExecutionContext& context, const time_type& expiry_time,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: impl_(context)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_at");
|
||||
}
|
||||
|
||||
@@ -173,21 +220,98 @@ public:
|
||||
/**
|
||||
* This constructor creates a timer and sets the expiry time.
|
||||
*
|
||||
* @param io_service The io_service object that the timer will use to dispatch
|
||||
* handlers for any asynchronous operations performed on the timer.
|
||||
* @param ex The I/O executor that the timer will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the timer.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer, relative to
|
||||
* now.
|
||||
*/
|
||||
basic_deadline_timer(boost::asio::io_service& io_service,
|
||||
basic_deadline_timer(const executor_type& ex,
|
||||
const duration_type& expiry_time)
|
||||
: basic_io_object<TimerService>(io_service)
|
||||
: impl_(ex)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->service.expires_from_now(this->implementation, expiry_time, ec);
|
||||
impl_.get_service().expires_from_now(
|
||||
impl_.get_implementation(), expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_from_now");
|
||||
}
|
||||
|
||||
/// Constructor to set a particular expiry time relative to now.
|
||||
/**
|
||||
* This constructor creates a timer and sets the expiry time.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the timer will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the timer.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer, relative to
|
||||
* now.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_deadline_timer(ExecutionContext& context,
|
||||
const duration_type& expiry_time,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: impl_(context)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
impl_.get_service().expires_from_now(
|
||||
impl_.get_implementation(), expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_from_now");
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
/// Move-construct a basic_deadline_timer from another.
|
||||
/**
|
||||
* This constructor moves a timer from one object to another.
|
||||
*
|
||||
* @param other The other basic_deadline_timer object from which the move will
|
||||
* occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_deadline_timer(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
basic_deadline_timer(basic_deadline_timer&& other)
|
||||
: impl_(std::move(other.impl_))
|
||||
{
|
||||
}
|
||||
|
||||
/// Move-assign a basic_deadline_timer from another.
|
||||
/**
|
||||
* This assignment operator moves a timer from one object to another. Cancels
|
||||
* any outstanding asynchronous operations associated with the target object.
|
||||
*
|
||||
* @param other The other basic_deadline_timer object from which the move will
|
||||
* occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_deadline_timer(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
basic_deadline_timer& operator=(basic_deadline_timer&& other)
|
||||
{
|
||||
impl_ = std::move(other.impl_);
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Destroys the timer.
|
||||
/**
|
||||
* This function destroys the timer, cancelling any outstanding asynchronous
|
||||
* wait operations associated with the timer as if by calling @c cancel.
|
||||
*/
|
||||
~basic_deadline_timer()
|
||||
{
|
||||
}
|
||||
|
||||
/// Get the executor associated with the object.
|
||||
executor_type get_executor() BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return impl_.get_executor();
|
||||
}
|
||||
|
||||
/// Cancel any asynchronous operations that are waiting on the timer.
|
||||
/**
|
||||
* This function forces the completion of any pending asynchronous wait
|
||||
@@ -213,7 +337,7 @@ public:
|
||||
std::size_t cancel()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->service.cancel(this->implementation, ec);
|
||||
std::size_t s = impl_.get_service().cancel(impl_.get_implementation(), ec);
|
||||
boost::asio::detail::throw_error(ec, "cancel");
|
||||
return s;
|
||||
}
|
||||
@@ -242,7 +366,7 @@ public:
|
||||
*/
|
||||
std::size_t cancel(boost::system::error_code& ec)
|
||||
{
|
||||
return this->service.cancel(this->implementation, ec);
|
||||
return impl_.get_service().cancel(impl_.get_implementation(), ec);
|
||||
}
|
||||
|
||||
/// Cancels one asynchronous operation that is waiting on the timer.
|
||||
@@ -272,7 +396,8 @@ public:
|
||||
std::size_t cancel_one()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->service.cancel_one(this->implementation, ec);
|
||||
std::size_t s = impl_.get_service().cancel_one(
|
||||
impl_.get_implementation(), ec);
|
||||
boost::asio::detail::throw_error(ec, "cancel_one");
|
||||
return s;
|
||||
}
|
||||
@@ -303,7 +428,7 @@ public:
|
||||
*/
|
||||
std::size_t cancel_one(boost::system::error_code& ec)
|
||||
{
|
||||
return this->service.cancel_one(this->implementation, ec);
|
||||
return impl_.get_service().cancel_one(impl_.get_implementation(), ec);
|
||||
}
|
||||
|
||||
/// Get the timer's expiry time as an absolute time.
|
||||
@@ -313,7 +438,7 @@ public:
|
||||
*/
|
||||
time_type expires_at() const
|
||||
{
|
||||
return this->service.expires_at(this->implementation);
|
||||
return impl_.get_service().expires_at(impl_.get_implementation());
|
||||
}
|
||||
|
||||
/// Set the timer's expiry time as an absolute time.
|
||||
@@ -341,8 +466,8 @@ public:
|
||||
std::size_t expires_at(const time_type& expiry_time)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->service.expires_at(
|
||||
this->implementation, expiry_time, ec);
|
||||
std::size_t s = impl_.get_service().expires_at(
|
||||
impl_.get_implementation(), expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_at");
|
||||
return s;
|
||||
}
|
||||
@@ -372,7 +497,8 @@ public:
|
||||
std::size_t expires_at(const time_type& expiry_time,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->service.expires_at(this->implementation, expiry_time, ec);
|
||||
return impl_.get_service().expires_at(
|
||||
impl_.get_implementation(), expiry_time, ec);
|
||||
}
|
||||
|
||||
/// Get the timer's expiry time relative to now.
|
||||
@@ -382,7 +508,7 @@ public:
|
||||
*/
|
||||
duration_type expires_from_now() const
|
||||
{
|
||||
return this->service.expires_from_now(this->implementation);
|
||||
return impl_.get_service().expires_from_now(impl_.get_implementation());
|
||||
}
|
||||
|
||||
/// Set the timer's expiry time relative to now.
|
||||
@@ -410,8 +536,8 @@ public:
|
||||
std::size_t expires_from_now(const duration_type& expiry_time)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->service.expires_from_now(
|
||||
this->implementation, expiry_time, ec);
|
||||
std::size_t s = impl_.get_service().expires_from_now(
|
||||
impl_.get_implementation(), expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_from_now");
|
||||
return s;
|
||||
}
|
||||
@@ -441,8 +567,8 @@ public:
|
||||
std::size_t expires_from_now(const duration_type& expiry_time,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->service.expires_from_now(
|
||||
this->implementation, expiry_time, ec);
|
||||
return impl_.get_service().expires_from_now(
|
||||
impl_.get_implementation(), expiry_time, ec);
|
||||
}
|
||||
|
||||
/// Perform a blocking wait on the timer.
|
||||
@@ -455,7 +581,7 @@ public:
|
||||
void wait()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->service.wait(this->implementation, ec);
|
||||
impl_.get_service().wait(impl_.get_implementation(), ec);
|
||||
boost::asio::detail::throw_error(ec, "wait");
|
||||
}
|
||||
|
||||
@@ -468,7 +594,7 @@ public:
|
||||
*/
|
||||
void wait(boost::system::error_code& ec)
|
||||
{
|
||||
this->service.wait(this->implementation, ec);
|
||||
impl_.get_service().wait(impl_.get_implementation(), ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous wait on the timer.
|
||||
@@ -491,22 +617,44 @@ public:
|
||||
* const boost::system::error_code& error // Result of operation.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*/
|
||||
template <typename WaitHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
|
||||
void (boost::system::error_code))
|
||||
async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
|
||||
{
|
||||
// If you get an error on the following line it means that your handler does
|
||||
// not meet the documented type requirements for a WaitHandler.
|
||||
BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
|
||||
|
||||
return this->service.async_wait(this->implementation,
|
||||
BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
|
||||
return async_initiate<WaitHandler, void (boost::system::error_code)>(
|
||||
initiate_async_wait(), handler, this);
|
||||
}
|
||||
|
||||
private:
|
||||
// Disallow copying and assignment.
|
||||
basic_deadline_timer(const basic_deadline_timer&) BOOST_ASIO_DELETED;
|
||||
basic_deadline_timer& operator=(
|
||||
const basic_deadline_timer&) BOOST_ASIO_DELETED;
|
||||
|
||||
struct initiate_async_wait
|
||||
{
|
||||
template <typename WaitHandler>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler,
|
||||
basic_deadline_timer* self) const
|
||||
{
|
||||
// If you get an error on the following line it means that your handler
|
||||
// does not meet the documented type requirements for a WaitHandler.
|
||||
BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
|
||||
|
||||
detail::non_const_lvalue<WaitHandler> handler2(handler);
|
||||
self->impl_.get_service().async_wait(
|
||||
self->impl_.get_implementation(), handler2.value,
|
||||
self->impl_.get_implementation_executor());
|
||||
}
|
||||
};
|
||||
|
||||
detail::io_object_impl<
|
||||
detail::deadline_timer_service<TimeTraits>, Executor> impl_;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// basic_io_object.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -16,7 +16,7 @@
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
@@ -68,17 +68,43 @@ public:
|
||||
/// The underlying implementation type of I/O object.
|
||||
typedef typename service_type::implementation_type implementation_type;
|
||||
|
||||
/// Get the io_service associated with the object.
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
/// (Deprecated: Use get_executor().) Get the io_context associated with the
|
||||
/// object.
|
||||
/**
|
||||
* This function may be used to obtain the io_service object that the I/O
|
||||
* This function may be used to obtain the io_context object that the I/O
|
||||
* object uses to dispatch handlers for asynchronous operations.
|
||||
*
|
||||
* @return A reference to the io_service object that the I/O object will use
|
||||
* @return A reference to the io_context object that the I/O object will use
|
||||
* to dispatch handlers. Ownership is not transferred to the caller.
|
||||
*/
|
||||
boost::asio::io_service& get_io_service()
|
||||
boost::asio::io_context& get_io_context()
|
||||
{
|
||||
return service.get_io_service();
|
||||
return service_.get_io_context();
|
||||
}
|
||||
|
||||
/// (Deprecated: Use get_executor().) Get the io_context associated with the
|
||||
/// object.
|
||||
/**
|
||||
* This function may be used to obtain the io_context object that the I/O
|
||||
* object uses to dispatch handlers for asynchronous operations.
|
||||
*
|
||||
* @return A reference to the io_context object that the I/O object will use
|
||||
* to dispatch handlers. Ownership is not transferred to the caller.
|
||||
*/
|
||||
boost::asio::io_context& get_io_service()
|
||||
{
|
||||
return service_.get_io_context();
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
/// The type of the executor associated with the object.
|
||||
typedef boost::asio::io_context::executor_type executor_type;
|
||||
|
||||
/// Get the executor associated with the object.
|
||||
executor_type get_executor() BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return service_.get_io_context().get_executor();
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -87,10 +113,10 @@ protected:
|
||||
* Performs:
|
||||
* @code get_service().construct(get_implementation()); @endcode
|
||||
*/
|
||||
explicit basic_io_object(boost::asio::io_service& io_service)
|
||||
: service(boost::asio::use_service<IoObjectService>(io_service))
|
||||
explicit basic_io_object(boost::asio::io_context& io_context)
|
||||
: service_(boost::asio::use_service<IoObjectService>(io_context))
|
||||
{
|
||||
service.construct(implementation);
|
||||
service_.construct(implementation_);
|
||||
}
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
@@ -127,47 +153,42 @@ protected:
|
||||
*/
|
||||
~basic_io_object()
|
||||
{
|
||||
service.destroy(implementation);
|
||||
service_.destroy(implementation_);
|
||||
}
|
||||
|
||||
/// Get the service associated with the I/O object.
|
||||
service_type& get_service()
|
||||
{
|
||||
return service;
|
||||
return service_;
|
||||
}
|
||||
|
||||
/// Get the service associated with the I/O object.
|
||||
const service_type& get_service() const
|
||||
{
|
||||
return service;
|
||||
return service_;
|
||||
}
|
||||
|
||||
/// (Deprecated: Use get_service().) The service associated with the I/O
|
||||
/// object.
|
||||
/**
|
||||
* @note Available only for services that do not support movability.
|
||||
*/
|
||||
service_type& service;
|
||||
|
||||
/// Get the underlying implementation of the I/O object.
|
||||
implementation_type& get_implementation()
|
||||
{
|
||||
return implementation;
|
||||
return implementation_;
|
||||
}
|
||||
|
||||
/// Get the underlying implementation of the I/O object.
|
||||
const implementation_type& get_implementation() const
|
||||
{
|
||||
return implementation;
|
||||
return implementation_;
|
||||
}
|
||||
|
||||
/// (Deprecated: Use get_implementation().) The underlying implementation of
|
||||
/// the I/O object.
|
||||
implementation_type implementation;
|
||||
|
||||
private:
|
||||
basic_io_object(const basic_io_object&);
|
||||
basic_io_object& operator=(const basic_io_object&);
|
||||
|
||||
// The service associated with the I/O object.
|
||||
service_type& service_;
|
||||
|
||||
/// The underlying implementation of the I/O object.
|
||||
implementation_type implementation_;
|
||||
};
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
@@ -179,43 +200,57 @@ public:
|
||||
typedef IoObjectService service_type;
|
||||
typedef typename service_type::implementation_type implementation_type;
|
||||
|
||||
boost::asio::io_service& get_io_service()
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
boost::asio::io_context& get_io_context()
|
||||
{
|
||||
return service_->get_io_service();
|
||||
return service_->get_io_context();
|
||||
}
|
||||
|
||||
boost::asio::io_context& get_io_service()
|
||||
{
|
||||
return service_->get_io_context();
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
typedef boost::asio::io_context::executor_type executor_type;
|
||||
|
||||
executor_type get_executor() BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return service_->get_io_context().get_executor();
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit basic_io_object(boost::asio::io_service& io_service)
|
||||
: service_(&boost::asio::use_service<IoObjectService>(io_service))
|
||||
explicit basic_io_object(boost::asio::io_context& io_context)
|
||||
: service_(&boost::asio::use_service<IoObjectService>(io_context))
|
||||
{
|
||||
service_->construct(implementation);
|
||||
service_->construct(implementation_);
|
||||
}
|
||||
|
||||
basic_io_object(basic_io_object&& other)
|
||||
: service_(&other.get_service())
|
||||
{
|
||||
service_->move_construct(implementation, other.implementation);
|
||||
service_->move_construct(implementation_, other.implementation_);
|
||||
}
|
||||
|
||||
template <typename IoObjectService1>
|
||||
basic_io_object(IoObjectService1& other_service,
|
||||
typename IoObjectService1::implementation_type& other_implementation)
|
||||
: service_(&boost::asio::use_service<IoObjectService>(
|
||||
other_service.get_io_service()))
|
||||
other_service.get_io_context()))
|
||||
{
|
||||
service_->converting_move_construct(implementation,
|
||||
service_->converting_move_construct(implementation_,
|
||||
other_service, other_implementation);
|
||||
}
|
||||
|
||||
~basic_io_object()
|
||||
{
|
||||
service_->destroy(implementation);
|
||||
service_->destroy(implementation_);
|
||||
}
|
||||
|
||||
basic_io_object& operator=(basic_io_object&& other)
|
||||
{
|
||||
service_->move_assign(implementation,
|
||||
*other.service_, other.implementation);
|
||||
service_->move_assign(implementation_,
|
||||
*other.service_, other.implementation_);
|
||||
service_ = other.service_;
|
||||
return *this;
|
||||
}
|
||||
@@ -232,21 +267,20 @@ protected:
|
||||
|
||||
implementation_type& get_implementation()
|
||||
{
|
||||
return implementation;
|
||||
return implementation_;
|
||||
}
|
||||
|
||||
const implementation_type& get_implementation() const
|
||||
{
|
||||
return implementation;
|
||||
return implementation_;
|
||||
}
|
||||
|
||||
implementation_type implementation;
|
||||
|
||||
private:
|
||||
basic_io_object(const basic_io_object&);
|
||||
void operator=(const basic_io_object&);
|
||||
|
||||
IoObjectService* service_;
|
||||
implementation_type implementation_;
|
||||
};
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// basic_raw_socket.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -19,16 +19,25 @@
|
||||
#include <cstddef>
|
||||
#include <boost/asio/basic_socket.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/raw_socket_service.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
#if !defined(BOOST_ASIO_BASIC_RAW_SOCKET_FWD_DECL)
|
||||
#define BOOST_ASIO_BASIC_RAW_SOCKET_FWD_DECL
|
||||
|
||||
// Forward declaration with defaulted arguments.
|
||||
template <typename Protocol, typename Executor = executor>
|
||||
class basic_raw_socket;
|
||||
|
||||
#endif // !defined(BOOST_ASIO_BASIC_RAW_SOCKET_FWD_DECL)
|
||||
|
||||
/// Provides raw-oriented socket functionality.
|
||||
/**
|
||||
* The basic_raw_socket class template provides asynchronous and blocking
|
||||
@@ -38,18 +47,29 @@ namespace asio {
|
||||
* @e Distinct @e objects: Safe.@n
|
||||
* @e Shared @e objects: Unsafe.
|
||||
*/
|
||||
template <typename Protocol,
|
||||
typename RawSocketService = raw_socket_service<Protocol> >
|
||||
template <typename Protocol, typename Executor>
|
||||
class basic_raw_socket
|
||||
: public basic_socket<Protocol, RawSocketService>
|
||||
: public basic_socket<Protocol, Executor>
|
||||
{
|
||||
public:
|
||||
/// (Deprecated: Use native_handle_type.) The native representation of a
|
||||
/// socket.
|
||||
typedef typename RawSocketService::native_handle_type native_type;
|
||||
/// The type of the executor associated with the object.
|
||||
typedef Executor executor_type;
|
||||
|
||||
/// Rebinds the socket type to another executor.
|
||||
template <typename Executor1>
|
||||
struct rebind_executor
|
||||
{
|
||||
/// The socket type when rebound to the specified executor.
|
||||
typedef basic_raw_socket<Protocol, Executor1> other;
|
||||
};
|
||||
|
||||
/// The native representation of a socket.
|
||||
typedef typename RawSocketService::native_handle_type native_handle_type;
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
typedef implementation_defined native_handle_type;
|
||||
#else
|
||||
typedef typename basic_socket<Protocol,
|
||||
Executor>::native_handle_type native_handle_type;
|
||||
#endif
|
||||
|
||||
/// The protocol type.
|
||||
typedef Protocol protocol_type;
|
||||
@@ -62,12 +82,29 @@ public:
|
||||
* This constructor creates a raw socket without opening it. The open()
|
||||
* function must be called before data can be sent or received on the socket.
|
||||
*
|
||||
* @param io_service The io_service object that the raw socket will use
|
||||
* to dispatch handlers for any asynchronous operations performed on the
|
||||
* socket.
|
||||
* @param ex The I/O executor that the socket will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*/
|
||||
explicit basic_raw_socket(boost::asio::io_service& io_service)
|
||||
: basic_socket<Protocol, RawSocketService>(io_service)
|
||||
explicit basic_raw_socket(const executor_type& ex)
|
||||
: basic_socket<Protocol, Executor>(ex)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a basic_raw_socket without opening it.
|
||||
/**
|
||||
* This constructor creates a raw socket without opening it. The open()
|
||||
* function must be called before data can be sent or received on the socket.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the socket will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the socket.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
explicit basic_raw_socket(ExecutionContext& context,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(context)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -75,17 +112,36 @@ public:
|
||||
/**
|
||||
* This constructor creates and opens a raw socket.
|
||||
*
|
||||
* @param io_service The io_service object that the raw socket will use
|
||||
* to dispatch handlers for any asynchronous operations performed on the
|
||||
* socket.
|
||||
* @param ex The I/O executor that the socket will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
basic_raw_socket(boost::asio::io_service& io_service,
|
||||
const protocol_type& protocol)
|
||||
: basic_socket<Protocol, RawSocketService>(io_service, protocol)
|
||||
basic_raw_socket(const executor_type& ex, const protocol_type& protocol)
|
||||
: basic_socket<Protocol, Executor>(ex, protocol)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct and open a basic_raw_socket.
|
||||
/**
|
||||
* This constructor creates and opens a raw socket.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the socket will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_raw_socket(ExecutionContext& context, const protocol_type& protocol,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(context, protocol)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -96,18 +152,41 @@ public:
|
||||
* to the specified endpoint on the local machine. The protocol used is the
|
||||
* protocol associated with the given endpoint.
|
||||
*
|
||||
* @param io_service The io_service object that the raw socket will use
|
||||
* to dispatch handlers for any asynchronous operations performed on the
|
||||
* socket.
|
||||
* @param ex The I/O executor that the socket will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*
|
||||
* @param endpoint An endpoint on the local machine to which the raw
|
||||
* socket will be bound.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
basic_raw_socket(boost::asio::io_service& io_service,
|
||||
const endpoint_type& endpoint)
|
||||
: basic_socket<Protocol, RawSocketService>(io_service, endpoint)
|
||||
basic_raw_socket(const executor_type& ex, const endpoint_type& endpoint)
|
||||
: basic_socket<Protocol, Executor>(ex, endpoint)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a basic_raw_socket, opening it and binding it to the given
|
||||
/// local endpoint.
|
||||
/**
|
||||
* This constructor creates a raw socket and automatically opens it bound
|
||||
* to the specified endpoint on the local machine. The protocol used is the
|
||||
* protocol associated with the given endpoint.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the socket will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the socket.
|
||||
*
|
||||
* @param endpoint An endpoint on the local machine to which the raw
|
||||
* socket will be bound.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_raw_socket(ExecutionContext& context, const endpoint_type& endpoint,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(context, endpoint)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -116,9 +195,8 @@ public:
|
||||
* This constructor creates a raw socket object to hold an existing
|
||||
* native socket.
|
||||
*
|
||||
* @param io_service The io_service object that the raw socket will use
|
||||
* to dispatch handlers for any asynchronous operations performed on the
|
||||
* socket.
|
||||
* @param ex The I/O executor that the socket will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
@@ -126,10 +204,34 @@ public:
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
basic_raw_socket(boost::asio::io_service& io_service,
|
||||
basic_raw_socket(const executor_type& ex,
|
||||
const protocol_type& protocol, const native_handle_type& native_socket)
|
||||
: basic_socket<Protocol, RawSocketService>(
|
||||
io_service, protocol, native_socket)
|
||||
: basic_socket<Protocol, Executor>(ex, protocol, native_socket)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a basic_raw_socket on an existing native socket.
|
||||
/**
|
||||
* This constructor creates a raw socket object to hold an existing
|
||||
* native socket.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the socket will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @param native_socket The new underlying socket implementation.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_raw_socket(ExecutionContext& context,
|
||||
const protocol_type& protocol, const native_handle_type& native_socket,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -142,11 +244,11 @@ public:
|
||||
* will occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_raw_socket(io_service&) constructor.
|
||||
* constructed using the @c basic_raw_socket(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
basic_raw_socket(basic_raw_socket&& other)
|
||||
: basic_socket<Protocol, RawSocketService>(
|
||||
BOOST_ASIO_MOVE_CAST(basic_raw_socket)(other))
|
||||
: basic_socket<Protocol, Executor>(std::move(other))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -158,31 +260,34 @@ public:
|
||||
* will occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_raw_socket(io_service&) constructor.
|
||||
* constructed using the @c basic_raw_socket(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
basic_raw_socket& operator=(basic_raw_socket&& other)
|
||||
{
|
||||
basic_socket<Protocol, RawSocketService>::operator=(
|
||||
BOOST_ASIO_MOVE_CAST(basic_raw_socket)(other));
|
||||
basic_socket<Protocol, Executor>::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Move-construct a basic_raw_socket from a socket of another protocol type.
|
||||
/// Move-construct a basic_raw_socket from a socket of another protocol
|
||||
/// type.
|
||||
/**
|
||||
* This constructor moves a raw socket from one object to another.
|
||||
*
|
||||
* @param other The other basic_raw_socket object from which the move will
|
||||
* occur.
|
||||
* @param other The other basic_raw_socket object from which the move
|
||||
* will occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_raw_socket(io_service&) constructor.
|
||||
* constructed using the @c basic_raw_socket(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
template <typename Protocol1, typename RawSocketService1>
|
||||
basic_raw_socket(basic_raw_socket<Protocol1, RawSocketService1>&& other,
|
||||
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
|
||||
: basic_socket<Protocol, RawSocketService>(
|
||||
BOOST_ASIO_MOVE_CAST2(basic_raw_socket<
|
||||
Protocol1, RawSocketService1>)(other))
|
||||
template <typename Protocol1, typename Executor1>
|
||||
basic_raw_socket(basic_raw_socket<Protocol1, Executor1>&& other,
|
||||
typename enable_if<
|
||||
is_convertible<Protocol1, Protocol>::value
|
||||
&& is_convertible<Executor1, Executor>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(std::move(other))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -194,20 +299,30 @@ public:
|
||||
* will occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_raw_socket(io_service&) constructor.
|
||||
* constructed using the @c basic_raw_socket(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
template <typename Protocol1, typename RawSocketService1>
|
||||
typename enable_if<is_convertible<Protocol1, Protocol>::value,
|
||||
basic_raw_socket>::type& operator=(
|
||||
basic_raw_socket<Protocol1, RawSocketService1>&& other)
|
||||
template <typename Protocol1, typename Executor1>
|
||||
typename enable_if<
|
||||
is_convertible<Protocol1, Protocol>::value
|
||||
&& is_convertible<Executor1, Executor>::value,
|
||||
basic_raw_socket&
|
||||
>::type operator=(basic_raw_socket<Protocol1, Executor1>&& other)
|
||||
{
|
||||
basic_socket<Protocol, RawSocketService>::operator=(
|
||||
BOOST_ASIO_MOVE_CAST2(basic_raw_socket<
|
||||
Protocol1, RawSocketService1>)(other));
|
||||
basic_socket<Protocol, Executor>::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Destroys the socket.
|
||||
/**
|
||||
* This function destroys the socket, cancelling any outstanding asynchronous
|
||||
* operations associated with the socket as if by calling @c cancel.
|
||||
*/
|
||||
~basic_raw_socket()
|
||||
{
|
||||
}
|
||||
|
||||
/// Send some data on a connected socket.
|
||||
/**
|
||||
* This function is used to send data on the raw socket. The function call
|
||||
@@ -233,8 +348,8 @@ public:
|
||||
std::size_t send(const ConstBufferSequence& buffers)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().send(
|
||||
this->get_implementation(), buffers, 0, ec);
|
||||
std::size_t s = this->impl_.get_service().send(
|
||||
this->impl_.get_implementation(), buffers, 0, ec);
|
||||
boost::asio::detail::throw_error(ec, "send");
|
||||
return s;
|
||||
}
|
||||
@@ -260,8 +375,8 @@ public:
|
||||
socket_base::message_flags flags)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().send(
|
||||
this->get_implementation(), buffers, flags, ec);
|
||||
std::size_t s = this->impl_.get_service().send(
|
||||
this->impl_.get_implementation(), buffers, flags, ec);
|
||||
boost::asio::detail::throw_error(ec, "send");
|
||||
return s;
|
||||
}
|
||||
@@ -286,8 +401,8 @@ public:
|
||||
std::size_t send(const ConstBufferSequence& buffers,
|
||||
socket_base::message_flags flags, boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().send(
|
||||
this->get_implementation(), buffers, flags, ec);
|
||||
return this->impl_.get_service().send(
|
||||
this->impl_.get_implementation(), buffers, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous send on a connected socket.
|
||||
@@ -308,9 +423,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes sent.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @note The async_send operation can only be used with a connected socket.
|
||||
* Use the async_send_to function to send data on an unconnected raw
|
||||
@@ -331,12 +446,10 @@ public:
|
||||
async_send(const ConstBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
// 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;
|
||||
|
||||
return this->get_service().async_send(this->get_implementation(),
|
||||
buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
return async_initiate<WriteHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_send(), handler, this,
|
||||
buffers, socket_base::message_flags(0));
|
||||
}
|
||||
|
||||
/// Start an asynchronous send on a connected socket.
|
||||
@@ -359,9 +472,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes sent.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @note The async_send operation can only be used with a connected socket.
|
||||
* Use the async_send_to function to send data on an unconnected raw
|
||||
@@ -374,12 +487,9 @@ public:
|
||||
socket_base::message_flags flags,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
// 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;
|
||||
|
||||
return this->get_service().async_send(this->get_implementation(),
|
||||
buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
return async_initiate<WriteHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_send(), handler, this, buffers, flags);
|
||||
}
|
||||
|
||||
/// Send raw data to the specified endpoint.
|
||||
@@ -412,8 +522,8 @@ public:
|
||||
const endpoint_type& destination)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().send_to(
|
||||
this->get_implementation(), buffers, destination, 0, ec);
|
||||
std::size_t s = this->impl_.get_service().send_to(
|
||||
this->impl_.get_implementation(), buffers, destination, 0, ec);
|
||||
boost::asio::detail::throw_error(ec, "send_to");
|
||||
return s;
|
||||
}
|
||||
@@ -439,8 +549,8 @@ public:
|
||||
const endpoint_type& destination, socket_base::message_flags flags)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().send_to(
|
||||
this->get_implementation(), buffers, destination, flags, ec);
|
||||
std::size_t s = this->impl_.get_service().send_to(
|
||||
this->impl_.get_implementation(), buffers, destination, flags, ec);
|
||||
boost::asio::detail::throw_error(ec, "send_to");
|
||||
return s;
|
||||
}
|
||||
@@ -466,7 +576,7 @@ public:
|
||||
const endpoint_type& destination, socket_base::message_flags flags,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().send_to(this->get_implementation(),
|
||||
return this->impl_.get_service().send_to(this->impl_.get_implementation(),
|
||||
buffers, destination, flags, ec);
|
||||
}
|
||||
|
||||
@@ -491,9 +601,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes sent.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @par Example
|
||||
* To send a single data buffer use the @ref buffer function as follows:
|
||||
@@ -514,12 +624,10 @@ public:
|
||||
const endpoint_type& destination,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
// 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;
|
||||
|
||||
return this->get_service().async_send_to(this->get_implementation(),
|
||||
buffers, destination, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
return async_initiate<WriteHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_send_to(), handler, this, buffers,
|
||||
destination, socket_base::message_flags(0));
|
||||
}
|
||||
|
||||
/// Start an asynchronous send.
|
||||
@@ -545,9 +653,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes sent.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*/
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
|
||||
@@ -556,13 +664,9 @@ public:
|
||||
const endpoint_type& destination, socket_base::message_flags flags,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
// 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;
|
||||
|
||||
return this->get_service().async_send_to(
|
||||
this->get_implementation(), buffers, destination, flags,
|
||||
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
return async_initiate<WriteHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_send_to(), handler, this, buffers, destination, flags);
|
||||
}
|
||||
|
||||
/// Receive some data on a connected socket.
|
||||
@@ -593,8 +697,8 @@ public:
|
||||
std::size_t receive(const MutableBufferSequence& buffers)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().receive(
|
||||
this->get_implementation(), buffers, 0, ec);
|
||||
std::size_t s = this->impl_.get_service().receive(
|
||||
this->impl_.get_implementation(), buffers, 0, ec);
|
||||
boost::asio::detail::throw_error(ec, "receive");
|
||||
return s;
|
||||
}
|
||||
@@ -622,8 +726,8 @@ public:
|
||||
socket_base::message_flags flags)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().receive(
|
||||
this->get_implementation(), buffers, flags, ec);
|
||||
std::size_t s = this->impl_.get_service().receive(
|
||||
this->impl_.get_implementation(), buffers, flags, ec);
|
||||
boost::asio::detail::throw_error(ec, "receive");
|
||||
return s;
|
||||
}
|
||||
@@ -650,8 +754,8 @@ public:
|
||||
std::size_t receive(const MutableBufferSequence& buffers,
|
||||
socket_base::message_flags flags, boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().receive(
|
||||
this->get_implementation(), buffers, flags, ec);
|
||||
return this->impl_.get_service().receive(
|
||||
this->impl_.get_implementation(), buffers, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive on a connected socket.
|
||||
@@ -672,9 +776,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes received.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @note The async_receive operation can only be used with a connected socket.
|
||||
* Use the async_receive_from function to receive data on an unconnected
|
||||
@@ -696,12 +800,10 @@ public:
|
||||
async_receive(const MutableBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
// If you get an error on the following line it means that your handler does
|
||||
// not meet the documented type requirements for a ReadHandler.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
return this->get_service().async_receive(this->get_implementation(),
|
||||
buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
return async_initiate<ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_receive(), handler, this,
|
||||
buffers, socket_base::message_flags(0));
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive on a connected socket.
|
||||
@@ -724,9 +826,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes received.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @note The async_receive operation can only be used with a connected socket.
|
||||
* Use the async_receive_from function to receive data on an unconnected
|
||||
@@ -739,12 +841,9 @@ public:
|
||||
socket_base::message_flags flags,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
// If you get an error on the following line it means that your handler does
|
||||
// not meet the documented type requirements for a ReadHandler.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
return this->get_service().async_receive(this->get_implementation(),
|
||||
buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
return async_initiate<ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_receive(), handler, this, buffers, flags);
|
||||
}
|
||||
|
||||
/// Receive raw data with the endpoint of the sender.
|
||||
@@ -778,8 +877,8 @@ public:
|
||||
endpoint_type& sender_endpoint)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().receive_from(
|
||||
this->get_implementation(), buffers, sender_endpoint, 0, ec);
|
||||
std::size_t s = this->impl_.get_service().receive_from(
|
||||
this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec);
|
||||
boost::asio::detail::throw_error(ec, "receive_from");
|
||||
return s;
|
||||
}
|
||||
@@ -805,8 +904,8 @@ public:
|
||||
endpoint_type& sender_endpoint, socket_base::message_flags flags)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().receive_from(
|
||||
this->get_implementation(), buffers, sender_endpoint, flags, ec);
|
||||
std::size_t s = this->impl_.get_service().receive_from(
|
||||
this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
|
||||
boost::asio::detail::throw_error(ec, "receive_from");
|
||||
return s;
|
||||
}
|
||||
@@ -832,8 +931,8 @@ public:
|
||||
endpoint_type& sender_endpoint, socket_base::message_flags flags,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().receive_from(this->get_implementation(),
|
||||
buffers, sender_endpoint, flags, ec);
|
||||
return this->impl_.get_service().receive_from(
|
||||
this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive.
|
||||
@@ -859,9 +958,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes received.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @par Example
|
||||
* To receive into a single data buffer use the @ref buffer function as
|
||||
@@ -879,13 +978,10 @@ public:
|
||||
endpoint_type& sender_endpoint,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
// If you get an error on the following line it means that your handler does
|
||||
// not meet the documented type requirements for a ReadHandler.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
return this->get_service().async_receive_from(
|
||||
this->get_implementation(), buffers, sender_endpoint, 0,
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
return async_initiate<ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_receive_from(), handler, this, buffers,
|
||||
&sender_endpoint, socket_base::message_flags(0));
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive.
|
||||
@@ -913,9 +1009,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes received.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*/
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
|
||||
@@ -924,14 +1020,85 @@ public:
|
||||
endpoint_type& sender_endpoint, socket_base::message_flags flags,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
// If you get an error on the following line it means that your handler does
|
||||
// not meet the documented type requirements for a ReadHandler.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
return this->get_service().async_receive_from(
|
||||
this->get_implementation(), buffers, sender_endpoint, flags,
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
return async_initiate<ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_receive_from(), handler,
|
||||
this, buffers, &sender_endpoint, flags);
|
||||
}
|
||||
|
||||
private:
|
||||
struct initiate_async_send
|
||||
{
|
||||
template <typename WriteHandler, typename ConstBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
|
||||
basic_raw_socket* self, const ConstBufferSequence& buffers,
|
||||
socket_base::message_flags flags) 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;
|
||||
|
||||
detail::non_const_lvalue<WriteHandler> handler2(handler);
|
||||
self->impl_.get_service().async_send(
|
||||
self->impl_.get_implementation(), buffers, flags,
|
||||
handler2.value, self->impl_.get_implementation_executor());
|
||||
}
|
||||
};
|
||||
|
||||
struct initiate_async_send_to
|
||||
{
|
||||
template <typename WriteHandler, typename ConstBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
|
||||
basic_raw_socket* self, const ConstBufferSequence& buffers,
|
||||
const endpoint_type& destination,
|
||||
socket_base::message_flags flags) 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;
|
||||
|
||||
detail::non_const_lvalue<WriteHandler> handler2(handler);
|
||||
self->impl_.get_service().async_send_to(
|
||||
self->impl_.get_implementation(), buffers, destination, flags,
|
||||
handler2.value, self->impl_.get_implementation_executor());
|
||||
}
|
||||
};
|
||||
|
||||
struct initiate_async_receive
|
||||
{
|
||||
template <typename ReadHandler, typename MutableBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
|
||||
basic_raw_socket* self, const MutableBufferSequence& buffers,
|
||||
socket_base::message_flags flags) 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.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
detail::non_const_lvalue<ReadHandler> handler2(handler);
|
||||
self->impl_.get_service().async_receive(
|
||||
self->impl_.get_implementation(), buffers, flags,
|
||||
handler2.value, self->impl_.get_implementation_executor());
|
||||
}
|
||||
};
|
||||
|
||||
struct initiate_async_receive_from
|
||||
{
|
||||
template <typename ReadHandler, typename MutableBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
|
||||
basic_raw_socket* self, const MutableBufferSequence& buffers,
|
||||
endpoint_type* sender_endpoint, socket_base::message_flags flags) 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.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
detail::non_const_lvalue<ReadHandler> handler2(handler);
|
||||
self->impl_.get_service().async_receive_from(
|
||||
self->impl_.get_implementation(), buffers, *sender_endpoint, flags,
|
||||
handler2.value, self->impl_.get_implementation_executor());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// basic_seq_packet_socket.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -21,13 +21,21 @@
|
||||
#include <boost/asio/detail/handler_type_requirements.hpp>
|
||||
#include <boost/asio/detail/throw_error.hpp>
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/asio/seq_packet_socket_service.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
#if !defined(BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL)
|
||||
#define BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL
|
||||
|
||||
// Forward declaration with defaulted arguments.
|
||||
template <typename Protocol, typename Executor = executor>
|
||||
class basic_seq_packet_socket;
|
||||
|
||||
#endif // !defined(BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL)
|
||||
|
||||
/// Provides sequenced packet socket functionality.
|
||||
/**
|
||||
* The basic_seq_packet_socket class template provides asynchronous and blocking
|
||||
@@ -37,19 +45,29 @@ namespace asio {
|
||||
* @e Distinct @e objects: Safe.@n
|
||||
* @e Shared @e objects: Unsafe.
|
||||
*/
|
||||
template <typename Protocol,
|
||||
typename SeqPacketSocketService = seq_packet_socket_service<Protocol> >
|
||||
template <typename Protocol, typename Executor>
|
||||
class basic_seq_packet_socket
|
||||
: public basic_socket<Protocol, SeqPacketSocketService>
|
||||
: public basic_socket<Protocol, Executor>
|
||||
{
|
||||
public:
|
||||
/// (Deprecated: Use native_handle_type.) The native representation of a
|
||||
/// socket.
|
||||
typedef typename SeqPacketSocketService::native_handle_type native_type;
|
||||
/// The type of the executor associated with the object.
|
||||
typedef Executor executor_type;
|
||||
|
||||
/// Rebinds the socket type to another executor.
|
||||
template <typename Executor1>
|
||||
struct rebind_executor
|
||||
{
|
||||
/// The socket type when rebound to the specified executor.
|
||||
typedef basic_seq_packet_socket<Protocol, Executor1> other;
|
||||
};
|
||||
|
||||
/// The native representation of a socket.
|
||||
typedef typename SeqPacketSocketService::native_handle_type
|
||||
native_handle_type;
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
typedef implementation_defined native_handle_type;
|
||||
#else
|
||||
typedef typename basic_socket<Protocol,
|
||||
Executor>::native_handle_type native_handle_type;
|
||||
#endif
|
||||
|
||||
/// The protocol type.
|
||||
typedef Protocol protocol_type;
|
||||
@@ -63,12 +81,30 @@ public:
|
||||
* socket needs to be opened and then connected or accepted before data can
|
||||
* be sent or received on it.
|
||||
*
|
||||
* @param io_service The io_service object that the sequenced packet socket
|
||||
* will use to dispatch handlers for any asynchronous operations performed on
|
||||
* the socket.
|
||||
* @param ex The I/O executor that the socket will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*/
|
||||
explicit basic_seq_packet_socket(boost::asio::io_service& io_service)
|
||||
: basic_socket<Protocol, SeqPacketSocketService>(io_service)
|
||||
explicit basic_seq_packet_socket(const executor_type& ex)
|
||||
: basic_socket<Protocol, Executor>(ex)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a basic_seq_packet_socket without opening it.
|
||||
/**
|
||||
* This constructor creates a sequenced packet socket without opening it. The
|
||||
* socket needs to be opened and then connected or accepted before data can
|
||||
* be sent or received on it.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the socket will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the socket.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
explicit basic_seq_packet_socket(ExecutionContext& context,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(context)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -78,17 +114,40 @@ public:
|
||||
* needs to be connected or accepted before data can be sent or received on
|
||||
* it.
|
||||
*
|
||||
* @param io_service The io_service object that the sequenced packet socket
|
||||
* will use to dispatch handlers for any asynchronous operations performed on
|
||||
* the socket.
|
||||
* @param ex The I/O executor that the socket will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
basic_seq_packet_socket(boost::asio::io_service& io_service,
|
||||
basic_seq_packet_socket(const executor_type& ex,
|
||||
const protocol_type& protocol)
|
||||
: basic_socket<Protocol, SeqPacketSocketService>(io_service, protocol)
|
||||
: basic_socket<Protocol, Executor>(ex, protocol)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct and open a basic_seq_packet_socket.
|
||||
/**
|
||||
* This constructor creates and opens a sequenced_packet socket. The socket
|
||||
* needs to be connected or accepted before data can be sent or received on
|
||||
* it.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the socket will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_seq_packet_socket(ExecutionContext& context,
|
||||
const protocol_type& protocol,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(context, protocol)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -99,18 +158,43 @@ public:
|
||||
* it bound to the specified endpoint on the local machine. The protocol used
|
||||
* is the protocol associated with the given endpoint.
|
||||
*
|
||||
* @param io_service The io_service object that the sequenced packet socket
|
||||
* will use to dispatch handlers for any asynchronous operations performed on
|
||||
* the socket.
|
||||
* @param ex The I/O executor that the socket will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*
|
||||
* @param endpoint An endpoint on the local machine to which the sequenced
|
||||
* packet socket will be bound.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
basic_seq_packet_socket(boost::asio::io_service& io_service,
|
||||
basic_seq_packet_socket(const executor_type& ex,
|
||||
const endpoint_type& endpoint)
|
||||
: basic_socket<Protocol, SeqPacketSocketService>(io_service, endpoint)
|
||||
: basic_socket<Protocol, Executor>(ex, endpoint)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a basic_seq_packet_socket, opening it and binding it to the
|
||||
/// given local endpoint.
|
||||
/**
|
||||
* This constructor creates a sequenced packet socket and automatically opens
|
||||
* it bound to the specified endpoint on the local machine. The protocol used
|
||||
* is the protocol associated with the given endpoint.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the socket will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the socket.
|
||||
*
|
||||
* @param endpoint An endpoint on the local machine to which the sequenced
|
||||
* packet socket will be bound.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_seq_packet_socket(ExecutionContext& context,
|
||||
const endpoint_type& endpoint,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(context, endpoint)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -119,9 +203,8 @@ public:
|
||||
* This constructor creates a sequenced packet socket object to hold an
|
||||
* existing native socket.
|
||||
*
|
||||
* @param io_service The io_service object that the sequenced packet socket
|
||||
* will use to dispatch handlers for any asynchronous operations performed on
|
||||
* the socket.
|
||||
* @param ex The I/O executor that the socket will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
@@ -129,10 +212,34 @@ public:
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
basic_seq_packet_socket(boost::asio::io_service& io_service,
|
||||
basic_seq_packet_socket(const executor_type& ex,
|
||||
const protocol_type& protocol, const native_handle_type& native_socket)
|
||||
: basic_socket<Protocol, SeqPacketSocketService>(
|
||||
io_service, protocol, native_socket)
|
||||
: basic_socket<Protocol, Executor>(ex, protocol, native_socket)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a basic_seq_packet_socket on an existing native socket.
|
||||
/**
|
||||
* This constructor creates a sequenced packet socket object to hold an
|
||||
* existing native socket.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the socket will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @param native_socket The new underlying socket implementation.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_seq_packet_socket(ExecutionContext& context,
|
||||
const protocol_type& protocol, const native_handle_type& native_socket,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -146,11 +253,11 @@ public:
|
||||
* will occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_seq_packet_socket(io_service&) constructor.
|
||||
* constructed using the @c basic_seq_packet_socket(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
basic_seq_packet_socket(basic_seq_packet_socket&& other)
|
||||
: basic_socket<Protocol, SeqPacketSocketService>(
|
||||
BOOST_ASIO_MOVE_CAST(basic_seq_packet_socket)(other))
|
||||
: basic_socket<Protocol, Executor>(std::move(other))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -163,12 +270,12 @@ public:
|
||||
* will occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_seq_packet_socket(io_service&) constructor.
|
||||
* constructed using the @c basic_seq_packet_socket(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other)
|
||||
{
|
||||
basic_socket<Protocol, SeqPacketSocketService>::operator=(
|
||||
BOOST_ASIO_MOVE_CAST(basic_seq_packet_socket)(other));
|
||||
basic_socket<Protocol, Executor>::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -182,15 +289,16 @@ public:
|
||||
* will occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_seq_packet_socket(io_service&) constructor.
|
||||
* constructed using the @c basic_seq_packet_socket(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
template <typename Protocol1, typename SeqPacketSocketService1>
|
||||
basic_seq_packet_socket(
|
||||
basic_seq_packet_socket<Protocol1, SeqPacketSocketService1>&& other,
|
||||
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
|
||||
: basic_socket<Protocol, SeqPacketSocketService>(
|
||||
BOOST_ASIO_MOVE_CAST2(basic_seq_packet_socket<
|
||||
Protocol1, SeqPacketSocketService1>)(other))
|
||||
template <typename Protocol1, typename Executor1>
|
||||
basic_seq_packet_socket(basic_seq_packet_socket<Protocol1, Executor1>&& other,
|
||||
typename enable_if<
|
||||
is_convertible<Protocol1, Protocol>::value
|
||||
&& is_convertible<Executor1, Executor>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(std::move(other))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -204,20 +312,30 @@ public:
|
||||
* will occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_seq_packet_socket(io_service&) constructor.
|
||||
* constructed using the @c basic_seq_packet_socket(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
template <typename Protocol1, typename SeqPacketSocketService1>
|
||||
typename enable_if<is_convertible<Protocol1, Protocol>::value,
|
||||
basic_seq_packet_socket>::type& operator=(
|
||||
basic_seq_packet_socket<Protocol1, SeqPacketSocketService1>&& other)
|
||||
template <typename Protocol1, typename Executor1>
|
||||
typename enable_if<
|
||||
is_convertible<Protocol1, Protocol>::value
|
||||
&& is_convertible<Executor1, Executor>::value,
|
||||
basic_seq_packet_socket&
|
||||
>::type operator=(basic_seq_packet_socket<Protocol1, Executor1>&& other)
|
||||
{
|
||||
basic_socket<Protocol, SeqPacketSocketService>::operator=(
|
||||
BOOST_ASIO_MOVE_CAST2(basic_seq_packet_socket<
|
||||
Protocol1, SeqPacketSocketService1>)(other));
|
||||
basic_socket<Protocol, Executor>::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Destroys the socket.
|
||||
/**
|
||||
* This function destroys the socket, cancelling any outstanding asynchronous
|
||||
* operations associated with the socket as if by calling @c cancel.
|
||||
*/
|
||||
~basic_seq_packet_socket()
|
||||
{
|
||||
}
|
||||
|
||||
/// Send some data on the socket.
|
||||
/**
|
||||
* This function is used to send data on the sequenced packet socket. The
|
||||
@@ -246,8 +364,8 @@ public:
|
||||
socket_base::message_flags flags)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().send(
|
||||
this->get_implementation(), buffers, flags, ec);
|
||||
std::size_t s = this->impl_.get_service().send(
|
||||
this->impl_.get_implementation(), buffers, flags, ec);
|
||||
boost::asio::detail::throw_error(ec, "send");
|
||||
return s;
|
||||
}
|
||||
@@ -274,8 +392,8 @@ public:
|
||||
std::size_t send(const ConstBufferSequence& buffers,
|
||||
socket_base::message_flags flags, boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().send(
|
||||
this->get_implementation(), buffers, flags, ec);
|
||||
return this->impl_.get_service().send(
|
||||
this->impl_.get_implementation(), buffers, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous send.
|
||||
@@ -298,9 +416,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes sent.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @par Example
|
||||
* To send a single data buffer use the @ref buffer function as follows:
|
||||
@@ -318,12 +436,9 @@ public:
|
||||
socket_base::message_flags flags,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
// 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;
|
||||
|
||||
return this->get_service().async_send(this->get_implementation(),
|
||||
buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
return async_initiate<WriteHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_send(), handler, this, buffers, flags);
|
||||
}
|
||||
|
||||
/// Receive some data on the socket.
|
||||
@@ -360,8 +475,8 @@ public:
|
||||
socket_base::message_flags& out_flags)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().receive(
|
||||
this->get_implementation(), buffers, 0, out_flags, ec);
|
||||
std::size_t s = this->impl_.get_service().receive_with_flags(
|
||||
this->impl_.get_implementation(), buffers, 0, out_flags, ec);
|
||||
boost::asio::detail::throw_error(ec, "receive");
|
||||
return s;
|
||||
}
|
||||
@@ -407,8 +522,8 @@ public:
|
||||
socket_base::message_flags& out_flags)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().receive(
|
||||
this->get_implementation(), buffers, in_flags, out_flags, ec);
|
||||
std::size_t s = this->impl_.get_service().receive_with_flags(
|
||||
this->impl_.get_implementation(), buffers, in_flags, out_flags, ec);
|
||||
boost::asio::detail::throw_error(ec, "receive");
|
||||
return s;
|
||||
}
|
||||
@@ -441,8 +556,8 @@ public:
|
||||
socket_base::message_flags in_flags,
|
||||
socket_base::message_flags& out_flags, boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().receive(this->get_implementation(),
|
||||
buffers, in_flags, out_flags, ec);
|
||||
return this->impl_.get_service().receive_with_flags(
|
||||
this->impl_.get_implementation(), buffers, in_flags, out_flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive.
|
||||
@@ -469,9 +584,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes received.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @par Example
|
||||
* To receive into a single data buffer use the @ref buffer function as
|
||||
@@ -490,13 +605,10 @@ public:
|
||||
socket_base::message_flags& out_flags,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
// If you get an error on the following line it means that your handler does
|
||||
// not meet the documented type requirements for a ReadHandler.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
return this->get_service().async_receive(
|
||||
this->get_implementation(), buffers, 0, out_flags,
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
return async_initiate<ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_receive_with_flags(), handler, this,
|
||||
buffers, socket_base::message_flags(0), &out_flags);
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive.
|
||||
@@ -525,9 +637,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes received.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @par Example
|
||||
* To receive into a single data buffer use the @ref buffer function as
|
||||
@@ -549,14 +661,49 @@ public:
|
||||
socket_base::message_flags& out_flags,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
// If you get an error on the following line it means that your handler does
|
||||
// not meet the documented type requirements for a ReadHandler.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
return this->get_service().async_receive(
|
||||
this->get_implementation(), buffers, in_flags, out_flags,
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
return async_initiate<ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_receive_with_flags(), handler,
|
||||
this, buffers, in_flags, &out_flags);
|
||||
}
|
||||
|
||||
private:
|
||||
struct initiate_async_send
|
||||
{
|
||||
template <typename WriteHandler, typename ConstBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
|
||||
basic_seq_packet_socket* self, const ConstBufferSequence& buffers,
|
||||
socket_base::message_flags flags) 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;
|
||||
|
||||
detail::non_const_lvalue<WriteHandler> handler2(handler);
|
||||
self->impl_.get_service().async_send(
|
||||
self->impl_.get_implementation(), buffers, flags,
|
||||
handler2.value, self->impl_.get_implementation_executor());
|
||||
}
|
||||
};
|
||||
|
||||
struct initiate_async_receive_with_flags
|
||||
{
|
||||
template <typename ReadHandler, typename MutableBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
|
||||
basic_seq_packet_socket* self, const MutableBufferSequence& buffers,
|
||||
socket_base::message_flags in_flags,
|
||||
socket_base::message_flags* out_flags) 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.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
detail::non_const_lvalue<ReadHandler> handler2(handler);
|
||||
self->impl_.get_service().async_receive_with_flags(
|
||||
self->impl_.get_implementation(), buffers, in_flags, *out_flags,
|
||||
handler2.value, self->impl_.get_implementation_executor());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// basic_serial_port.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2019 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
|
||||
@@ -22,12 +22,25 @@
|
||||
|| defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
#include <string>
|
||||
#include <boost/asio/basic_io_object.hpp>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/detail/handler_type_requirements.hpp>
|
||||
#include <boost/asio/detail/io_object_impl.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/execution_context.hpp>
|
||||
#include <boost/asio/executor.hpp>
|
||||
#include <boost/asio/serial_port_base.hpp>
|
||||
#include <boost/asio/serial_port_service.hpp>
|
||||
#if defined(BOOST_ASIO_HAS_IOCP)
|
||||
# include <boost/asio/detail/win_iocp_serial_port_service.hpp>
|
||||
#else
|
||||
# include <boost/asio/detail/reactive_serial_port_service.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
# include <utility>
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
@@ -36,38 +49,63 @@ namespace asio {
|
||||
|
||||
/// Provides serial port functionality.
|
||||
/**
|
||||
* The basic_serial_port class template provides functionality that is common
|
||||
* to all serial ports.
|
||||
* The basic_serial_port class provides a wrapper over serial port
|
||||
* functionality.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* @e Distinct @e objects: Safe.@n
|
||||
* @e Shared @e objects: Unsafe.
|
||||
*/
|
||||
template <typename SerialPortService = serial_port_service>
|
||||
template <typename Executor = executor>
|
||||
class basic_serial_port
|
||||
: public basic_io_object<SerialPortService>,
|
||||
public serial_port_base
|
||||
: public serial_port_base
|
||||
{
|
||||
public:
|
||||
/// (Deprecated: Use native_handle_type.) The native representation of a
|
||||
/// serial port.
|
||||
typedef typename SerialPortService::native_handle_type native_type;
|
||||
/// The type of the executor associated with the object.
|
||||
typedef Executor executor_type;
|
||||
|
||||
/// The native representation of a serial port.
|
||||
typedef typename SerialPortService::native_handle_type native_handle_type;
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
typedef implementation_defined native_handle_type;
|
||||
#elif defined(BOOST_ASIO_HAS_IOCP)
|
||||
typedef detail::win_iocp_serial_port_service::native_handle_type
|
||||
native_handle_type;
|
||||
#else
|
||||
typedef detail::reactive_serial_port_service::native_handle_type
|
||||
native_handle_type;
|
||||
#endif
|
||||
|
||||
/// A basic_serial_port is always the lowest layer.
|
||||
typedef basic_serial_port<SerialPortService> lowest_layer_type;
|
||||
/// A basic_basic_serial_port is always the lowest layer.
|
||||
typedef basic_serial_port lowest_layer_type;
|
||||
|
||||
/// Construct a basic_serial_port without opening it.
|
||||
/**
|
||||
* This constructor creates a serial port without opening it.
|
||||
*
|
||||
* @param io_service The io_service object that the serial port will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the port.
|
||||
* @param ex The I/O executor that the serial port will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the
|
||||
* serial port.
|
||||
*/
|
||||
explicit basic_serial_port(boost::asio::io_service& io_service)
|
||||
: basic_io_object<SerialPortService>(io_service)
|
||||
explicit basic_serial_port(const executor_type& ex)
|
||||
: impl_(ex)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a basic_serial_port without opening it.
|
||||
/**
|
||||
* This constructor creates a serial port without opening it.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the serial port will use, by default, to dispatch handlers for any
|
||||
* asynchronous operations performed on the serial port.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
explicit basic_serial_port(ExecutionContext& context,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||
basic_serial_port
|
||||
>::type* = 0)
|
||||
: impl_(context)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -76,18 +114,18 @@ public:
|
||||
* This constructor creates and opens a serial port for the specified device
|
||||
* name.
|
||||
*
|
||||
* @param io_service The io_service object that the serial port will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the port.
|
||||
* @param ex The I/O executor that the serial port will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the
|
||||
* serial port.
|
||||
*
|
||||
* @param device The platform-specific device name for this serial
|
||||
* port.
|
||||
*/
|
||||
explicit basic_serial_port(boost::asio::io_service& io_service,
|
||||
const char* device)
|
||||
: basic_io_object<SerialPortService>(io_service)
|
||||
basic_serial_port(const executor_type& ex, const char* device)
|
||||
: impl_(ex)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->get_service().open(this->get_implementation(), device, ec);
|
||||
impl_.get_service().open(impl_.get_implementation(), device, ec);
|
||||
boost::asio::detail::throw_error(ec, "open");
|
||||
}
|
||||
|
||||
@@ -96,18 +134,66 @@ public:
|
||||
* This constructor creates and opens a serial port for the specified device
|
||||
* name.
|
||||
*
|
||||
* @param io_service The io_service object that the serial port will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the port.
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the serial port will use, by default, to dispatch handlers for any
|
||||
* asynchronous operations performed on the serial port.
|
||||
*
|
||||
* @param device The platform-specific device name for this serial
|
||||
* port.
|
||||
*/
|
||||
explicit basic_serial_port(boost::asio::io_service& io_service,
|
||||
const std::string& device)
|
||||
: basic_io_object<SerialPortService>(io_service)
|
||||
template <typename ExecutionContext>
|
||||
basic_serial_port(ExecutionContext& context, const char* device,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: impl_(context)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->get_service().open(this->get_implementation(), device, ec);
|
||||
impl_.get_service().open(impl_.get_implementation(), device, ec);
|
||||
boost::asio::detail::throw_error(ec, "open");
|
||||
}
|
||||
|
||||
/// Construct and open a basic_serial_port.
|
||||
/**
|
||||
* This constructor creates and opens a serial port for the specified device
|
||||
* name.
|
||||
*
|
||||
* @param ex The I/O executor that the serial port will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the
|
||||
* serial port.
|
||||
*
|
||||
* @param device The platform-specific device name for this serial
|
||||
* port.
|
||||
*/
|
||||
basic_serial_port(const executor_type& ex, const std::string& device)
|
||||
: impl_(ex)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
impl_.get_service().open(impl_.get_implementation(), device, ec);
|
||||
boost::asio::detail::throw_error(ec, "open");
|
||||
}
|
||||
|
||||
/// Construct and open a basic_serial_port.
|
||||
/**
|
||||
* This constructor creates and opens a serial port for the specified device
|
||||
* name.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the serial port will use, by default, to dispatch handlers for any
|
||||
* asynchronous operations performed on the serial port.
|
||||
*
|
||||
* @param device The platform-specific device name for this serial
|
||||
* port.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_serial_port(ExecutionContext& context, const std::string& device,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: impl_(context)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
impl_.get_service().open(impl_.get_implementation(), device, ec);
|
||||
boost::asio::detail::throw_error(ec, "open");
|
||||
}
|
||||
|
||||
@@ -116,19 +202,47 @@ public:
|
||||
* This constructor creates a serial port object to hold an existing native
|
||||
* serial port.
|
||||
*
|
||||
* @param io_service The io_service object that the serial port will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the port.
|
||||
* @param ex The I/O executor that the serial port will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the
|
||||
* serial port.
|
||||
*
|
||||
* @param native_serial_port A native serial port.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
basic_serial_port(boost::asio::io_service& io_service,
|
||||
basic_serial_port(const executor_type& ex,
|
||||
const native_handle_type& native_serial_port)
|
||||
: basic_io_object<SerialPortService>(io_service)
|
||||
: impl_(ex)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->get_service().assign(this->get_implementation(),
|
||||
impl_.get_service().assign(impl_.get_implementation(),
|
||||
native_serial_port, ec);
|
||||
boost::asio::detail::throw_error(ec, "assign");
|
||||
}
|
||||
|
||||
/// Construct a basic_serial_port on an existing native serial port.
|
||||
/**
|
||||
* This constructor creates a serial port object to hold an existing native
|
||||
* serial port.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the serial port will use, by default, to dispatch handlers for any
|
||||
* asynchronous operations performed on the serial port.
|
||||
*
|
||||
* @param native_serial_port A native serial port.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_serial_port(ExecutionContext& context,
|
||||
const native_handle_type& native_serial_port,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: impl_(context)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
impl_.get_service().assign(impl_.get_implementation(),
|
||||
native_serial_port, ec);
|
||||
boost::asio::detail::throw_error(ec, "assign");
|
||||
}
|
||||
@@ -142,11 +256,11 @@ public:
|
||||
* occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_serial_port(io_service&) constructor.
|
||||
* constructed using the @c basic_serial_port(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
basic_serial_port(basic_serial_port&& other)
|
||||
: basic_io_object<SerialPortService>(
|
||||
BOOST_ASIO_MOVE_CAST(basic_serial_port)(other))
|
||||
: impl_(std::move(other.impl_))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -158,16 +272,32 @@ public:
|
||||
* occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_serial_port(io_service&) constructor.
|
||||
* constructed using the @c basic_serial_port(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
basic_serial_port& operator=(basic_serial_port&& other)
|
||||
{
|
||||
basic_io_object<SerialPortService>::operator=(
|
||||
BOOST_ASIO_MOVE_CAST(basic_serial_port)(other));
|
||||
impl_ = std::move(other.impl_);
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Destroys the serial port.
|
||||
/**
|
||||
* This function destroys the serial port, cancelling any outstanding
|
||||
* asynchronous wait operations associated with the serial port as if by
|
||||
* calling @c cancel.
|
||||
*/
|
||||
~basic_serial_port()
|
||||
{
|
||||
}
|
||||
|
||||
/// Get the executor associated with the object.
|
||||
executor_type get_executor() BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return impl_.get_executor();
|
||||
}
|
||||
|
||||
/// Get a reference to the lowest layer.
|
||||
/**
|
||||
* This function returns a reference to the lowest layer in a stack of
|
||||
@@ -207,7 +337,7 @@ public:
|
||||
void open(const std::string& device)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->get_service().open(this->get_implementation(), device, ec);
|
||||
impl_.get_service().open(impl_.get_implementation(), device, ec);
|
||||
boost::asio::detail::throw_error(ec, "open");
|
||||
}
|
||||
|
||||
@@ -220,10 +350,11 @@ public:
|
||||
*
|
||||
* @param ec Set the indicate what error occurred, if any.
|
||||
*/
|
||||
boost::system::error_code open(const std::string& device,
|
||||
BOOST_ASIO_SYNC_OP_VOID open(const std::string& device,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().open(this->get_implementation(), device, ec);
|
||||
impl_.get_service().open(impl_.get_implementation(), device, ec);
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
/// Assign an existing native serial port to the serial port.
|
||||
@@ -237,7 +368,7 @@ public:
|
||||
void assign(const native_handle_type& native_serial_port)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->get_service().assign(this->get_implementation(),
|
||||
impl_.get_service().assign(impl_.get_implementation(),
|
||||
native_serial_port, ec);
|
||||
boost::asio::detail::throw_error(ec, "assign");
|
||||
}
|
||||
@@ -250,17 +381,18 @@ public:
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
boost::system::error_code assign(const native_handle_type& native_serial_port,
|
||||
BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_serial_port,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().assign(this->get_implementation(),
|
||||
impl_.get_service().assign(impl_.get_implementation(),
|
||||
native_serial_port, ec);
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
/// Determine whether the serial port is open.
|
||||
bool is_open() const
|
||||
{
|
||||
return this->get_service().is_open(this->get_implementation());
|
||||
return impl_.get_service().is_open(impl_.get_implementation());
|
||||
}
|
||||
|
||||
/// Close the serial port.
|
||||
@@ -274,7 +406,7 @@ public:
|
||||
void close()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->get_service().close(this->get_implementation(), ec);
|
||||
impl_.get_service().close(impl_.get_implementation(), ec);
|
||||
boost::asio::detail::throw_error(ec, "close");
|
||||
}
|
||||
|
||||
@@ -286,21 +418,10 @@ public:
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
boost::system::error_code close(boost::system::error_code& ec)
|
||||
BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().close(this->get_implementation(), ec);
|
||||
}
|
||||
|
||||
/// (Deprecated: Use native_handle().) Get the native serial port
|
||||
/// representation.
|
||||
/**
|
||||
* This function may be used to obtain the underlying representation of the
|
||||
* serial port. This is intended to allow access to native serial port
|
||||
* functionality that is not otherwise provided.
|
||||
*/
|
||||
native_type native()
|
||||
{
|
||||
return this->get_service().native_handle(this->get_implementation());
|
||||
impl_.get_service().close(impl_.get_implementation(), ec);
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
/// Get the native serial port representation.
|
||||
@@ -311,7 +432,7 @@ public:
|
||||
*/
|
||||
native_handle_type native_handle()
|
||||
{
|
||||
return this->get_service().native_handle(this->get_implementation());
|
||||
return impl_.get_service().native_handle(impl_.get_implementation());
|
||||
}
|
||||
|
||||
/// Cancel all asynchronous operations associated with the serial port.
|
||||
@@ -325,7 +446,7 @@ public:
|
||||
void cancel()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->get_service().cancel(this->get_implementation(), ec);
|
||||
impl_.get_service().cancel(impl_.get_implementation(), ec);
|
||||
boost::asio::detail::throw_error(ec, "cancel");
|
||||
}
|
||||
|
||||
@@ -337,9 +458,10 @@ public:
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
boost::system::error_code cancel(boost::system::error_code& ec)
|
||||
BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().cancel(this->get_implementation(), ec);
|
||||
impl_.get_service().cancel(impl_.get_implementation(), ec);
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
/// Send a break sequence to the serial port.
|
||||
@@ -352,7 +474,7 @@ public:
|
||||
void send_break()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->get_service().send_break(this->get_implementation(), ec);
|
||||
impl_.get_service().send_break(impl_.get_implementation(), ec);
|
||||
boost::asio::detail::throw_error(ec, "send_break");
|
||||
}
|
||||
|
||||
@@ -363,9 +485,10 @@ public:
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
boost::system::error_code send_break(boost::system::error_code& ec)
|
||||
BOOST_ASIO_SYNC_OP_VOID send_break(boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().send_break(this->get_implementation(), ec);
|
||||
impl_.get_service().send_break(impl_.get_implementation(), ec);
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
/// Set an option on the serial port.
|
||||
@@ -387,7 +510,7 @@ public:
|
||||
void set_option(const SettableSerialPortOption& option)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->get_service().set_option(this->get_implementation(), option, ec);
|
||||
impl_.get_service().set_option(impl_.get_implementation(), option, ec);
|
||||
boost::asio::detail::throw_error(ec, "set_option");
|
||||
}
|
||||
|
||||
@@ -407,11 +530,11 @@ public:
|
||||
* boost::asio::serial_port_base::character_size
|
||||
*/
|
||||
template <typename SettableSerialPortOption>
|
||||
boost::system::error_code set_option(const SettableSerialPortOption& option,
|
||||
BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSerialPortOption& option,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().set_option(
|
||||
this->get_implementation(), option, ec);
|
||||
impl_.get_service().set_option(impl_.get_implementation(), option, ec);
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
/// Get an option from the serial port.
|
||||
@@ -434,7 +557,7 @@ public:
|
||||
void get_option(GettableSerialPortOption& option)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->get_service().get_option(this->get_implementation(), option, ec);
|
||||
impl_.get_service().get_option(impl_.get_implementation(), option, ec);
|
||||
boost::asio::detail::throw_error(ec, "get_option");
|
||||
}
|
||||
|
||||
@@ -455,11 +578,11 @@ public:
|
||||
* boost::asio::serial_port_base::character_size
|
||||
*/
|
||||
template <typename GettableSerialPortOption>
|
||||
boost::system::error_code get_option(GettableSerialPortOption& option,
|
||||
BOOST_ASIO_SYNC_OP_VOID get_option(GettableSerialPortOption& option,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().get_option(
|
||||
this->get_implementation(), option, ec);
|
||||
impl_.get_service().get_option(impl_.get_implementation(), option, ec);
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
/// Write some data to the serial port.
|
||||
@@ -483,7 +606,7 @@ public:
|
||||
* @par Example
|
||||
* To write a single data buffer use the @ref buffer function as follows:
|
||||
* @code
|
||||
* serial_port.write_some(boost::asio::buffer(data, size));
|
||||
* basic_serial_port.write_some(boost::asio::buffer(data, size));
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on writing multiple
|
||||
* buffers in one go, and how to use it with arrays, boost::array or
|
||||
@@ -493,8 +616,8 @@ public:
|
||||
std::size_t write_some(const ConstBufferSequence& buffers)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().write_some(
|
||||
this->get_implementation(), buffers, ec);
|
||||
std::size_t s = impl_.get_service().write_some(
|
||||
impl_.get_implementation(), buffers, ec);
|
||||
boost::asio::detail::throw_error(ec, "write_some");
|
||||
return s;
|
||||
}
|
||||
@@ -519,8 +642,8 @@ public:
|
||||
std::size_t write_some(const ConstBufferSequence& buffers,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().write_some(
|
||||
this->get_implementation(), buffers, ec);
|
||||
return impl_.get_service().write_some(
|
||||
impl_.get_implementation(), buffers, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous write.
|
||||
@@ -541,9 +664,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes written.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @note The write operation may not transmit all of the data to the peer.
|
||||
* Consider using the @ref async_write function if you need to ensure that all
|
||||
@@ -552,7 +675,8 @@ public:
|
||||
* @par Example
|
||||
* To write a single data buffer use the @ref buffer function as follows:
|
||||
* @code
|
||||
* serial_port.async_write_some(boost::asio::buffer(data, size), handler);
|
||||
* basic_serial_port.async_write_some(
|
||||
* boost::asio::buffer(data, size), handler);
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on writing multiple
|
||||
* buffers in one go, and how to use it with arrays, boost::array or
|
||||
@@ -564,12 +688,9 @@ public:
|
||||
async_write_some(const ConstBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
// 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;
|
||||
|
||||
return this->get_service().async_write_some(this->get_implementation(),
|
||||
buffers, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
return async_initiate<WriteHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_write_some(), handler, this, buffers);
|
||||
}
|
||||
|
||||
/// Read some data from the serial port.
|
||||
@@ -594,7 +715,7 @@ public:
|
||||
* @par Example
|
||||
* To read into a single data buffer use the @ref buffer function as follows:
|
||||
* @code
|
||||
* serial_port.read_some(boost::asio::buffer(data, size));
|
||||
* basic_serial_port.read_some(boost::asio::buffer(data, size));
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on reading into multiple
|
||||
* buffers in one go, and how to use it with arrays, boost::array or
|
||||
@@ -604,8 +725,8 @@ public:
|
||||
std::size_t read_some(const MutableBufferSequence& buffers)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().read_some(
|
||||
this->get_implementation(), buffers, ec);
|
||||
std::size_t s = impl_.get_service().read_some(
|
||||
impl_.get_implementation(), buffers, ec);
|
||||
boost::asio::detail::throw_error(ec, "read_some");
|
||||
return s;
|
||||
}
|
||||
@@ -631,8 +752,8 @@ public:
|
||||
std::size_t read_some(const MutableBufferSequence& buffers,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().read_some(
|
||||
this->get_implementation(), buffers, ec);
|
||||
return impl_.get_service().read_some(
|
||||
impl_.get_implementation(), buffers, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous read.
|
||||
@@ -653,9 +774,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes read.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @note The read operation may not read all of the requested number of bytes.
|
||||
* Consider using the @ref async_read function if you need to ensure that the
|
||||
@@ -665,7 +786,8 @@ public:
|
||||
* @par Example
|
||||
* To read into a single data buffer use the @ref buffer function as follows:
|
||||
* @code
|
||||
* serial_port.async_read_some(boost::asio::buffer(data, size), handler);
|
||||
* basic_serial_port.async_read_some(
|
||||
* boost::asio::buffer(data, size), handler);
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on reading into multiple
|
||||
* buffers in one go, and how to use it with arrays, boost::array or
|
||||
@@ -677,13 +799,55 @@ public:
|
||||
async_read_some(const MutableBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
// If you get an error on the following line it means that your handler does
|
||||
// not meet the documented type requirements for a ReadHandler.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
return this->get_service().async_read_some(this->get_implementation(),
|
||||
buffers, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
return async_initiate<ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_read_some(), handler, this, buffers);
|
||||
}
|
||||
|
||||
private:
|
||||
// Disallow copying and assignment.
|
||||
basic_serial_port(const basic_serial_port&) BOOST_ASIO_DELETED;
|
||||
basic_serial_port& operator=(const basic_serial_port&) BOOST_ASIO_DELETED;
|
||||
|
||||
struct initiate_async_write_some
|
||||
{
|
||||
template <typename WriteHandler, typename ConstBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
|
||||
basic_serial_port* self, const ConstBufferSequence& buffers) 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;
|
||||
|
||||
detail::non_const_lvalue<WriteHandler> handler2(handler);
|
||||
self->impl_.get_service().async_write_some(
|
||||
self->impl_.get_implementation(), buffers, handler2.value,
|
||||
self->impl_.get_implementation_executor());
|
||||
}
|
||||
};
|
||||
|
||||
struct initiate_async_read_some
|
||||
{
|
||||
template <typename ReadHandler, typename MutableBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
|
||||
basic_serial_port* self, const MutableBufferSequence& buffers) 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.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
detail::non_const_lvalue<ReadHandler> handler2(handler);
|
||||
self->impl_.get_service().async_read_some(
|
||||
self->impl_.get_implementation(), buffers, handler2.value,
|
||||
self->impl_.get_implementation_executor());
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_IOCP)
|
||||
detail::io_object_impl<detail::win_iocp_serial_port_service, Executor> impl_;
|
||||
#else
|
||||
detail::io_object_impl<detail::reactive_serial_port_service, Executor> impl_;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// basic_signal_set.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -17,23 +17,24 @@
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#include <boost/asio/basic_io_object.hpp>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/detail/handler_type_requirements.hpp>
|
||||
#include <boost/asio/detail/io_object_impl.hpp>
|
||||
#include <boost/asio/detail/non_const_lvalue.hpp>
|
||||
#include <boost/asio/detail/signal_set_service.hpp>
|
||||
#include <boost/asio/detail/throw_error.hpp>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/asio/signal_set_service.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
#include <boost/asio/execution_context.hpp>
|
||||
#include <boost/asio/executor.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
/// Provides signal functionality.
|
||||
/**
|
||||
* The basic_signal_set class template provides the ability to perform an
|
||||
* asynchronous wait for one or more signals to occur.
|
||||
*
|
||||
* Most applications will use the boost::asio::signal_set typedef.
|
||||
* The basic_signal_set class provides the ability to perform an asynchronous
|
||||
* wait for one or more signals to occur.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* @e Distinct @e objects: Safe.@n
|
||||
@@ -55,7 +56,7 @@ namespace asio {
|
||||
* ...
|
||||
*
|
||||
* // Construct a signal set registered for process termination.
|
||||
* boost::asio::signal_set signals(io_service, SIGINT, SIGTERM);
|
||||
* boost::asio::signal_set signals(my_context, SIGINT, SIGTERM);
|
||||
*
|
||||
* // Start an asynchronous wait for one of the signals to occur.
|
||||
* signals.async_wait(handler);
|
||||
@@ -90,20 +91,40 @@ namespace asio {
|
||||
* that any signals registered using signal_set objects are unblocked in at
|
||||
* least one thread.
|
||||
*/
|
||||
template <typename SignalSetService = signal_set_service>
|
||||
template <typename Executor = executor>
|
||||
class basic_signal_set
|
||||
: public basic_io_object<SignalSetService>
|
||||
{
|
||||
public:
|
||||
/// The type of the executor associated with the object.
|
||||
typedef Executor executor_type;
|
||||
|
||||
/// Construct a signal set without adding any signals.
|
||||
/**
|
||||
* This constructor creates a signal set without registering for any signals.
|
||||
*
|
||||
* @param io_service The io_service object that the signal set will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the set.
|
||||
* @param ex The I/O executor that the signal set will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the
|
||||
* signal set.
|
||||
*/
|
||||
explicit basic_signal_set(boost::asio::io_service& io_service)
|
||||
: basic_io_object<SignalSetService>(io_service)
|
||||
explicit basic_signal_set(const executor_type& ex)
|
||||
: impl_(ex)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a signal set without adding any signals.
|
||||
/**
|
||||
* This constructor creates a signal set without registering for any signals.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the signal set will use, by default, to dispatch handlers for any
|
||||
* asynchronous operations performed on the signal set.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
explicit basic_signal_set(ExecutionContext& context,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: impl_(context)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -111,20 +132,47 @@ public:
|
||||
/**
|
||||
* This constructor creates a signal set and registers for one signal.
|
||||
*
|
||||
* @param io_service The io_service object that the signal set will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the set.
|
||||
* @param ex The I/O executor that the signal set will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the
|
||||
* signal set.
|
||||
*
|
||||
* @param signal_number_1 The signal number to be added.
|
||||
*
|
||||
* @note This constructor is equivalent to performing:
|
||||
* @code boost::asio::signal_set signals(io_service);
|
||||
* @code boost::asio::signal_set signals(ex);
|
||||
* signals.add(signal_number_1); @endcode
|
||||
*/
|
||||
basic_signal_set(boost::asio::io_service& io_service, int signal_number_1)
|
||||
: basic_io_object<SignalSetService>(io_service)
|
||||
basic_signal_set(const executor_type& ex, int signal_number_1)
|
||||
: impl_(ex)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->service.add(this->implementation, signal_number_1, ec);
|
||||
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
|
||||
boost::asio::detail::throw_error(ec, "add");
|
||||
}
|
||||
|
||||
/// Construct a signal set and add one signal.
|
||||
/**
|
||||
* This constructor creates a signal set and registers for one signal.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the signal set will use, by default, to dispatch handlers for any
|
||||
* asynchronous operations performed on the signal set.
|
||||
*
|
||||
* @param signal_number_1 The signal number to be added.
|
||||
*
|
||||
* @note This constructor is equivalent to performing:
|
||||
* @code boost::asio::signal_set signals(context);
|
||||
* signals.add(signal_number_1); @endcode
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_signal_set(ExecutionContext& context, int signal_number_1,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: impl_(context)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
|
||||
boost::asio::detail::throw_error(ec, "add");
|
||||
}
|
||||
|
||||
@@ -132,26 +180,59 @@ public:
|
||||
/**
|
||||
* This constructor creates a signal set and registers for two signals.
|
||||
*
|
||||
* @param io_service The io_service object that the signal set will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the set.
|
||||
* @param ex The I/O executor that the signal set will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the
|
||||
* signal set.
|
||||
*
|
||||
* @param signal_number_1 The first signal number to be added.
|
||||
*
|
||||
* @param signal_number_2 The second signal number to be added.
|
||||
*
|
||||
* @note This constructor is equivalent to performing:
|
||||
* @code boost::asio::signal_set signals(io_service);
|
||||
* @code boost::asio::signal_set signals(ex);
|
||||
* signals.add(signal_number_1);
|
||||
* signals.add(signal_number_2); @endcode
|
||||
*/
|
||||
basic_signal_set(boost::asio::io_service& io_service, int signal_number_1,
|
||||
basic_signal_set(const executor_type& ex, int signal_number_1,
|
||||
int signal_number_2)
|
||||
: basic_io_object<SignalSetService>(io_service)
|
||||
: impl_(ex)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->service.add(this->implementation, signal_number_1, ec);
|
||||
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
|
||||
boost::asio::detail::throw_error(ec, "add");
|
||||
this->service.add(this->implementation, signal_number_2, ec);
|
||||
impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec);
|
||||
boost::asio::detail::throw_error(ec, "add");
|
||||
}
|
||||
|
||||
/// Construct a signal set and add two signals.
|
||||
/**
|
||||
* This constructor creates a signal set and registers for two signals.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the signal set will use, by default, to dispatch handlers for any
|
||||
* asynchronous operations performed on the signal set.
|
||||
*
|
||||
* @param signal_number_1 The first signal number to be added.
|
||||
*
|
||||
* @param signal_number_2 The second signal number to be added.
|
||||
*
|
||||
* @note This constructor is equivalent to performing:
|
||||
* @code boost::asio::signal_set signals(context);
|
||||
* signals.add(signal_number_1);
|
||||
* signals.add(signal_number_2); @endcode
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_signal_set(ExecutionContext& context, int signal_number_1,
|
||||
int signal_number_2,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: impl_(context)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
|
||||
boost::asio::detail::throw_error(ec, "add");
|
||||
impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec);
|
||||
boost::asio::detail::throw_error(ec, "add");
|
||||
}
|
||||
|
||||
@@ -159,8 +240,9 @@ public:
|
||||
/**
|
||||
* This constructor creates a signal set and registers for three signals.
|
||||
*
|
||||
* @param io_service The io_service object that the signal set will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the set.
|
||||
* @param ex The I/O executor that the signal set will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the
|
||||
* signal set.
|
||||
*
|
||||
* @param signal_number_1 The first signal number to be added.
|
||||
*
|
||||
@@ -169,24 +251,77 @@ public:
|
||||
* @param signal_number_3 The third signal number to be added.
|
||||
*
|
||||
* @note This constructor is equivalent to performing:
|
||||
* @code boost::asio::signal_set signals(io_service);
|
||||
* @code boost::asio::signal_set signals(ex);
|
||||
* signals.add(signal_number_1);
|
||||
* signals.add(signal_number_2);
|
||||
* signals.add(signal_number_3); @endcode
|
||||
*/
|
||||
basic_signal_set(boost::asio::io_service& io_service, int signal_number_1,
|
||||
basic_signal_set(const executor_type& ex, int signal_number_1,
|
||||
int signal_number_2, int signal_number_3)
|
||||
: basic_io_object<SignalSetService>(io_service)
|
||||
: impl_(ex)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->service.add(this->implementation, signal_number_1, ec);
|
||||
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
|
||||
boost::asio::detail::throw_error(ec, "add");
|
||||
this->service.add(this->implementation, signal_number_2, ec);
|
||||
impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec);
|
||||
boost::asio::detail::throw_error(ec, "add");
|
||||
this->service.add(this->implementation, signal_number_3, ec);
|
||||
impl_.get_service().add(impl_.get_implementation(), signal_number_3, ec);
|
||||
boost::asio::detail::throw_error(ec, "add");
|
||||
}
|
||||
|
||||
/// Construct a signal set and add three signals.
|
||||
/**
|
||||
* This constructor creates a signal set and registers for three signals.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the signal set will use, by default, to dispatch handlers for any
|
||||
* asynchronous operations performed on the signal set.
|
||||
*
|
||||
* @param signal_number_1 The first signal number to be added.
|
||||
*
|
||||
* @param signal_number_2 The second signal number to be added.
|
||||
*
|
||||
* @param signal_number_3 The third signal number to be added.
|
||||
*
|
||||
* @note This constructor is equivalent to performing:
|
||||
* @code boost::asio::signal_set signals(context);
|
||||
* signals.add(signal_number_1);
|
||||
* signals.add(signal_number_2);
|
||||
* signals.add(signal_number_3); @endcode
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_signal_set(ExecutionContext& context, int signal_number_1,
|
||||
int signal_number_2, int signal_number_3,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: impl_(context)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
|
||||
boost::asio::detail::throw_error(ec, "add");
|
||||
impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec);
|
||||
boost::asio::detail::throw_error(ec, "add");
|
||||
impl_.get_service().add(impl_.get_implementation(), signal_number_3, ec);
|
||||
boost::asio::detail::throw_error(ec, "add");
|
||||
}
|
||||
|
||||
/// Destroys the signal set.
|
||||
/**
|
||||
* This function destroys the signal set, cancelling any outstanding
|
||||
* asynchronous wait operations associated with the signal set as if by
|
||||
* calling @c cancel.
|
||||
*/
|
||||
~basic_signal_set()
|
||||
{
|
||||
}
|
||||
|
||||
/// Get the executor associated with the object.
|
||||
executor_type get_executor() BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return impl_.get_executor();
|
||||
}
|
||||
|
||||
/// Add a signal to a signal_set.
|
||||
/**
|
||||
* This function adds the specified signal to the set. It has no effect if the
|
||||
@@ -199,7 +334,7 @@ public:
|
||||
void add(int signal_number)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->service.add(this->implementation, signal_number, ec);
|
||||
impl_.get_service().add(impl_.get_implementation(), signal_number, ec);
|
||||
boost::asio::detail::throw_error(ec, "add");
|
||||
}
|
||||
|
||||
@@ -212,10 +347,11 @@ public:
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
boost::system::error_code add(int signal_number,
|
||||
BOOST_ASIO_SYNC_OP_VOID add(int signal_number,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->service.add(this->implementation, signal_number, ec);
|
||||
impl_.get_service().add(impl_.get_implementation(), signal_number, ec);
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
/// Remove a signal from a signal_set.
|
||||
@@ -233,7 +369,7 @@ public:
|
||||
void remove(int signal_number)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->service.remove(this->implementation, signal_number, ec);
|
||||
impl_.get_service().remove(impl_.get_implementation(), signal_number, ec);
|
||||
boost::asio::detail::throw_error(ec, "remove");
|
||||
}
|
||||
|
||||
@@ -249,10 +385,11 @@ public:
|
||||
* @note Removes any notifications that have been queued for the specified
|
||||
* signal number.
|
||||
*/
|
||||
boost::system::error_code remove(int signal_number,
|
||||
BOOST_ASIO_SYNC_OP_VOID remove(int signal_number,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->service.remove(this->implementation, signal_number, ec);
|
||||
impl_.get_service().remove(impl_.get_implementation(), signal_number, ec);
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
/// Remove all signals from a signal_set.
|
||||
@@ -267,7 +404,7 @@ public:
|
||||
void clear()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->service.clear(this->implementation, ec);
|
||||
impl_.get_service().clear(impl_.get_implementation(), ec);
|
||||
boost::asio::detail::throw_error(ec, "clear");
|
||||
}
|
||||
|
||||
@@ -280,9 +417,10 @@ public:
|
||||
*
|
||||
* @note Removes all queued notifications.
|
||||
*/
|
||||
boost::system::error_code clear(boost::system::error_code& ec)
|
||||
BOOST_ASIO_SYNC_OP_VOID clear(boost::system::error_code& ec)
|
||||
{
|
||||
return this->service.clear(this->implementation, ec);
|
||||
impl_.get_service().clear(impl_.get_implementation(), ec);
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
/// Cancel all operations associated with the signal set.
|
||||
@@ -309,7 +447,7 @@ public:
|
||||
void cancel()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->service.cancel(this->implementation, ec);
|
||||
impl_.get_service().cancel(impl_.get_implementation(), ec);
|
||||
boost::asio::detail::throw_error(ec, "cancel");
|
||||
}
|
||||
|
||||
@@ -334,9 +472,10 @@ public:
|
||||
* These handlers can no longer be cancelled, and therefore are passed an
|
||||
* error code that indicates the successful completion of the wait operation.
|
||||
*/
|
||||
boost::system::error_code cancel(boost::system::error_code& ec)
|
||||
BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
|
||||
{
|
||||
return this->service.cancel(this->implementation, ec);
|
||||
impl_.get_service().cancel(impl_.get_implementation(), ec);
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous operation to wait for a signal to be delivered.
|
||||
@@ -360,27 +499,45 @@ public:
|
||||
* int signal_number // Indicates which signal occurred.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*/
|
||||
template <typename SignalHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(SignalHandler,
|
||||
void (boost::system::error_code, int))
|
||||
async_wait(BOOST_ASIO_MOVE_ARG(SignalHandler) handler)
|
||||
{
|
||||
// If you get an error on the following line it means that your handler does
|
||||
// not meet the documented type requirements for a SignalHandler.
|
||||
BOOST_ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check;
|
||||
|
||||
return this->service.async_wait(this->implementation,
|
||||
BOOST_ASIO_MOVE_CAST(SignalHandler)(handler));
|
||||
return async_initiate<SignalHandler, void (boost::system::error_code, int)>(
|
||||
initiate_async_wait(), handler, this);
|
||||
}
|
||||
|
||||
private:
|
||||
// Disallow copying and assignment.
|
||||
basic_signal_set(const basic_signal_set&) BOOST_ASIO_DELETED;
|
||||
basic_signal_set& operator=(const basic_signal_set&) BOOST_ASIO_DELETED;
|
||||
|
||||
struct initiate_async_wait
|
||||
{
|
||||
template <typename SignalHandler>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(SignalHandler) handler,
|
||||
basic_signal_set* self) const
|
||||
{
|
||||
// If you get an error on the following line it means that your handler
|
||||
// does not meet the documented type requirements for a SignalHandler.
|
||||
BOOST_ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check;
|
||||
|
||||
detail::non_const_lvalue<SignalHandler> handler2(handler);
|
||||
self->impl_.get_service().async_wait(
|
||||
self->impl_.get_implementation(), handler2.value,
|
||||
self->impl_.get_implementation_executor());
|
||||
}
|
||||
};
|
||||
|
||||
detail::io_object_impl<detail::signal_set_service, Executor> impl_;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_BASIC_SIGNAL_SET_HPP
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
// basic_socket_iostream.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <boost/asio/basic_socket_streambuf.hpp>
|
||||
#include <boost/asio/stream_socket_service.hpp>
|
||||
|
||||
#if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
@@ -33,8 +32,7 @@
|
||||
// explicit basic_socket_iostream(T1 x1, ..., Tn xn)
|
||||
// : std::basic_iostream<char>(
|
||||
// &this->detail::socket_iostream_base<
|
||||
// Protocol, StreamSocketService, Time,
|
||||
// TimeTraits, TimerService>::streambuf_)
|
||||
// Protocol, Clock, WaitTraits>::streambuf_)
|
||||
// {
|
||||
// if (rdbuf()->connect(x1, ..., xn) == 0)
|
||||
// this->setstate(std::ios_base::failbit);
|
||||
@@ -43,14 +41,13 @@
|
||||
|
||||
# define BOOST_ASIO_PRIVATE_CTR_DEF(n) \
|
||||
template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
explicit basic_socket_iostream(BOOST_ASIO_VARIADIC_PARAMS(n)) \
|
||||
explicit basic_socket_iostream(BOOST_ASIO_VARIADIC_BYVAL_PARAMS(n)) \
|
||||
: std::basic_iostream<char>( \
|
||||
&this->detail::socket_iostream_base< \
|
||||
Protocol, StreamSocketService, Time, \
|
||||
TimeTraits, TimerService>::streambuf_) \
|
||||
Protocol, Clock, WaitTraits>::streambuf_) \
|
||||
{ \
|
||||
this->setf(std::ios_base::unitbuf); \
|
||||
if (rdbuf()->connect(BOOST_ASIO_VARIADIC_ARGS(n)) == 0) \
|
||||
if (rdbuf()->connect(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \
|
||||
this->setstate(std::ios_base::failbit); \
|
||||
} \
|
||||
/**/
|
||||
@@ -66,9 +63,9 @@
|
||||
|
||||
# define BOOST_ASIO_PRIVATE_CONNECT_DEF(n) \
|
||||
template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
void connect(BOOST_ASIO_VARIADIC_PARAMS(n)) \
|
||||
void connect(BOOST_ASIO_VARIADIC_BYVAL_PARAMS(n)) \
|
||||
{ \
|
||||
if (rdbuf()->connect(BOOST_ASIO_VARIADIC_ARGS(n)) == 0) \
|
||||
if (rdbuf()->connect(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \
|
||||
this->setstate(std::ios_base::failbit); \
|
||||
} \
|
||||
/**/
|
||||
@@ -83,69 +80,156 @@ namespace detail {
|
||||
|
||||
// A separate base class is used to ensure that the streambuf is initialised
|
||||
// prior to the basic_socket_iostream's basic_iostream base class.
|
||||
template <typename Protocol, typename StreamSocketService,
|
||||
typename Time, typename TimeTraits, typename TimerService>
|
||||
template <typename Protocol, typename Clock, typename WaitTraits>
|
||||
class socket_iostream_base
|
||||
{
|
||||
protected:
|
||||
basic_socket_streambuf<Protocol, StreamSocketService,
|
||||
Time, TimeTraits, TimerService> streambuf_;
|
||||
socket_iostream_base()
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
socket_iostream_base(socket_iostream_base&& other)
|
||||
: streambuf_(std::move(other.streambuf_))
|
||||
{
|
||||
}
|
||||
|
||||
socket_iostream_base(basic_stream_socket<Protocol> s)
|
||||
: streambuf_(std::move(s))
|
||||
{
|
||||
}
|
||||
|
||||
socket_iostream_base& operator=(socket_iostream_base&& other)
|
||||
{
|
||||
streambuf_ = std::move(other.streambuf_);
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
basic_socket_streambuf<Protocol, Clock, WaitTraits> streambuf_;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
#if !defined(BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL)
|
||||
#define BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL
|
||||
|
||||
// Forward declaration with defaulted arguments.
|
||||
template <typename Protocol,
|
||||
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
|
||||
&& defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
|
||||
typename Clock = boost::posix_time::ptime,
|
||||
typename WaitTraits = time_traits<Clock> >
|
||||
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
|
||||
typename Clock = chrono::steady_clock,
|
||||
typename WaitTraits = wait_traits<Clock> >
|
||||
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
|
||||
class basic_socket_iostream;
|
||||
|
||||
#endif // !defined(BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL)
|
||||
|
||||
/// Iostream interface for a socket.
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
template <typename Protocol,
|
||||
typename StreamSocketService = stream_socket_service<Protocol>,
|
||||
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
|
||||
|| defined(GENERATING_DOCUMENTATION)
|
||||
typename Time = boost::posix_time::ptime,
|
||||
typename TimeTraits = boost::asio::time_traits<Time>,
|
||||
typename TimerService = deadline_timer_service<Time, TimeTraits> >
|
||||
#else
|
||||
typename Time = steady_timer::clock_type,
|
||||
typename TimeTraits = steady_timer::traits_type,
|
||||
typename TimerService = steady_timer::service_type>
|
||||
#endif
|
||||
typename Clock = chrono::steady_clock,
|
||||
typename WaitTraits = wait_traits<Clock> >
|
||||
#else // defined(GENERATING_DOCUMENTATION)
|
||||
template <typename Protocol, typename Clock, typename WaitTraits>
|
||||
#endif // defined(GENERATING_DOCUMENTATION)
|
||||
class basic_socket_iostream
|
||||
: private detail::socket_iostream_base<Protocol,
|
||||
StreamSocketService, Time, TimeTraits, TimerService>,
|
||||
: private detail::socket_iostream_base<Protocol, Clock, WaitTraits>,
|
||||
public std::basic_iostream<char>
|
||||
{
|
||||
private:
|
||||
// These typedefs are intended keep this class's implementation independent
|
||||
// of whether it's using Boost.DateTime, Boost.Chrono or std::chrono.
|
||||
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
typedef TimeTraits traits_helper;
|
||||
#else
|
||||
typedef detail::chrono_time_traits<Time, TimeTraits> traits_helper;
|
||||
#endif
|
||||
// of whether it's using Boost.DateClock, Boost.Chrono or std::chrono.
|
||||
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
|
||||
&& defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
|
||||
typedef WaitTraits traits_helper;
|
||||
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
|
||||
typedef detail::chrono_time_traits<Clock, WaitTraits> traits_helper;
|
||||
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
|
||||
|
||||
public:
|
||||
/// The protocol type.
|
||||
typedef Protocol protocol_type;
|
||||
|
||||
/// The endpoint type.
|
||||
typedef typename Protocol::endpoint endpoint_type;
|
||||
|
||||
/// The clock type.
|
||||
typedef Clock clock_type;
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
/// (Deprecated: Use time_point.) The time type.
|
||||
typedef typename WaitTraits::time_type time_type;
|
||||
|
||||
/// The time type.
|
||||
typedef typename TimeTraits::time_type time_type;
|
||||
typedef typename WaitTraits::time_point time_point;
|
||||
|
||||
/// (Deprecated: Use duration.) The duration type.
|
||||
typedef typename WaitTraits::duration_type duration_type;
|
||||
|
||||
/// The duration type.
|
||||
typedef typename TimeTraits::duration_type duration_type;
|
||||
typedef typename WaitTraits::duration duration;
|
||||
#else
|
||||
# if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
typedef typename traits_helper::time_type time_type;
|
||||
typedef typename traits_helper::duration_type duration_type;
|
||||
# endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
typedef typename traits_helper::time_type time_point;
|
||||
typedef typename traits_helper::duration_type duration;
|
||||
#endif
|
||||
|
||||
/// Construct a basic_socket_iostream without establishing a connection.
|
||||
basic_socket_iostream()
|
||||
: std::basic_iostream<char>(
|
||||
&this->detail::socket_iostream_base<
|
||||
Protocol, StreamSocketService, Time,
|
||||
TimeTraits, TimerService>::streambuf_)
|
||||
Protocol, Clock, WaitTraits>::streambuf_)
|
||||
{
|
||||
this->setf(std::ios_base::unitbuf);
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
/// Construct a basic_socket_iostream from the supplied socket.
|
||||
explicit basic_socket_iostream(basic_stream_socket<protocol_type> s)
|
||||
: detail::socket_iostream_base<
|
||||
Protocol, Clock, WaitTraits>(std::move(s)),
|
||||
std::basic_iostream<char>(
|
||||
&this->detail::socket_iostream_base<
|
||||
Protocol, Clock, WaitTraits>::streambuf_)
|
||||
{
|
||||
this->setf(std::ios_base::unitbuf);
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_STD_IOSTREAM_MOVE) \
|
||||
|| defined(GENERATING_DOCUMENTATION)
|
||||
/// Move-construct a basic_socket_iostream from another.
|
||||
basic_socket_iostream(basic_socket_iostream&& other)
|
||||
: detail::socket_iostream_base<
|
||||
Protocol, Clock, WaitTraits>(std::move(other)),
|
||||
std::basic_iostream<char>(std::move(other))
|
||||
{
|
||||
this->set_rdbuf(&this->detail::socket_iostream_base<
|
||||
Protocol, Clock, WaitTraits>::streambuf_);
|
||||
}
|
||||
|
||||
/// Move-assign a basic_socket_iostream from another.
|
||||
basic_socket_iostream& operator=(basic_socket_iostream&& other)
|
||||
{
|
||||
std::basic_iostream<char>::operator=(std::move(other));
|
||||
detail::socket_iostream_base<
|
||||
Protocol, Clock, WaitTraits>::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_STD_IOSTREAM_MOVE)
|
||||
// || defined(GENERATING_DOCUMENTATION)
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
/// Establish a connection to an endpoint corresponding to a resolver query.
|
||||
/**
|
||||
@@ -160,8 +244,7 @@ public:
|
||||
explicit basic_socket_iostream(T... x)
|
||||
: std::basic_iostream<char>(
|
||||
&this->detail::socket_iostream_base<
|
||||
Protocol, StreamSocketService, Time,
|
||||
TimeTraits, TimerService>::streambuf_)
|
||||
Protocol, Clock, WaitTraits>::streambuf_)
|
||||
{
|
||||
this->setf(std::ios_base::unitbuf);
|
||||
if (rdbuf()->connect(x...) == 0)
|
||||
@@ -199,14 +282,17 @@ public:
|
||||
}
|
||||
|
||||
/// Return a pointer to the underlying streambuf.
|
||||
basic_socket_streambuf<Protocol, StreamSocketService,
|
||||
Time, TimeTraits, TimerService>* rdbuf() const
|
||||
basic_socket_streambuf<Protocol, Clock, WaitTraits>* rdbuf() const
|
||||
{
|
||||
return const_cast<basic_socket_streambuf<Protocol, StreamSocketService,
|
||||
Time, TimeTraits, TimerService>*>(
|
||||
return const_cast<basic_socket_streambuf<Protocol, Clock, WaitTraits>*>(
|
||||
&this->detail::socket_iostream_base<
|
||||
Protocol, StreamSocketService, Time,
|
||||
TimeTraits, TimerService>::streambuf_);
|
||||
Protocol, Clock, WaitTraits>::streambuf_);
|
||||
}
|
||||
|
||||
/// Get a reference to the underlying socket.
|
||||
basic_socket<Protocol>& socket()
|
||||
{
|
||||
return rdbuf()->socket();
|
||||
}
|
||||
|
||||
/// Get the last error associated with the stream.
|
||||
@@ -223,16 +309,28 @@ public:
|
||||
*/
|
||||
const boost::system::error_code& error() const
|
||||
{
|
||||
return rdbuf()->puberror();
|
||||
return rdbuf()->error();
|
||||
}
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
/// (Deprecated: Use expiry().) Get the stream's expiry time as an absolute
|
||||
/// time.
|
||||
/**
|
||||
* @return An absolute time value representing the stream's expiry time.
|
||||
*/
|
||||
time_point expires_at() const
|
||||
{
|
||||
return rdbuf()->expires_at();
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
/// Get the stream's expiry time as an absolute time.
|
||||
/**
|
||||
* @return An absolute time value representing the stream's expiry time.
|
||||
*/
|
||||
time_type expires_at() const
|
||||
time_point expiry() const
|
||||
{
|
||||
return rdbuf()->expires_at();
|
||||
return rdbuf()->expiry();
|
||||
}
|
||||
|
||||
/// Set the stream's expiry time as an absolute time.
|
||||
@@ -244,20 +342,11 @@ public:
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the stream.
|
||||
*/
|
||||
void expires_at(const time_type& expiry_time)
|
||||
void expires_at(const time_point& expiry_time)
|
||||
{
|
||||
rdbuf()->expires_at(expiry_time);
|
||||
}
|
||||
|
||||
/// Get the timer's expiry time relative to now.
|
||||
/**
|
||||
* @return A relative time value representing the stream's expiry time.
|
||||
*/
|
||||
duration_type expires_from_now() const
|
||||
{
|
||||
return rdbuf()->expires_from_now();
|
||||
}
|
||||
|
||||
/// Set the stream's expiry time relative to now.
|
||||
/**
|
||||
* This function sets the expiry time associated with the stream. Stream
|
||||
@@ -267,10 +356,42 @@ public:
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer.
|
||||
*/
|
||||
void expires_from_now(const duration_type& expiry_time)
|
||||
void expires_after(const duration& expiry_time)
|
||||
{
|
||||
rdbuf()->expires_after(expiry_time);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
/// (Deprecated: Use expiry().) Get the stream's expiry time relative to now.
|
||||
/**
|
||||
* @return A relative time value representing the stream's expiry time.
|
||||
*/
|
||||
duration expires_from_now() const
|
||||
{
|
||||
return rdbuf()->expires_from_now();
|
||||
}
|
||||
|
||||
/// (Deprecated: Use expires_after().) Set the stream's expiry time relative
|
||||
/// to now.
|
||||
/**
|
||||
* This function sets the expiry time associated with the stream. Stream
|
||||
* operations performed after this time (where the operations cannot be
|
||||
* completed using the internal buffers) will fail with the error
|
||||
* boost::asio::error::operation_aborted.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer.
|
||||
*/
|
||||
void expires_from_now(const duration& expiry_time)
|
||||
{
|
||||
rdbuf()->expires_from_now(expiry_time);
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
private:
|
||||
// Disallow copying and assignment.
|
||||
basic_socket_iostream(const basic_socket_iostream&) BOOST_ASIO_DELETED;
|
||||
basic_socket_iostream& operator=(
|
||||
const basic_socket_iostream&) BOOST_ASIO_DELETED;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// basic_socket_streambuf.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -20,18 +20,22 @@
|
||||
#if !defined(BOOST_ASIO_NO_IOSTREAM)
|
||||
|
||||
#include <streambuf>
|
||||
#include <vector>
|
||||
#include <boost/asio/basic_socket.hpp>
|
||||
#include <boost/asio/deadline_timer_service.hpp>
|
||||
#include <boost/asio/detail/array.hpp>
|
||||
#include <boost/asio/basic_stream_socket.hpp>
|
||||
#include <boost/asio/detail/buffer_sequence_adapter.hpp>
|
||||
#include <boost/asio/detail/memory.hpp>
|
||||
#include <boost/asio/detail/throw_error.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/stream_socket_service.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
# include <boost/asio/deadline_timer.hpp>
|
||||
#else
|
||||
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
|
||||
&& defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
|
||||
# include <boost/asio/detail/deadline_timer_service.hpp>
|
||||
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
|
||||
# include <boost/asio/steady_timer.hpp>
|
||||
#endif
|
||||
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
|
||||
|
||||
#if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
@@ -39,31 +43,26 @@
|
||||
|
||||
// A macro that should expand to:
|
||||
// template <typename T1, ..., typename Tn>
|
||||
// basic_socket_streambuf<Protocol, StreamSocketService,
|
||||
// Time, TimeTraits, TimerService>* connect(
|
||||
// T1 x1, ..., Tn xn)
|
||||
// basic_socket_streambuf* connect(T1 x1, ..., Tn xn)
|
||||
// {
|
||||
// init_buffers();
|
||||
// this->basic_socket<Protocol, StreamSocketService>::close(ec_);
|
||||
// typedef typename Protocol::resolver resolver_type;
|
||||
// typedef typename resolver_type::query resolver_query;
|
||||
// resolver_query query(x1, ..., xn);
|
||||
// resolve_and_connect(query);
|
||||
// resolver_type resolver(socket().get_executor());
|
||||
// connect_to_endpoints(
|
||||
// resolver.resolve(x1, ..., xn, ec_));
|
||||
// return !ec_ ? this : 0;
|
||||
// }
|
||||
// This macro should only persist within this file.
|
||||
|
||||
# define BOOST_ASIO_PRIVATE_CONNECT_DEF(n) \
|
||||
template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
basic_socket_streambuf<Protocol, StreamSocketService, \
|
||||
Time, TimeTraits, TimerService>* connect(BOOST_ASIO_VARIADIC_PARAMS(n)) \
|
||||
basic_socket_streambuf* connect(BOOST_ASIO_VARIADIC_BYVAL_PARAMS(n)) \
|
||||
{ \
|
||||
init_buffers(); \
|
||||
this->basic_socket<Protocol, StreamSocketService>::close(ec_); \
|
||||
typedef typename Protocol::resolver resolver_type; \
|
||||
typedef typename resolver_type::query resolver_query; \
|
||||
resolver_query query(BOOST_ASIO_VARIADIC_ARGS(n)); \
|
||||
resolve_and_connect(query); \
|
||||
resolver_type resolver(socket().get_executor()); \
|
||||
connect_to_endpoints( \
|
||||
resolver.resolve(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n), ec_)); \
|
||||
return !ec_ ? this : 0; \
|
||||
} \
|
||||
/**/
|
||||
@@ -76,76 +75,180 @@ namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
// A separate base class is used to ensure that the io_service is initialised
|
||||
// prior to the basic_socket_streambuf's basic_socket base class.
|
||||
class socket_streambuf_base
|
||||
// A separate base class is used to ensure that the io_context member is
|
||||
// initialised prior to the basic_socket_streambuf's basic_socket base class.
|
||||
class socket_streambuf_io_context
|
||||
{
|
||||
protected:
|
||||
io_service io_service_;
|
||||
socket_streambuf_io_context(io_context* ctx)
|
||||
: default_io_context_(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
shared_ptr<io_context> default_io_context_;
|
||||
};
|
||||
|
||||
// A separate base class is used to ensure that the dynamically allocated
|
||||
// buffers are constructed prior to the basic_socket_streambuf's basic_socket
|
||||
// base class. This makes moving the socket is the last potentially throwing
|
||||
// step in the streambuf's move constructor, giving the constructor a strong
|
||||
// exception safety guarantee.
|
||||
class socket_streambuf_buffers
|
||||
{
|
||||
protected:
|
||||
socket_streambuf_buffers()
|
||||
: get_buffer_(buffer_size),
|
||||
put_buffer_(buffer_size)
|
||||
{
|
||||
}
|
||||
|
||||
enum { buffer_size = 512 };
|
||||
std::vector<char> get_buffer_;
|
||||
std::vector<char> put_buffer_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// Iostream streambuf for a socket.
|
||||
#if !defined(BOOST_ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL)
|
||||
#define BOOST_ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL
|
||||
|
||||
// Forward declaration with defaulted arguments.
|
||||
template <typename Protocol,
|
||||
typename StreamSocketService = stream_socket_service<Protocol>,
|
||||
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
|
||||
|| defined(GENERATING_DOCUMENTATION)
|
||||
typename Time = boost::posix_time::ptime,
|
||||
typename TimeTraits = boost::asio::time_traits<Time>,
|
||||
typename TimerService = deadline_timer_service<Time, TimeTraits> >
|
||||
#else
|
||||
typename Time = steady_timer::clock_type,
|
||||
typename TimeTraits = steady_timer::traits_type,
|
||||
typename TimerService = steady_timer::service_type>
|
||||
#endif
|
||||
&& defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
|
||||
typename Clock = boost::posix_time::ptime,
|
||||
typename WaitTraits = time_traits<Clock> >
|
||||
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
|
||||
typename Clock = chrono::steady_clock,
|
||||
typename WaitTraits = wait_traits<Clock> >
|
||||
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
|
||||
class basic_socket_streambuf;
|
||||
|
||||
#endif // !defined(BOOST_ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL)
|
||||
|
||||
/// Iostream streambuf for a socket.
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
template <typename Protocol,
|
||||
typename Clock = chrono::steady_clock,
|
||||
typename WaitTraits = wait_traits<Clock> >
|
||||
#else // defined(GENERATING_DOCUMENTATION)
|
||||
template <typename Protocol, typename Clock, typename WaitTraits>
|
||||
#endif // defined(GENERATING_DOCUMENTATION)
|
||||
class basic_socket_streambuf
|
||||
: public std::streambuf,
|
||||
private detail::socket_streambuf_base,
|
||||
public basic_socket<Protocol, StreamSocketService>
|
||||
private detail::socket_streambuf_io_context,
|
||||
private detail::socket_streambuf_buffers,
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
|
||||
private basic_socket<Protocol>
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
|
||||
public basic_socket<Protocol>
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
|
||||
{
|
||||
private:
|
||||
// These typedefs are intended keep this class's implementation independent
|
||||
// of whether it's using Boost.DateTime, Boost.Chrono or std::chrono.
|
||||
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
typedef TimeTraits traits_helper;
|
||||
#else
|
||||
typedef detail::chrono_time_traits<Time, TimeTraits> traits_helper;
|
||||
#endif
|
||||
// of whether it's using Boost.DateClock, Boost.Chrono or std::chrono.
|
||||
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
|
||||
&& defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
|
||||
typedef WaitTraits traits_helper;
|
||||
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
|
||||
typedef detail::chrono_time_traits<Clock, WaitTraits> traits_helper;
|
||||
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
|
||||
|
||||
public:
|
||||
/// The protocol type.
|
||||
typedef Protocol protocol_type;
|
||||
|
||||
/// The endpoint type.
|
||||
typedef typename Protocol::endpoint endpoint_type;
|
||||
|
||||
/// The clock type.
|
||||
typedef Clock clock_type;
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
/// (Deprecated: Use time_point.) The time type.
|
||||
typedef typename WaitTraits::time_type time_type;
|
||||
|
||||
/// The time type.
|
||||
typedef typename TimeTraits::time_type time_type;
|
||||
typedef typename WaitTraits::time_point time_point;
|
||||
|
||||
/// (Deprecated: Use duration.) The duration type.
|
||||
typedef typename WaitTraits::duration_type duration_type;
|
||||
|
||||
/// The duration type.
|
||||
typedef typename TimeTraits::duration_type duration_type;
|
||||
typedef typename WaitTraits::duration duration;
|
||||
#else
|
||||
# if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
typedef typename traits_helper::time_type time_type;
|
||||
typedef typename traits_helper::duration_type duration_type;
|
||||
# endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
typedef typename traits_helper::time_type time_point;
|
||||
typedef typename traits_helper::duration_type duration;
|
||||
#endif
|
||||
|
||||
/// Construct a basic_socket_streambuf without establishing a connection.
|
||||
basic_socket_streambuf()
|
||||
: basic_socket<Protocol, StreamSocketService>(
|
||||
this->detail::socket_streambuf_base::io_service_),
|
||||
unbuffered_(false),
|
||||
timer_service_(0),
|
||||
timer_state_(no_timer)
|
||||
: detail::socket_streambuf_io_context(new io_context),
|
||||
basic_socket<Protocol>(*default_io_context_),
|
||||
expiry_time_(max_expiry_time())
|
||||
{
|
||||
init_buffers();
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
/// Construct a basic_socket_streambuf from the supplied socket.
|
||||
explicit basic_socket_streambuf(basic_stream_socket<protocol_type> s)
|
||||
: detail::socket_streambuf_io_context(0),
|
||||
basic_socket<Protocol>(std::move(s)),
|
||||
expiry_time_(max_expiry_time())
|
||||
{
|
||||
init_buffers();
|
||||
}
|
||||
|
||||
/// Move-construct a basic_socket_streambuf from another.
|
||||
basic_socket_streambuf(basic_socket_streambuf&& other)
|
||||
: detail::socket_streambuf_io_context(other),
|
||||
basic_socket<Protocol>(std::move(other.socket())),
|
||||
ec_(other.ec_),
|
||||
expiry_time_(other.expiry_time_)
|
||||
{
|
||||
get_buffer_.swap(other.get_buffer_);
|
||||
put_buffer_.swap(other.put_buffer_);
|
||||
setg(other.eback(), other.gptr(), other.egptr());
|
||||
setp(other.pptr(), other.epptr());
|
||||
other.ec_ = boost::system::error_code();
|
||||
other.expiry_time_ = max_expiry_time();
|
||||
other.init_buffers();
|
||||
}
|
||||
|
||||
/// Move-assign a basic_socket_streambuf from another.
|
||||
basic_socket_streambuf& operator=(basic_socket_streambuf&& other)
|
||||
{
|
||||
this->close();
|
||||
socket() = std::move(other.socket());
|
||||
detail::socket_streambuf_io_context::operator=(other);
|
||||
ec_ = other.ec_;
|
||||
expiry_time_ = other.expiry_time_;
|
||||
get_buffer_.swap(other.get_buffer_);
|
||||
put_buffer_.swap(other.put_buffer_);
|
||||
setg(other.eback(), other.gptr(), other.egptr());
|
||||
setp(other.pptr(), other.epptr());
|
||||
other.ec_ = boost::system::error_code();
|
||||
other.expiry_time_ = max_expiry_time();
|
||||
other.put_buffer_.resize(buffer_size);
|
||||
other.init_buffers();
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Destructor flushes buffered data.
|
||||
virtual ~basic_socket_streambuf()
|
||||
{
|
||||
if (pptr() != pbase())
|
||||
overflow(traits_type::eof());
|
||||
|
||||
destroy_timer();
|
||||
}
|
||||
|
||||
/// Establish a connection.
|
||||
@@ -155,29 +258,11 @@ public:
|
||||
* @return \c this if a connection was successfully established, a null
|
||||
* pointer otherwise.
|
||||
*/
|
||||
basic_socket_streambuf<Protocol, StreamSocketService,
|
||||
Time, TimeTraits, TimerService>* connect(
|
||||
const endpoint_type& endpoint)
|
||||
basic_socket_streambuf* connect(const endpoint_type& endpoint)
|
||||
{
|
||||
init_buffers();
|
||||
|
||||
this->basic_socket<Protocol, StreamSocketService>::close(ec_);
|
||||
|
||||
if (timer_state_ == timer_has_expired)
|
||||
{
|
||||
ec_ = boost::asio::error::operation_aborted;
|
||||
return 0;
|
||||
}
|
||||
|
||||
io_handler handler = { this };
|
||||
this->basic_socket<Protocol, StreamSocketService>::async_connect(
|
||||
endpoint, handler);
|
||||
|
||||
ec_ = boost::asio::error::would_block;
|
||||
this->get_service().get_io_service().reset();
|
||||
do this->get_service().get_io_service().run_one();
|
||||
while (ec_ == boost::asio::error::would_block);
|
||||
|
||||
ec_ = boost::system::error_code();
|
||||
this->connect_to_endpoints(&endpoint, &endpoint + 1);
|
||||
return !ec_ ? this : 0;
|
||||
}
|
||||
|
||||
@@ -192,19 +277,15 @@ public:
|
||||
* pointer otherwise.
|
||||
*/
|
||||
template <typename T1, ..., typename TN>
|
||||
basic_socket_streambuf<Protocol, StreamSocketService>* connect(
|
||||
T1 t1, ..., TN tn);
|
||||
basic_socket_streambuf* connect(T1 t1, ..., TN tn);
|
||||
#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
template <typename... T>
|
||||
basic_socket_streambuf<Protocol, StreamSocketService,
|
||||
Time, TimeTraits, TimerService>* connect(T... x)
|
||||
basic_socket_streambuf* connect(T... x)
|
||||
{
|
||||
init_buffers();
|
||||
this->basic_socket<Protocol, StreamSocketService>::close(ec_);
|
||||
typedef typename Protocol::resolver resolver_type;
|
||||
typedef typename resolver_type::query resolver_query;
|
||||
resolver_query query(x...);
|
||||
resolve_and_connect(query);
|
||||
resolver_type resolver(socket().get_executor());
|
||||
connect_to_endpoints(resolver.resolve(x..., ec_));
|
||||
return !ec_ ? this : 0;
|
||||
}
|
||||
#else
|
||||
@@ -216,17 +297,34 @@ public:
|
||||
* @return \c this if a connection was successfully established, a null
|
||||
* pointer otherwise.
|
||||
*/
|
||||
basic_socket_streambuf<Protocol, StreamSocketService,
|
||||
Time, TimeTraits, TimerService>* close()
|
||||
basic_socket_streambuf* close()
|
||||
{
|
||||
sync();
|
||||
this->basic_socket<Protocol, StreamSocketService>::close(ec_);
|
||||
socket().close(ec_);
|
||||
if (!ec_)
|
||||
init_buffers();
|
||||
return !ec_ ? this : 0;
|
||||
}
|
||||
|
||||
/// Get a reference to the underlying socket.
|
||||
basic_socket<Protocol>& socket()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Get the last error associated with the stream buffer.
|
||||
/**
|
||||
* @return An \c error_code corresponding to the last error from the stream
|
||||
* buffer.
|
||||
*/
|
||||
const boost::system::error_code& error() const
|
||||
{
|
||||
return ec_;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
/// (Deprecated: Use error().) Get the last error associated with the stream
|
||||
/// buffer.
|
||||
/**
|
||||
* @return An \c error_code corresponding to the last error from the stream
|
||||
* buffer.
|
||||
@@ -236,16 +334,26 @@ public:
|
||||
return error();
|
||||
}
|
||||
|
||||
/// (Deprecated: Use expiry().) Get the stream buffer's expiry time as an
|
||||
/// absolute time.
|
||||
/**
|
||||
* @return An absolute time value representing the stream buffer's expiry
|
||||
* time.
|
||||
*/
|
||||
time_point expires_at() const
|
||||
{
|
||||
return expiry_time_;
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
/// Get the stream buffer's expiry time as an absolute time.
|
||||
/**
|
||||
* @return An absolute time value representing the stream buffer's expiry
|
||||
* time.
|
||||
*/
|
||||
time_type expires_at() const
|
||||
time_point expiry() const
|
||||
{
|
||||
return timer_service_
|
||||
? timer_service_->expires_at(timer_implementation_)
|
||||
: time_type();
|
||||
return expiry_time_;
|
||||
}
|
||||
|
||||
/// Set the stream buffer's expiry time as an absolute time.
|
||||
@@ -257,24 +365,9 @@ public:
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the stream.
|
||||
*/
|
||||
void expires_at(const time_type& expiry_time)
|
||||
void expires_at(const time_point& expiry_time)
|
||||
{
|
||||
construct_timer();
|
||||
|
||||
boost::system::error_code ec;
|
||||
timer_service_->expires_at(timer_implementation_, expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_at");
|
||||
|
||||
start_timer();
|
||||
}
|
||||
|
||||
/// Get the stream buffer's expiry time relative to now.
|
||||
/**
|
||||
* @return A relative time value representing the stream buffer's expiry time.
|
||||
*/
|
||||
duration_type expires_from_now() const
|
||||
{
|
||||
return traits_helper::subtract(expires_at(), traits_helper::now());
|
||||
expiry_time_ = expiry_time;
|
||||
}
|
||||
|
||||
/// Set the stream buffer's expiry time relative to now.
|
||||
@@ -286,109 +379,152 @@ public:
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer.
|
||||
*/
|
||||
void expires_from_now(const duration_type& expiry_time)
|
||||
void expires_after(const duration& expiry_time)
|
||||
{
|
||||
construct_timer();
|
||||
|
||||
boost::system::error_code ec;
|
||||
timer_service_->expires_from_now(timer_implementation_, expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_from_now");
|
||||
|
||||
start_timer();
|
||||
expiry_time_ = traits_helper::add(traits_helper::now(), expiry_time);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
/// (Deprecated: Use expiry().) Get the stream buffer's expiry time relative
|
||||
/// to now.
|
||||
/**
|
||||
* @return A relative time value representing the stream buffer's expiry time.
|
||||
*/
|
||||
duration expires_from_now() const
|
||||
{
|
||||
return traits_helper::subtract(expires_at(), traits_helper::now());
|
||||
}
|
||||
|
||||
/// (Deprecated: Use expires_after().) Set the stream buffer's expiry time
|
||||
/// relative to now.
|
||||
/**
|
||||
* This function sets the expiry time associated with the stream. Stream
|
||||
* operations performed after this time (where the operations cannot be
|
||||
* completed using the internal buffers) will fail with the error
|
||||
* boost::asio::error::operation_aborted.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer.
|
||||
*/
|
||||
void expires_from_now(const duration& expiry_time)
|
||||
{
|
||||
expiry_time_ = traits_helper::add(traits_helper::now(), expiry_time);
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
protected:
|
||||
int_type underflow()
|
||||
{
|
||||
if (gptr() == egptr())
|
||||
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
||||
ec_ = boost::asio::error::operation_not_supported;
|
||||
return traits_type::eof();
|
||||
#else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
||||
if (gptr() != egptr())
|
||||
return traits_type::eof();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (timer_state_ == timer_has_expired)
|
||||
// Check if we are past the expiry time.
|
||||
if (traits_helper::less_than(expiry_time_, traits_helper::now()))
|
||||
{
|
||||
ec_ = boost::asio::error::operation_aborted;
|
||||
ec_ = boost::asio::error::timed_out;
|
||||
return traits_type::eof();
|
||||
}
|
||||
|
||||
io_handler handler = { this };
|
||||
this->get_service().async_receive(this->get_implementation(),
|
||||
boost::asio::buffer(boost::asio::buffer(get_buffer_) + putback_max),
|
||||
0, handler);
|
||||
// Try to complete the operation without blocking.
|
||||
if (!socket().native_non_blocking())
|
||||
socket().native_non_blocking(true, ec_);
|
||||
detail::buffer_sequence_adapter<mutable_buffer, mutable_buffer>
|
||||
bufs(boost::asio::buffer(get_buffer_) + putback_max);
|
||||
detail::signed_size_type bytes = detail::socket_ops::recv(
|
||||
socket().native_handle(), bufs.buffers(), bufs.count(), 0, ec_);
|
||||
|
||||
ec_ = boost::asio::error::would_block;
|
||||
this->get_service().get_io_service().reset();
|
||||
do this->get_service().get_io_service().run_one();
|
||||
while (ec_ == boost::asio::error::would_block);
|
||||
if (ec_)
|
||||
// Check if operation succeeded.
|
||||
if (bytes > 0)
|
||||
{
|
||||
setg(&get_buffer_[0], &get_buffer_[0] + putback_max,
|
||||
&get_buffer_[0] + putback_max + bytes);
|
||||
return traits_type::to_int_type(*gptr());
|
||||
}
|
||||
|
||||
// Check for EOF.
|
||||
if (bytes == 0)
|
||||
{
|
||||
ec_ = boost::asio::error::eof;
|
||||
return traits_type::eof();
|
||||
}
|
||||
|
||||
// Operation failed.
|
||||
if (ec_ != boost::asio::error::would_block
|
||||
&& ec_ != boost::asio::error::try_again)
|
||||
return traits_type::eof();
|
||||
|
||||
setg(&get_buffer_[0], &get_buffer_[0] + putback_max,
|
||||
&get_buffer_[0] + putback_max + bytes_transferred_);
|
||||
return traits_type::to_int_type(*gptr());
|
||||
}
|
||||
else
|
||||
{
|
||||
return traits_type::eof();
|
||||
// Wait for socket to become ready.
|
||||
if (detail::socket_ops::poll_read(
|
||||
socket().native_handle(), 0, timeout(), ec_) < 0)
|
||||
return traits_type::eof();
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
||||
}
|
||||
|
||||
int_type overflow(int_type c)
|
||||
{
|
||||
if (unbuffered_)
|
||||
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
||||
ec_ = boost::asio::error::operation_not_supported;
|
||||
return traits_type::eof();
|
||||
#else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
||||
char_type ch = traits_type::to_char_type(c);
|
||||
|
||||
// Determine what needs to be sent.
|
||||
const_buffer output_buffer;
|
||||
if (put_buffer_.empty())
|
||||
{
|
||||
if (traits_type::eq_int_type(c, traits_type::eof()))
|
||||
{
|
||||
// Nothing to do.
|
||||
return traits_type::not_eof(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (timer_state_ == timer_has_expired)
|
||||
{
|
||||
ec_ = boost::asio::error::operation_aborted;
|
||||
return traits_type::eof();
|
||||
}
|
||||
|
||||
// Send the single character immediately.
|
||||
char_type ch = traits_type::to_char_type(c);
|
||||
io_handler handler = { this };
|
||||
this->get_service().async_send(this->get_implementation(),
|
||||
boost::asio::buffer(&ch, sizeof(char_type)), 0, handler);
|
||||
|
||||
ec_ = boost::asio::error::would_block;
|
||||
this->get_service().get_io_service().reset();
|
||||
do this->get_service().get_io_service().run_one();
|
||||
while (ec_ == boost::asio::error::would_block);
|
||||
if (ec_)
|
||||
return traits_type::eof();
|
||||
|
||||
return c;
|
||||
}
|
||||
return traits_type::not_eof(c); // Nothing to do.
|
||||
output_buffer = boost::asio::buffer(&ch, sizeof(char_type));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send all data in the output buffer.
|
||||
boost::asio::const_buffer buffer =
|
||||
boost::asio::buffer(pbase(), pptr() - pbase());
|
||||
while (boost::asio::buffer_size(buffer) > 0)
|
||||
output_buffer = boost::asio::buffer(pbase(),
|
||||
(pptr() - pbase()) * sizeof(char_type));
|
||||
}
|
||||
|
||||
while (output_buffer.size() > 0)
|
||||
{
|
||||
// Check if we are past the expiry time.
|
||||
if (traits_helper::less_than(expiry_time_, traits_helper::now()))
|
||||
{
|
||||
if (timer_state_ == timer_has_expired)
|
||||
{
|
||||
ec_ = boost::asio::error::operation_aborted;
|
||||
return traits_type::eof();
|
||||
}
|
||||
|
||||
io_handler handler = { this };
|
||||
this->get_service().async_send(this->get_implementation(),
|
||||
boost::asio::buffer(buffer), 0, handler);
|
||||
|
||||
ec_ = boost::asio::error::would_block;
|
||||
this->get_service().get_io_service().reset();
|
||||
do this->get_service().get_io_service().run_one();
|
||||
while (ec_ == boost::asio::error::would_block);
|
||||
if (ec_)
|
||||
return traits_type::eof();
|
||||
|
||||
buffer = buffer + bytes_transferred_;
|
||||
ec_ = boost::asio::error::timed_out;
|
||||
return traits_type::eof();
|
||||
}
|
||||
|
||||
// Try to complete the operation without blocking.
|
||||
if (!socket().native_non_blocking())
|
||||
socket().native_non_blocking(true, ec_);
|
||||
detail::buffer_sequence_adapter<
|
||||
const_buffer, const_buffer> bufs(output_buffer);
|
||||
detail::signed_size_type bytes = detail::socket_ops::send(
|
||||
socket().native_handle(), bufs.buffers(), bufs.count(), 0, ec_);
|
||||
|
||||
// Check if operation succeeded.
|
||||
if (bytes > 0)
|
||||
{
|
||||
output_buffer += static_cast<std::size_t>(bytes);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Operation failed.
|
||||
if (ec_ != boost::asio::error::would_block
|
||||
&& ec_ != boost::asio::error::try_again)
|
||||
return traits_type::eof();
|
||||
|
||||
// Wait for socket to become ready.
|
||||
if (detail::socket_ops::poll_write(
|
||||
socket().native_handle(), 0, timeout(), ec_) < 0)
|
||||
return traits_type::eof();
|
||||
}
|
||||
|
||||
if (!put_buffer_.empty())
|
||||
{
|
||||
setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size());
|
||||
|
||||
// If the new character is eof then our work here is done.
|
||||
@@ -396,10 +532,12 @@ protected:
|
||||
return traits_type::not_eof(c);
|
||||
|
||||
// Add the new character to the output buffer.
|
||||
*pptr() = traits_type::to_char_type(c);
|
||||
*pptr() = ch;
|
||||
pbump(1);
|
||||
return c;
|
||||
}
|
||||
|
||||
return c;
|
||||
#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
||||
}
|
||||
|
||||
int sync()
|
||||
@@ -411,148 +549,130 @@ protected:
|
||||
{
|
||||
if (pptr() == pbase() && s == 0 && n == 0)
|
||||
{
|
||||
unbuffered_ = true;
|
||||
put_buffer_.clear();
|
||||
setp(0, 0);
|
||||
sync();
|
||||
return this;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Get the last error associated with the stream buffer.
|
||||
/**
|
||||
* @return An \c error_code corresponding to the last error from the stream
|
||||
* buffer.
|
||||
*/
|
||||
virtual const boost::system::error_code& error() const
|
||||
{
|
||||
return ec_;
|
||||
}
|
||||
|
||||
private:
|
||||
// Disallow copying and assignment.
|
||||
basic_socket_streambuf(const basic_socket_streambuf&) BOOST_ASIO_DELETED;
|
||||
basic_socket_streambuf& operator=(
|
||||
const basic_socket_streambuf&) BOOST_ASIO_DELETED;
|
||||
|
||||
void init_buffers()
|
||||
{
|
||||
setg(&get_buffer_[0],
|
||||
&get_buffer_[0] + putback_max,
|
||||
&get_buffer_[0] + putback_max);
|
||||
if (unbuffered_)
|
||||
|
||||
if (put_buffer_.empty())
|
||||
setp(0, 0);
|
||||
else
|
||||
setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size());
|
||||
}
|
||||
|
||||
template <typename ResolverQuery>
|
||||
void resolve_and_connect(const ResolverQuery& query)
|
||||
int timeout() const
|
||||
{
|
||||
typedef typename Protocol::resolver resolver_type;
|
||||
typedef typename resolver_type::iterator iterator_type;
|
||||
resolver_type resolver(detail::socket_streambuf_base::io_service_);
|
||||
iterator_type i = resolver.resolve(query, ec_);
|
||||
if (!ec_)
|
||||
{
|
||||
iterator_type end;
|
||||
ec_ = boost::asio::error::host_not_found;
|
||||
while (ec_ && i != end)
|
||||
{
|
||||
this->basic_socket<Protocol, StreamSocketService>::close(ec_);
|
||||
|
||||
if (timer_state_ == timer_has_expired)
|
||||
{
|
||||
ec_ = boost::asio::error::operation_aborted;
|
||||
return;
|
||||
}
|
||||
|
||||
io_handler handler = { this };
|
||||
this->basic_socket<Protocol, StreamSocketService>::async_connect(
|
||||
*i, handler);
|
||||
|
||||
ec_ = boost::asio::error::would_block;
|
||||
this->get_service().get_io_service().reset();
|
||||
do this->get_service().get_io_service().run_one();
|
||||
while (ec_ == boost::asio::error::would_block);
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
int64_t msec = traits_helper::to_posix_duration(
|
||||
traits_helper::subtract(expiry_time_,
|
||||
traits_helper::now())).total_milliseconds();
|
||||
if (msec > (std::numeric_limits<int>::max)())
|
||||
msec = (std::numeric_limits<int>::max)();
|
||||
else if (msec < 0)
|
||||
msec = 0;
|
||||
return static_cast<int>(msec);
|
||||
}
|
||||
|
||||
struct io_handler;
|
||||
friend struct io_handler;
|
||||
struct io_handler
|
||||
template <typename EndpointSequence>
|
||||
void connect_to_endpoints(const EndpointSequence& endpoints)
|
||||
{
|
||||
basic_socket_streambuf* this_;
|
||||
|
||||
void operator()(const boost::system::error_code& ec,
|
||||
std::size_t bytes_transferred = 0)
|
||||
{
|
||||
this_->ec_ = ec;
|
||||
this_->bytes_transferred_ = bytes_transferred;
|
||||
}
|
||||
};
|
||||
|
||||
struct timer_handler;
|
||||
friend struct timer_handler;
|
||||
struct timer_handler
|
||||
{
|
||||
basic_socket_streambuf* this_;
|
||||
|
||||
void operator()(const boost::system::error_code&)
|
||||
{
|
||||
time_type now = traits_helper::now();
|
||||
|
||||
time_type expiry_time = this_->timer_service_->expires_at(
|
||||
this_->timer_implementation_);
|
||||
|
||||
if (traits_helper::less_than(now, expiry_time))
|
||||
{
|
||||
this_->timer_state_ = timer_is_pending;
|
||||
this_->timer_service_->async_wait(this_->timer_implementation_, *this);
|
||||
}
|
||||
else
|
||||
{
|
||||
this_->timer_state_ = timer_has_expired;
|
||||
boost::system::error_code ec;
|
||||
this_->basic_socket<Protocol, StreamSocketService>::close(ec);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void construct_timer()
|
||||
{
|
||||
if (timer_service_ == 0)
|
||||
{
|
||||
TimerService& timer_service = use_service<TimerService>(
|
||||
detail::socket_streambuf_base::io_service_);
|
||||
timer_service.construct(timer_implementation_);
|
||||
timer_service_ = &timer_service;
|
||||
}
|
||||
this->connect_to_endpoints(endpoints.begin(), endpoints.end());
|
||||
}
|
||||
|
||||
void destroy_timer()
|
||||
template <typename EndpointIterator>
|
||||
void connect_to_endpoints(EndpointIterator begin, EndpointIterator end)
|
||||
{
|
||||
if (timer_service_)
|
||||
timer_service_->destroy(timer_implementation_);
|
||||
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
||||
ec_ = boost::asio::error::operation_not_supported;
|
||||
#else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
||||
if (ec_)
|
||||
return;
|
||||
|
||||
ec_ = boost::asio::error::not_found;
|
||||
for (EndpointIterator i = begin; i != end; ++i)
|
||||
{
|
||||
// Check if we are past the expiry time.
|
||||
if (traits_helper::less_than(expiry_time_, traits_helper::now()))
|
||||
{
|
||||
ec_ = boost::asio::error::timed_out;
|
||||
return;
|
||||
}
|
||||
|
||||
// Close and reopen the socket.
|
||||
typename Protocol::endpoint ep(*i);
|
||||
socket().close(ec_);
|
||||
socket().open(ep.protocol(), ec_);
|
||||
if (ec_)
|
||||
continue;
|
||||
|
||||
// Try to complete the operation without blocking.
|
||||
if (!socket().native_non_blocking())
|
||||
socket().native_non_blocking(true, ec_);
|
||||
detail::socket_ops::connect(socket().native_handle(),
|
||||
ep.data(), ep.size(), ec_);
|
||||
|
||||
// Check if operation succeeded.
|
||||
if (!ec_)
|
||||
return;
|
||||
|
||||
// Operation failed.
|
||||
if (ec_ != boost::asio::error::in_progress
|
||||
&& ec_ != boost::asio::error::would_block)
|
||||
continue;
|
||||
|
||||
// Wait for socket to become ready.
|
||||
if (detail::socket_ops::poll_connect(
|
||||
socket().native_handle(), timeout(), ec_) < 0)
|
||||
continue;
|
||||
|
||||
// Get the error code from the connect operation.
|
||||
int connect_error = 0;
|
||||
size_t connect_error_len = sizeof(connect_error);
|
||||
if (detail::socket_ops::getsockopt(socket().native_handle(), 0,
|
||||
SOL_SOCKET, SO_ERROR, &connect_error, &connect_error_len, ec_)
|
||||
== detail::socket_error_retval)
|
||||
return;
|
||||
|
||||
// Check the result of the connect operation.
|
||||
ec_ = boost::system::error_code(connect_error,
|
||||
boost::asio::error::get_system_category());
|
||||
if (!ec_)
|
||||
return;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
||||
}
|
||||
|
||||
void start_timer()
|
||||
// Helper function to get the maximum expiry time.
|
||||
static time_point max_expiry_time()
|
||||
{
|
||||
if (timer_state_ != timer_is_pending)
|
||||
{
|
||||
timer_handler handler = { this };
|
||||
handler(boost::system::error_code());
|
||||
}
|
||||
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
|
||||
&& defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
|
||||
return boost::posix_time::pos_infin;
|
||||
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
|
||||
return (time_point::max)();
|
||||
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
|
||||
}
|
||||
|
||||
enum { putback_max = 8 };
|
||||
enum { buffer_size = 512 };
|
||||
boost::asio::detail::array<char, buffer_size> get_buffer_;
|
||||
boost::asio::detail::array<char, buffer_size> put_buffer_;
|
||||
bool unbuffered_;
|
||||
boost::system::error_code ec_;
|
||||
std::size_t bytes_transferred_;
|
||||
TimerService* timer_service_;
|
||||
typename TimerService::implementation_type timer_implementation_;
|
||||
enum state { no_timer, timer_is_pending, timer_has_expired } timer_state_;
|
||||
time_point expiry_time_;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// basic_stream_socket.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -20,15 +20,24 @@
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/basic_socket.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/error.hpp>
|
||||
#include <boost/asio/stream_socket_service.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
#if !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL)
|
||||
#define BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL
|
||||
|
||||
// Forward declaration with defaulted arguments.
|
||||
template <typename Protocol, typename Executor = executor>
|
||||
class basic_stream_socket;
|
||||
|
||||
#endif // !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL)
|
||||
|
||||
/// Provides stream-oriented socket functionality.
|
||||
/**
|
||||
* The basic_stream_socket class template provides asynchronous and blocking
|
||||
@@ -41,18 +50,29 @@ namespace asio {
|
||||
* @par Concepts:
|
||||
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
|
||||
*/
|
||||
template <typename Protocol,
|
||||
typename StreamSocketService = stream_socket_service<Protocol> >
|
||||
template <typename Protocol, typename Executor>
|
||||
class basic_stream_socket
|
||||
: public basic_socket<Protocol, StreamSocketService>
|
||||
: public basic_socket<Protocol, Executor>
|
||||
{
|
||||
public:
|
||||
/// (Deprecated: Use native_handle_type.) The native representation of a
|
||||
/// socket.
|
||||
typedef typename StreamSocketService::native_handle_type native_type;
|
||||
/// The type of the executor associated with the object.
|
||||
typedef Executor executor_type;
|
||||
|
||||
/// Rebinds the socket type to another executor.
|
||||
template <typename Executor1>
|
||||
struct rebind_executor
|
||||
{
|
||||
/// The socket type when rebound to the specified executor.
|
||||
typedef basic_stream_socket<Protocol, Executor1> other;
|
||||
};
|
||||
|
||||
/// The native representation of a socket.
|
||||
typedef typename StreamSocketService::native_handle_type native_handle_type;
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
typedef implementation_defined native_handle_type;
|
||||
#else
|
||||
typedef typename basic_socket<Protocol,
|
||||
Executor>::native_handle_type native_handle_type;
|
||||
#endif
|
||||
|
||||
/// The protocol type.
|
||||
typedef Protocol protocol_type;
|
||||
@@ -66,11 +86,30 @@ public:
|
||||
* needs to be opened and then connected or accepted before data can be sent
|
||||
* or received on it.
|
||||
*
|
||||
* @param io_service The io_service object that the stream socket will use to
|
||||
* @param ex The I/O executor that the socket will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*/
|
||||
explicit basic_stream_socket(boost::asio::io_service& io_service)
|
||||
: basic_socket<Protocol, StreamSocketService>(io_service)
|
||||
explicit basic_stream_socket(const executor_type& ex)
|
||||
: basic_socket<Protocol, Executor>(ex)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a basic_stream_socket without opening it.
|
||||
/**
|
||||
* This constructor creates a stream socket without opening it. The socket
|
||||
* needs to be opened and then connected or accepted before data can be sent
|
||||
* or received on it.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the socket will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the socket.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
explicit basic_stream_socket(ExecutionContext& context,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(context)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -79,16 +118,37 @@ public:
|
||||
* This constructor creates and opens a stream socket. The socket needs to be
|
||||
* connected or accepted before data can be sent or received on it.
|
||||
*
|
||||
* @param io_service The io_service object that the stream socket will use to
|
||||
* @param ex The I/O executor that the socket will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
basic_stream_socket(boost::asio::io_service& io_service,
|
||||
const protocol_type& protocol)
|
||||
: basic_socket<Protocol, StreamSocketService>(io_service, protocol)
|
||||
basic_stream_socket(const executor_type& ex, const protocol_type& protocol)
|
||||
: basic_socket<Protocol, Executor>(ex, protocol)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct and open a basic_stream_socket.
|
||||
/**
|
||||
* This constructor creates and opens a stream socket. The socket needs to be
|
||||
* connected or accepted before data can be sent or received on it.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the socket will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_stream_socket(ExecutionContext& context, const protocol_type& protocol,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(context, protocol)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -99,7 +159,7 @@ public:
|
||||
* to the specified endpoint on the local machine. The protocol used is the
|
||||
* protocol associated with the given endpoint.
|
||||
*
|
||||
* @param io_service The io_service object that the stream socket will use to
|
||||
* @param ex The I/O executor that the socket will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*
|
||||
* @param endpoint An endpoint on the local machine to which the stream
|
||||
@@ -107,9 +167,33 @@ public:
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
basic_stream_socket(boost::asio::io_service& io_service,
|
||||
const endpoint_type& endpoint)
|
||||
: basic_socket<Protocol, StreamSocketService>(io_service, endpoint)
|
||||
basic_stream_socket(const executor_type& ex, const endpoint_type& endpoint)
|
||||
: basic_socket<Protocol, Executor>(ex, endpoint)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a basic_stream_socket, opening it and binding it to the given
|
||||
/// local endpoint.
|
||||
/**
|
||||
* This constructor creates a stream socket and automatically opens it bound
|
||||
* to the specified endpoint on the local machine. The protocol used is the
|
||||
* protocol associated with the given endpoint.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the socket will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the socket.
|
||||
*
|
||||
* @param endpoint An endpoint on the local machine to which the stream
|
||||
* socket will be bound.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_stream_socket(ExecutionContext& context, const endpoint_type& endpoint,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(context, endpoint)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -118,7 +202,7 @@ public:
|
||||
* This constructor creates a stream socket object to hold an existing native
|
||||
* socket.
|
||||
*
|
||||
* @param io_service The io_service object that the stream socket will use to
|
||||
* @param ex The I/O executor that the socket will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
@@ -127,10 +211,34 @@ public:
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
basic_stream_socket(boost::asio::io_service& io_service,
|
||||
basic_stream_socket(const executor_type& ex,
|
||||
const protocol_type& protocol, const native_handle_type& native_socket)
|
||||
: basic_socket<Protocol, StreamSocketService>(
|
||||
io_service, protocol, native_socket)
|
||||
: basic_socket<Protocol, Executor>(ex, protocol, native_socket)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a basic_stream_socket on an existing native socket.
|
||||
/**
|
||||
* This constructor creates a stream socket object to hold an existing native
|
||||
* socket.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the socket will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @param native_socket The new underlying socket implementation.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
basic_stream_socket(ExecutionContext& context,
|
||||
const protocol_type& protocol, const native_handle_type& native_socket,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -143,11 +251,11 @@ public:
|
||||
* will occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_stream_socket(io_service&) constructor.
|
||||
* constructed using the @c basic_stream_socket(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
basic_stream_socket(basic_stream_socket&& other)
|
||||
: basic_socket<Protocol, StreamSocketService>(
|
||||
BOOST_ASIO_MOVE_CAST(basic_stream_socket)(other))
|
||||
: basic_socket<Protocol, Executor>(std::move(other))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -159,12 +267,12 @@ public:
|
||||
* will occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_stream_socket(io_service&) constructor.
|
||||
* constructed using the @c basic_stream_socket(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
basic_stream_socket& operator=(basic_stream_socket&& other)
|
||||
{
|
||||
basic_socket<Protocol, StreamSocketService>::operator=(
|
||||
BOOST_ASIO_MOVE_CAST(basic_stream_socket)(other));
|
||||
basic_socket<Protocol, Executor>::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -177,15 +285,16 @@ public:
|
||||
* will occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_stream_socket(io_service&) constructor.
|
||||
* constructed using the @c basic_stream_socket(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
template <typename Protocol1, typename StreamSocketService1>
|
||||
basic_stream_socket(
|
||||
basic_stream_socket<Protocol1, StreamSocketService1>&& other,
|
||||
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
|
||||
: basic_socket<Protocol, StreamSocketService>(
|
||||
BOOST_ASIO_MOVE_CAST2(basic_stream_socket<
|
||||
Protocol1, StreamSocketService1>)(other))
|
||||
template <typename Protocol1, typename Executor1>
|
||||
basic_stream_socket(basic_stream_socket<Protocol1, Executor1>&& other,
|
||||
typename enable_if<
|
||||
is_convertible<Protocol1, Protocol>::value
|
||||
&& is_convertible<Executor1, Executor>::value
|
||||
>::type* = 0)
|
||||
: basic_socket<Protocol, Executor>(std::move(other))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -197,20 +306,30 @@ public:
|
||||
* will occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_stream_socket(io_service&) constructor.
|
||||
* constructed using the @c basic_stream_socket(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
template <typename Protocol1, typename StreamSocketService1>
|
||||
typename enable_if<is_convertible<Protocol1, Protocol>::value,
|
||||
basic_stream_socket>::type& operator=(
|
||||
basic_stream_socket<Protocol1, StreamSocketService1>&& other)
|
||||
template <typename Protocol1, typename Executor1>
|
||||
typename enable_if<
|
||||
is_convertible<Protocol1, Protocol>::value
|
||||
&& is_convertible<Executor1, Executor>::value,
|
||||
basic_stream_socket&
|
||||
>::type operator=(basic_stream_socket<Protocol1, Executor1>&& other)
|
||||
{
|
||||
basic_socket<Protocol, StreamSocketService>::operator=(
|
||||
BOOST_ASIO_MOVE_CAST2(basic_stream_socket<
|
||||
Protocol1, StreamSocketService1>)(other));
|
||||
basic_socket<Protocol, Executor>::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Destroys the socket.
|
||||
/**
|
||||
* This function destroys the socket, cancelling any outstanding asynchronous
|
||||
* operations associated with the socket as if by calling @c cancel.
|
||||
*/
|
||||
~basic_stream_socket()
|
||||
{
|
||||
}
|
||||
|
||||
/// Send some data on the socket.
|
||||
/**
|
||||
* This function is used to send data on the stream socket. The function
|
||||
@@ -240,8 +359,8 @@ public:
|
||||
std::size_t send(const ConstBufferSequence& buffers)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().send(
|
||||
this->get_implementation(), buffers, 0, ec);
|
||||
std::size_t s = this->impl_.get_service().send(
|
||||
this->impl_.get_implementation(), buffers, 0, ec);
|
||||
boost::asio::detail::throw_error(ec, "send");
|
||||
return s;
|
||||
}
|
||||
@@ -278,8 +397,8 @@ public:
|
||||
socket_base::message_flags flags)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().send(
|
||||
this->get_implementation(), buffers, flags, ec);
|
||||
std::size_t s = this->impl_.get_service().send(
|
||||
this->impl_.get_implementation(), buffers, flags, ec);
|
||||
boost::asio::detail::throw_error(ec, "send");
|
||||
return s;
|
||||
}
|
||||
@@ -306,8 +425,8 @@ public:
|
||||
std::size_t send(const ConstBufferSequence& buffers,
|
||||
socket_base::message_flags flags, boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().send(
|
||||
this->get_implementation(), buffers, flags, ec);
|
||||
return this->impl_.get_service().send(
|
||||
this->impl_.get_implementation(), buffers, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous send.
|
||||
@@ -328,9 +447,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes sent.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @note The send operation may not transmit all of the data to the peer.
|
||||
* Consider using the @ref async_write function if you need to ensure that all
|
||||
@@ -351,13 +470,10 @@ public:
|
||||
async_send(const ConstBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
// 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;
|
||||
|
||||
return this->get_service().async_send(
|
||||
this->get_implementation(), buffers, 0,
|
||||
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
return async_initiate<WriteHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_send(), handler, this,
|
||||
buffers, socket_base::message_flags(0));
|
||||
}
|
||||
|
||||
/// Start an asynchronous send.
|
||||
@@ -380,9 +496,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes sent.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @note The send operation may not transmit all of the data to the peer.
|
||||
* Consider using the @ref async_write function if you need to ensure that all
|
||||
@@ -404,13 +520,9 @@ public:
|
||||
socket_base::message_flags flags,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
// 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;
|
||||
|
||||
return this->get_service().async_send(
|
||||
this->get_implementation(), buffers, flags,
|
||||
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
return async_initiate<WriteHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_send(), handler, this, buffers, flags);
|
||||
}
|
||||
|
||||
/// Receive some data on the socket.
|
||||
@@ -445,8 +557,8 @@ public:
|
||||
std::size_t receive(const MutableBufferSequence& buffers)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().receive(
|
||||
this->get_implementation(), buffers, 0, ec);
|
||||
std::size_t s = this->impl_.get_service().receive(
|
||||
this->impl_.get_implementation(), buffers, 0, ec);
|
||||
boost::asio::detail::throw_error(ec, "receive");
|
||||
return s;
|
||||
}
|
||||
@@ -486,8 +598,8 @@ public:
|
||||
socket_base::message_flags flags)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().receive(
|
||||
this->get_implementation(), buffers, flags, ec);
|
||||
std::size_t s = this->impl_.get_service().receive(
|
||||
this->impl_.get_implementation(), buffers, flags, ec);
|
||||
boost::asio::detail::throw_error(ec, "receive");
|
||||
return s;
|
||||
}
|
||||
@@ -514,8 +626,8 @@ public:
|
||||
std::size_t receive(const MutableBufferSequence& buffers,
|
||||
socket_base::message_flags flags, boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().receive(
|
||||
this->get_implementation(), buffers, flags, ec);
|
||||
return this->impl_.get_service().receive(
|
||||
this->impl_.get_implementation(), buffers, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive.
|
||||
@@ -536,9 +648,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes received.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @note The receive operation may not receive all of the requested number of
|
||||
* bytes. Consider using the @ref async_read function if you need to ensure
|
||||
@@ -561,12 +673,10 @@ public:
|
||||
async_receive(const MutableBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
// If you get an error on the following line it means that your handler does
|
||||
// not meet the documented type requirements for a ReadHandler.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
return this->get_service().async_receive(this->get_implementation(),
|
||||
buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
return async_initiate<ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_receive(), handler, this,
|
||||
buffers, socket_base::message_flags(0));
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive.
|
||||
@@ -589,9 +699,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes received.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @note The receive operation may not receive all of the requested number of
|
||||
* bytes. Consider using the @ref async_read function if you need to ensure
|
||||
@@ -615,12 +725,9 @@ public:
|
||||
socket_base::message_flags flags,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
// If you get an error on the following line it means that your handler does
|
||||
// not meet the documented type requirements for a ReadHandler.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
return this->get_service().async_receive(this->get_implementation(),
|
||||
buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
return async_initiate<ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_receive(), handler, this, buffers, flags);
|
||||
}
|
||||
|
||||
/// Write some data to the socket.
|
||||
@@ -654,8 +761,8 @@ public:
|
||||
std::size_t write_some(const ConstBufferSequence& buffers)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().send(
|
||||
this->get_implementation(), buffers, 0, ec);
|
||||
std::size_t s = this->impl_.get_service().send(
|
||||
this->impl_.get_implementation(), buffers, 0, ec);
|
||||
boost::asio::detail::throw_error(ec, "write_some");
|
||||
return s;
|
||||
}
|
||||
@@ -680,7 +787,8 @@ public:
|
||||
std::size_t write_some(const ConstBufferSequence& buffers,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().send(this->get_implementation(), buffers, 0, ec);
|
||||
return this->impl_.get_service().send(
|
||||
this->impl_.get_implementation(), buffers, 0, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous write.
|
||||
@@ -701,9 +809,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes written.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @note The write operation may not transmit all of the data to the peer.
|
||||
* Consider using the @ref async_write function if you need to ensure that all
|
||||
@@ -724,12 +832,10 @@ public:
|
||||
async_write_some(const ConstBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
// 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;
|
||||
|
||||
return this->get_service().async_send(this->get_implementation(),
|
||||
buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
return async_initiate<WriteHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_send(), handler, this,
|
||||
buffers, socket_base::message_flags(0));
|
||||
}
|
||||
|
||||
/// Read some data from the socket.
|
||||
@@ -764,8 +870,8 @@ public:
|
||||
std::size_t read_some(const MutableBufferSequence& buffers)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->get_service().receive(
|
||||
this->get_implementation(), buffers, 0, ec);
|
||||
std::size_t s = this->impl_.get_service().receive(
|
||||
this->impl_.get_implementation(), buffers, 0, ec);
|
||||
boost::asio::detail::throw_error(ec, "read_some");
|
||||
return s;
|
||||
}
|
||||
@@ -791,8 +897,8 @@ public:
|
||||
std::size_t read_some(const MutableBufferSequence& buffers,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->get_service().receive(
|
||||
this->get_implementation(), buffers, 0, ec);
|
||||
return this->impl_.get_service().receive(
|
||||
this->impl_.get_implementation(), buffers, 0, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous read.
|
||||
@@ -813,9 +919,9 @@ public:
|
||||
* std::size_t bytes_transferred // Number of bytes read.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @note The read operation may not read all of the requested number of bytes.
|
||||
* Consider using the @ref async_read function if you need to ensure that the
|
||||
@@ -837,13 +943,48 @@ public:
|
||||
async_read_some(const MutableBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
// If you get an error on the following line it means that your handler does
|
||||
// not meet the documented type requirements for a ReadHandler.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
return this->get_service().async_receive(this->get_implementation(),
|
||||
buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
return async_initiate<ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_receive(), handler, this,
|
||||
buffers, socket_base::message_flags(0));
|
||||
}
|
||||
|
||||
private:
|
||||
struct initiate_async_send
|
||||
{
|
||||
template <typename WriteHandler, typename ConstBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
|
||||
basic_stream_socket* self, const ConstBufferSequence& buffers,
|
||||
socket_base::message_flags flags) 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;
|
||||
|
||||
detail::non_const_lvalue<WriteHandler> handler2(handler);
|
||||
self->impl_.get_service().async_send(
|
||||
self->impl_.get_implementation(), buffers, flags,
|
||||
handler2.value, self->impl_.get_implementation_executor());
|
||||
}
|
||||
};
|
||||
|
||||
struct initiate_async_receive
|
||||
{
|
||||
template <typename ReadHandler, typename MutableBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
|
||||
basic_stream_socket* self, const MutableBufferSequence& buffers,
|
||||
socket_base::message_flags flags) 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.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
detail::non_const_lvalue<ReadHandler> handler2(handler);
|
||||
self->impl_.get_service().async_receive(
|
||||
self->impl_.get_implementation(), buffers, flags,
|
||||
handler2.value, self->impl_.get_implementation_executor());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// basic_streambuf.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -120,8 +120,8 @@ public:
|
||||
/// The type used to represent the output sequence as a list of buffers.
|
||||
typedef implementation_defined mutable_buffers_type;
|
||||
#else
|
||||
typedef boost::asio::const_buffers_1 const_buffers_type;
|
||||
typedef boost::asio::mutable_buffers_1 mutable_buffers_type;
|
||||
typedef BOOST_ASIO_CONST_BUFFER const_buffers_type;
|
||||
typedef BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_type;
|
||||
#endif
|
||||
|
||||
/// Construct a basic_streambuf object.
|
||||
@@ -152,11 +152,11 @@ public:
|
||||
* while (i != bufs.end())
|
||||
* {
|
||||
* const_buffer buf(*i++);
|
||||
* s += buffer_size(buf);
|
||||
* s += buf.size();
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
std::size_t size() const
|
||||
std::size_t size() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return pptr() - gptr();
|
||||
}
|
||||
@@ -166,11 +166,21 @@ public:
|
||||
* @returns The allowed maximum of the sum of the sizes of the input sequence
|
||||
* and output sequence.
|
||||
*/
|
||||
std::size_t max_size() const
|
||||
std::size_t max_size() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return max_size_;
|
||||
}
|
||||
|
||||
/// Get the current capacity of the basic_streambuf.
|
||||
/**
|
||||
* @returns The current total capacity of the streambuf, i.e. for both the
|
||||
* input sequence and output sequence.
|
||||
*/
|
||||
std::size_t capacity() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return buffer_.capacity();
|
||||
}
|
||||
|
||||
/// Get a list of buffers that represents the input sequence.
|
||||
/**
|
||||
* @returns An object of type @c const_buffers_type that satisfies
|
||||
@@ -180,7 +190,7 @@ public:
|
||||
* @note The returned object is invalidated by any @c basic_streambuf member
|
||||
* function that modifies the input sequence or output sequence.
|
||||
*/
|
||||
const_buffers_type data() const
|
||||
const_buffers_type data() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return boost::asio::buffer(boost::asio::const_buffer(gptr(),
|
||||
(pptr() - gptr()) * sizeof(char_type)));
|
||||
@@ -223,8 +233,7 @@ public:
|
||||
*/
|
||||
void commit(std::size_t n)
|
||||
{
|
||||
if (pptr() + n > epptr())
|
||||
n = epptr() - pptr();
|
||||
n = std::min<std::size_t>(n, epptr() - pptr());
|
||||
pbump(static_cast<int>(n));
|
||||
setg(eback(), gptr(), pptr());
|
||||
}
|
||||
@@ -351,15 +360,89 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
// Helper function to get the preferred size for reading data. Used for any
|
||||
// user-provided specialisations of basic_streambuf.
|
||||
/// Adapts basic_streambuf to the dynamic buffer sequence type requirements.
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
template <typename Allocator = std::allocator<char> >
|
||||
#else
|
||||
template <typename Allocator>
|
||||
inline std::size_t read_size_helper(
|
||||
basic_streambuf<Allocator>& sb, std::size_t max_size)
|
||||
#endif
|
||||
class basic_streambuf_ref
|
||||
{
|
||||
return std::min<std::size_t>(512,
|
||||
std::min<std::size_t>(max_size, sb.max_size() - sb.size()));
|
||||
}
|
||||
public:
|
||||
/// The type used to represent the input sequence as a list of buffers.
|
||||
typedef typename basic_streambuf<Allocator>::const_buffers_type
|
||||
const_buffers_type;
|
||||
|
||||
/// The type used to represent the output sequence as a list of buffers.
|
||||
typedef typename basic_streambuf<Allocator>::mutable_buffers_type
|
||||
mutable_buffers_type;
|
||||
|
||||
/// Construct a basic_streambuf_ref for the given basic_streambuf object.
|
||||
explicit basic_streambuf_ref(basic_streambuf<Allocator>& sb)
|
||||
: sb_(sb)
|
||||
{
|
||||
}
|
||||
|
||||
/// Copy construct a basic_streambuf_ref.
|
||||
basic_streambuf_ref(const basic_streambuf_ref& other) BOOST_ASIO_NOEXCEPT
|
||||
: sb_(other.sb_)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
/// Move construct a basic_streambuf_ref.
|
||||
basic_streambuf_ref(basic_streambuf_ref&& other) BOOST_ASIO_NOEXCEPT
|
||||
: sb_(other.sb_)
|
||||
{
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Get the size of the input sequence.
|
||||
std::size_t size() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return sb_.size();
|
||||
}
|
||||
|
||||
/// Get the maximum size of the dynamic buffer.
|
||||
std::size_t max_size() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return sb_.max_size();
|
||||
}
|
||||
|
||||
/// Get the current capacity of the dynamic buffer.
|
||||
std::size_t capacity() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return sb_.capacity();
|
||||
}
|
||||
|
||||
/// Get a list of buffers that represents the input sequence.
|
||||
const_buffers_type data() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return sb_.data();
|
||||
}
|
||||
|
||||
/// Get a list of buffers that represents the output sequence, with the given
|
||||
/// size.
|
||||
mutable_buffers_type prepare(std::size_t n)
|
||||
{
|
||||
return sb_.prepare(n);
|
||||
}
|
||||
|
||||
/// Move bytes from the output sequence to the input sequence.
|
||||
void commit(std::size_t n)
|
||||
{
|
||||
return sb_.commit(n);
|
||||
}
|
||||
|
||||
/// Remove characters from the input sequence.
|
||||
void consume(std::size_t n)
|
||||
{
|
||||
return sb_.consume(n);
|
||||
}
|
||||
|
||||
private:
|
||||
basic_streambuf<Allocator>& sb_;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// basic_streambuf_fwd.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -27,6 +27,9 @@ namespace asio {
|
||||
template <typename Allocator = std::allocator<char> >
|
||||
class basic_streambuf;
|
||||
|
||||
template <typename Allocator = std::allocator<char> >
|
||||
class basic_streambuf_ref;
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// basic_waitable_timer.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -17,18 +17,36 @@
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <cstddef>
|
||||
#include <boost/asio/basic_io_object.hpp>
|
||||
#include <boost/asio/detail/chrono_time_traits.hpp>
|
||||
#include <boost/asio/detail/deadline_timer_service.hpp>
|
||||
#include <boost/asio/detail/handler_type_requirements.hpp>
|
||||
#include <boost/asio/detail/io_object_impl.hpp>
|
||||
#include <boost/asio/detail/non_const_lvalue.hpp>
|
||||
#include <boost/asio/detail/throw_error.hpp>
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/asio/executor.hpp>
|
||||
#include <boost/asio/wait_traits.hpp>
|
||||
#include <boost/asio/waitable_timer_service.hpp>
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
# include <utility>
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
#if !defined(BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL)
|
||||
#define BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL
|
||||
|
||||
// Forward declaration with defaulted arguments.
|
||||
template <typename Clock,
|
||||
typename WaitTraits = boost::asio::wait_traits<Clock>,
|
||||
typename Executor = executor>
|
||||
class basic_waitable_timer;
|
||||
|
||||
#endif // !defined(BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL)
|
||||
|
||||
/// Provides waitable timer functionality.
|
||||
/**
|
||||
* The basic_waitable_timer class template provides the ability to perform a
|
||||
@@ -52,10 +70,10 @@ namespace asio {
|
||||
* Performing a blocking wait (C++11):
|
||||
* @code
|
||||
* // Construct a timer without setting an expiry time.
|
||||
* boost::asio::steady_timer timer(io_service);
|
||||
* boost::asio::steady_timer timer(my_context);
|
||||
*
|
||||
* // Set an expiry time relative to now.
|
||||
* timer.expires_from_now(std::chrono::seconds(5));
|
||||
* timer.expires_after(std::chrono::seconds(5));
|
||||
*
|
||||
* // Wait for the timer to expire.
|
||||
* timer.wait();
|
||||
@@ -75,7 +93,7 @@ namespace asio {
|
||||
* ...
|
||||
*
|
||||
* // Construct a timer with an absolute expiry time.
|
||||
* boost::asio::steady_timer timer(io_service,
|
||||
* boost::asio::steady_timer timer(my_context,
|
||||
* std::chrono::steady_clock::now() + std::chrono::seconds(60));
|
||||
*
|
||||
* // Start an asynchronous wait.
|
||||
@@ -92,7 +110,7 @@ namespace asio {
|
||||
* @code
|
||||
* void on_some_event()
|
||||
* {
|
||||
* if (my_timer.expires_from_now(seconds(5)) > 0)
|
||||
* if (my_timer.expires_after(seconds(5)) > 0)
|
||||
* {
|
||||
* // We managed to cancel the timer. Start new asynchronous wait.
|
||||
* my_timer.async_wait(on_timeout);
|
||||
@@ -112,7 +130,7 @@ namespace asio {
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @li The boost::asio::basic_waitable_timer::expires_from_now() function
|
||||
* @li The boost::asio::basic_waitable_timer::expires_after() function
|
||||
* cancels any pending asynchronous waits, and returns the number of
|
||||
* asynchronous waits that were cancelled. If it returns 0 then you were too
|
||||
* late and the wait handler has already been executed, or will soon be
|
||||
@@ -121,13 +139,13 @@ namespace asio {
|
||||
* @li If a wait handler is cancelled, the boost::system::error_code passed to
|
||||
* it contains the value boost::asio::error::operation_aborted.
|
||||
*/
|
||||
template <typename Clock,
|
||||
typename WaitTraits = boost::asio::wait_traits<Clock>,
|
||||
typename WaitableTimerService = waitable_timer_service<Clock, WaitTraits> >
|
||||
template <typename Clock, typename WaitTraits, typename Executor>
|
||||
class basic_waitable_timer
|
||||
: public basic_io_object<WaitableTimerService>
|
||||
{
|
||||
public:
|
||||
/// The type of the executor associated with the object.
|
||||
typedef Executor executor_type;
|
||||
|
||||
/// The clock type.
|
||||
typedef Clock clock_type;
|
||||
|
||||
@@ -143,14 +161,33 @@ public:
|
||||
/// Constructor.
|
||||
/**
|
||||
* This constructor creates a timer without setting an expiry time. The
|
||||
* expires_at() or expires_from_now() functions must be called to set an
|
||||
* expiry time before the timer can be waited on.
|
||||
* expires_at() or expires_after() functions must be called to set an expiry
|
||||
* time before the timer can be waited on.
|
||||
*
|
||||
* @param io_service The io_service object that the timer will use to dispatch
|
||||
* handlers for any asynchronous operations performed on the timer.
|
||||
* @param ex The I/O executor that the timer will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the timer.
|
||||
*/
|
||||
explicit basic_waitable_timer(boost::asio::io_service& io_service)
|
||||
: basic_io_object<WaitableTimerService>(io_service)
|
||||
explicit basic_waitable_timer(const executor_type& ex)
|
||||
: impl_(ex)
|
||||
{
|
||||
}
|
||||
|
||||
/// Constructor.
|
||||
/**
|
||||
* This constructor creates a timer without setting an expiry time. The
|
||||
* expires_at() or expires_after() functions must be called to set an expiry
|
||||
* time before the timer can be waited on.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the timer will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the timer.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
explicit basic_waitable_timer(ExecutionContext& context,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: impl_(context)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -158,18 +195,41 @@ public:
|
||||
/**
|
||||
* This constructor creates a timer and sets the expiry time.
|
||||
*
|
||||
* @param io_service The io_service object that the timer will use to dispatch
|
||||
* handlers for any asynchronous operations performed on the timer.
|
||||
* @param ex The I/O executor object that the timer will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the timer.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer, expressed
|
||||
* as an absolute time.
|
||||
*/
|
||||
basic_waitable_timer(boost::asio::io_service& io_service,
|
||||
const time_point& expiry_time)
|
||||
: basic_io_object<WaitableTimerService>(io_service)
|
||||
basic_waitable_timer(const executor_type& ex, const time_point& expiry_time)
|
||||
: impl_(ex)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->service.expires_at(this->implementation, expiry_time, ec);
|
||||
impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_at");
|
||||
}
|
||||
|
||||
/// Constructor to set a particular expiry time as an absolute time.
|
||||
/**
|
||||
* This constructor creates a timer and sets the expiry time.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the timer will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the timer.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer, expressed
|
||||
* as an absolute time.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
explicit basic_waitable_timer(ExecutionContext& context,
|
||||
const time_point& expiry_time,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: impl_(context)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_at");
|
||||
}
|
||||
|
||||
@@ -177,19 +237,95 @@ public:
|
||||
/**
|
||||
* This constructor creates a timer and sets the expiry time.
|
||||
*
|
||||
* @param io_service The io_service object that the timer will use to dispatch
|
||||
* handlers for any asynchronous operations performed on the timer.
|
||||
* @param ex The I/O executor that the timer will use, by default, to
|
||||
* dispatch handlers for any asynchronous operations performed on the timer.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer, relative to
|
||||
* now.
|
||||
*/
|
||||
basic_waitable_timer(boost::asio::io_service& io_service,
|
||||
const duration& expiry_time)
|
||||
: basic_io_object<WaitableTimerService>(io_service)
|
||||
basic_waitable_timer(const executor_type& ex, const duration& expiry_time)
|
||||
: impl_(ex)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->service.expires_from_now(this->implementation, expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_from_now");
|
||||
impl_.get_service().expires_after(
|
||||
impl_.get_implementation(), expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_after");
|
||||
}
|
||||
|
||||
/// Constructor to set a particular expiry time relative to now.
|
||||
/**
|
||||
* This constructor creates a timer and sets the expiry time.
|
||||
*
|
||||
* @param context An execution context which provides the I/O executor that
|
||||
* the timer will use, by default, to dispatch handlers for any asynchronous
|
||||
* operations performed on the timer.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer, relative to
|
||||
* now.
|
||||
*/
|
||||
template <typename ExecutionContext>
|
||||
explicit basic_waitable_timer(ExecutionContext& context,
|
||||
const duration& expiry_time,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0)
|
||||
: impl_(context)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
impl_.get_service().expires_after(
|
||||
impl_.get_implementation(), expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_after");
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
/// Move-construct a basic_waitable_timer from another.
|
||||
/**
|
||||
* This constructor moves a timer from one object to another.
|
||||
*
|
||||
* @param other The other basic_waitable_timer object from which the move will
|
||||
* occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_waitable_timer(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
basic_waitable_timer(basic_waitable_timer&& other)
|
||||
: impl_(std::move(other.impl_))
|
||||
{
|
||||
}
|
||||
|
||||
/// Move-assign a basic_waitable_timer from another.
|
||||
/**
|
||||
* This assignment operator moves a timer from one object to another. Cancels
|
||||
* any outstanding asynchronous operations associated with the target object.
|
||||
*
|
||||
* @param other The other basic_waitable_timer object from which the move will
|
||||
* occur.
|
||||
*
|
||||
* @note Following the move, the moved-from object is in the same state as if
|
||||
* constructed using the @c basic_waitable_timer(const executor_type&)
|
||||
* constructor.
|
||||
*/
|
||||
basic_waitable_timer& operator=(basic_waitable_timer&& other)
|
||||
{
|
||||
impl_ = std::move(other.impl_);
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Destroys the timer.
|
||||
/**
|
||||
* This function destroys the timer, cancelling any outstanding asynchronous
|
||||
* wait operations associated with the timer as if by calling @c cancel.
|
||||
*/
|
||||
~basic_waitable_timer()
|
||||
{
|
||||
}
|
||||
|
||||
/// Get the executor associated with the object.
|
||||
executor_type get_executor() BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return impl_.get_executor();
|
||||
}
|
||||
|
||||
/// Cancel any asynchronous operations that are waiting on the timer.
|
||||
@@ -217,12 +353,14 @@ public:
|
||||
std::size_t cancel()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->service.cancel(this->implementation, ec);
|
||||
std::size_t s = impl_.get_service().cancel(impl_.get_implementation(), ec);
|
||||
boost::asio::detail::throw_error(ec, "cancel");
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Cancel any asynchronous operations that are waiting on the timer.
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
/// (Deprecated: Use non-error_code overload.) Cancel any asynchronous
|
||||
/// operations that are waiting on the timer.
|
||||
/**
|
||||
* This function forces the completion of any pending asynchronous wait
|
||||
* operations against the timer. The handler for each cancelled operation will
|
||||
@@ -246,8 +384,9 @@ public:
|
||||
*/
|
||||
std::size_t cancel(boost::system::error_code& ec)
|
||||
{
|
||||
return this->service.cancel(this->implementation, ec);
|
||||
return impl_.get_service().cancel(impl_.get_implementation(), ec);
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
/// Cancels one asynchronous operation that is waiting on the timer.
|
||||
/**
|
||||
@@ -276,12 +415,15 @@ public:
|
||||
std::size_t cancel_one()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->service.cancel_one(this->implementation, ec);
|
||||
std::size_t s = impl_.get_service().cancel_one(
|
||||
impl_.get_implementation(), ec);
|
||||
boost::asio::detail::throw_error(ec, "cancel_one");
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Cancels one asynchronous operation that is waiting on the timer.
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
/// (Deprecated: Use non-error_code overload.) Cancels one asynchronous
|
||||
/// operation that is waiting on the timer.
|
||||
/**
|
||||
* This function forces the completion of one pending asynchronous wait
|
||||
* operation against the timer. Handlers are cancelled in FIFO order. The
|
||||
@@ -307,17 +449,29 @@ public:
|
||||
*/
|
||||
std::size_t cancel_one(boost::system::error_code& ec)
|
||||
{
|
||||
return this->service.cancel_one(this->implementation, ec);
|
||||
return impl_.get_service().cancel_one(impl_.get_implementation(), ec);
|
||||
}
|
||||
|
||||
/// Get the timer's expiry time as an absolute time.
|
||||
/// (Deprecated: Use expiry().) Get the timer's expiry time as an absolute
|
||||
/// time.
|
||||
/**
|
||||
* This function may be used to obtain the timer's current expiry time.
|
||||
* Whether the timer has expired or not does not affect this value.
|
||||
*/
|
||||
time_point expires_at() const
|
||||
{
|
||||
return this->service.expires_at(this->implementation);
|
||||
return impl_.get_service().expires_at(impl_.get_implementation());
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
/// Get the timer's expiry time as an absolute time.
|
||||
/**
|
||||
* This function may be used to obtain the timer's current expiry time.
|
||||
* Whether the timer has expired or not does not affect this value.
|
||||
*/
|
||||
time_point expiry() const
|
||||
{
|
||||
return impl_.get_service().expiry(impl_.get_implementation());
|
||||
}
|
||||
|
||||
/// Set the timer's expiry time as an absolute time.
|
||||
@@ -345,13 +499,15 @@ public:
|
||||
std::size_t expires_at(const time_point& expiry_time)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->service.expires_at(
|
||||
this->implementation, expiry_time, ec);
|
||||
std::size_t s = impl_.get_service().expires_at(
|
||||
impl_.get_implementation(), expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_at");
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Set the timer's expiry time as an absolute time.
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
/// (Deprecated: Use non-error_code overload.) Set the timer's expiry time as
|
||||
/// an absolute time.
|
||||
/**
|
||||
* This function sets the expiry time. Any pending asynchronous wait
|
||||
* operations will be cancelled. The handler for each cancelled operation will
|
||||
@@ -376,20 +532,55 @@ public:
|
||||
std::size_t expires_at(const time_point& expiry_time,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->service.expires_at(this->implementation, expiry_time, ec);
|
||||
return impl_.get_service().expires_at(
|
||||
impl_.get_implementation(), expiry_time, ec);
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
/// Set the timer's expiry time relative to now.
|
||||
/**
|
||||
* This function sets the expiry time. Any pending asynchronous wait
|
||||
* operations will be cancelled. The handler for each cancelled operation will
|
||||
* be invoked with the boost::asio::error::operation_aborted error code.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer.
|
||||
*
|
||||
* @return The number of asynchronous operations that were cancelled.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*
|
||||
* @note If the timer has already expired when expires_after() is called,
|
||||
* then the handlers for asynchronous wait operations will:
|
||||
*
|
||||
* @li have already been invoked; or
|
||||
*
|
||||
* @li have been queued for invocation in the near future.
|
||||
*
|
||||
* These handlers can no longer be cancelled, and therefore are passed an
|
||||
* error code that indicates the successful completion of the wait operation.
|
||||
*/
|
||||
std::size_t expires_after(const duration& expiry_time)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = impl_.get_service().expires_after(
|
||||
impl_.get_implementation(), expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_after");
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Get the timer's expiry time relative to now.
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
/// (Deprecated: Use expiry().) Get the timer's expiry time relative to now.
|
||||
/**
|
||||
* This function may be used to obtain the timer's current expiry time.
|
||||
* Whether the timer has expired or not does not affect this value.
|
||||
*/
|
||||
duration expires_from_now() const
|
||||
{
|
||||
return this->service.expires_from_now(this->implementation);
|
||||
return impl_.get_service().expires_from_now(impl_.get_implementation());
|
||||
}
|
||||
|
||||
/// Set the timer's expiry time relative to now.
|
||||
/// (Deprecated: Use expires_after().) Set the timer's expiry time relative
|
||||
/// to now.
|
||||
/**
|
||||
* This function sets the expiry time. Any pending asynchronous wait
|
||||
* operations will be cancelled. The handler for each cancelled operation will
|
||||
@@ -414,13 +605,14 @@ public:
|
||||
std::size_t expires_from_now(const duration& expiry_time)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->service.expires_from_now(
|
||||
this->implementation, expiry_time, ec);
|
||||
std::size_t s = impl_.get_service().expires_from_now(
|
||||
impl_.get_implementation(), expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_from_now");
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Set the timer's expiry time relative to now.
|
||||
/// (Deprecated: Use expires_after().) Set the timer's expiry time relative
|
||||
/// to now.
|
||||
/**
|
||||
* This function sets the expiry time. Any pending asynchronous wait
|
||||
* operations will be cancelled. The handler for each cancelled operation will
|
||||
@@ -445,9 +637,10 @@ public:
|
||||
std::size_t expires_from_now(const duration& expiry_time,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->service.expires_from_now(
|
||||
this->implementation, expiry_time, ec);
|
||||
return impl_.get_service().expires_from_now(
|
||||
impl_.get_implementation(), expiry_time, ec);
|
||||
}
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
/// Perform a blocking wait on the timer.
|
||||
/**
|
||||
@@ -459,7 +652,7 @@ public:
|
||||
void wait()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->service.wait(this->implementation, ec);
|
||||
impl_.get_service().wait(impl_.get_implementation(), ec);
|
||||
boost::asio::detail::throw_error(ec, "wait");
|
||||
}
|
||||
|
||||
@@ -472,7 +665,7 @@ public:
|
||||
*/
|
||||
void wait(boost::system::error_code& ec)
|
||||
{
|
||||
this->service.wait(this->implementation, ec);
|
||||
impl_.get_service().wait(impl_.get_implementation(), ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous wait on the timer.
|
||||
@@ -495,22 +688,46 @@ public:
|
||||
* const boost::system::error_code& error // Result of operation.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
* not, the handler will not be invoked from within this function. On
|
||||
* immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*/
|
||||
template <typename WaitHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
|
||||
void (boost::system::error_code))
|
||||
async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
|
||||
{
|
||||
// If you get an error on the following line it means that your handler does
|
||||
// not meet the documented type requirements for a WaitHandler.
|
||||
BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
|
||||
|
||||
return this->service.async_wait(this->implementation,
|
||||
BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
|
||||
return async_initiate<WaitHandler, void (boost::system::error_code)>(
|
||||
initiate_async_wait(), handler, this);
|
||||
}
|
||||
|
||||
private:
|
||||
// Disallow copying and assignment.
|
||||
basic_waitable_timer(const basic_waitable_timer&) BOOST_ASIO_DELETED;
|
||||
basic_waitable_timer& operator=(
|
||||
const basic_waitable_timer&) BOOST_ASIO_DELETED;
|
||||
|
||||
struct initiate_async_wait
|
||||
{
|
||||
template <typename WaitHandler>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler,
|
||||
basic_waitable_timer* self) const
|
||||
{
|
||||
// If you get an error on the following line it means that your handler
|
||||
// does not meet the documented type requirements for a WaitHandler.
|
||||
BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
|
||||
|
||||
detail::non_const_lvalue<WaitHandler> handler2(handler);
|
||||
self->impl_.get_service().async_wait(
|
||||
self->impl_.get_implementation(), handler2.value,
|
||||
self->impl_.get_implementation_executor());
|
||||
}
|
||||
};
|
||||
|
||||
detail::io_object_impl<
|
||||
detail::deadline_timer_service<
|
||||
detail::chrono_time_traits<Clock, WaitTraits> >,
|
||||
executor_type > impl_;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
582
winx64/include/boost/asio/bind_executor.hpp
Normal file
582
winx64/include/boost/asio/bind_executor.hpp
Normal file
@@ -0,0 +1,582 @@
|
||||
//
|
||||
// bind_executor.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_BIND_EXECUTOR_HPP
|
||||
#define BOOST_ASIO_BIND_EXECUTOR_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/type_traits.hpp>
|
||||
#include <boost/asio/detail/variadic_templates.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/execution_context.hpp>
|
||||
#include <boost/asio/is_executor.hpp>
|
||||
#include <boost/asio/uses_executor.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct executor_binder_check
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
// Helper to automatically define nested typedef result_type.
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct executor_binder_result_type
|
||||
{
|
||||
protected:
|
||||
typedef void result_type_or_void;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct executor_binder_result_type<T,
|
||||
typename executor_binder_check<typename T::result_type>::type>
|
||||
{
|
||||
typedef typename T::result_type result_type;
|
||||
protected:
|
||||
typedef result_type result_type_or_void;
|
||||
};
|
||||
|
||||
template <typename R>
|
||||
struct executor_binder_result_type<R(*)()>
|
||||
{
|
||||
typedef R result_type;
|
||||
protected:
|
||||
typedef result_type result_type_or_void;
|
||||
};
|
||||
|
||||
template <typename R>
|
||||
struct executor_binder_result_type<R(&)()>
|
||||
{
|
||||
typedef R result_type;
|
||||
protected:
|
||||
typedef result_type result_type_or_void;
|
||||
};
|
||||
|
||||
template <typename R, typename A1>
|
||||
struct executor_binder_result_type<R(*)(A1)>
|
||||
{
|
||||
typedef R result_type;
|
||||
protected:
|
||||
typedef result_type result_type_or_void;
|
||||
};
|
||||
|
||||
template <typename R, typename A1>
|
||||
struct executor_binder_result_type<R(&)(A1)>
|
||||
{
|
||||
typedef R result_type;
|
||||
protected:
|
||||
typedef result_type result_type_or_void;
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2>
|
||||
struct executor_binder_result_type<R(*)(A1, A2)>
|
||||
{
|
||||
typedef R result_type;
|
||||
protected:
|
||||
typedef result_type result_type_or_void;
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2>
|
||||
struct executor_binder_result_type<R(&)(A1, A2)>
|
||||
{
|
||||
typedef R result_type;
|
||||
protected:
|
||||
typedef result_type result_type_or_void;
|
||||
};
|
||||
|
||||
// Helper to automatically define nested typedef argument_type.
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct executor_binder_argument_type {};
|
||||
|
||||
template <typename T>
|
||||
struct executor_binder_argument_type<T,
|
||||
typename executor_binder_check<typename T::argument_type>::type>
|
||||
{
|
||||
typedef typename T::argument_type argument_type;
|
||||
};
|
||||
|
||||
template <typename R, typename A1>
|
||||
struct executor_binder_argument_type<R(*)(A1)>
|
||||
{
|
||||
typedef A1 argument_type;
|
||||
};
|
||||
|
||||
template <typename R, typename A1>
|
||||
struct executor_binder_argument_type<R(&)(A1)>
|
||||
{
|
||||
typedef A1 argument_type;
|
||||
};
|
||||
|
||||
// Helper to automatically define nested typedefs first_argument_type and
|
||||
// second_argument_type.
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct executor_binder_argument_types {};
|
||||
|
||||
template <typename T>
|
||||
struct executor_binder_argument_types<T,
|
||||
typename executor_binder_check<typename T::first_argument_type>::type>
|
||||
{
|
||||
typedef typename T::first_argument_type first_argument_type;
|
||||
typedef typename T::second_argument_type second_argument_type;
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2>
|
||||
struct executor_binder_argument_type<R(*)(A1, A2)>
|
||||
{
|
||||
typedef A1 first_argument_type;
|
||||
typedef A2 second_argument_type;
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2>
|
||||
struct executor_binder_argument_type<R(&)(A1, A2)>
|
||||
{
|
||||
typedef A1 first_argument_type;
|
||||
typedef A2 second_argument_type;
|
||||
};
|
||||
|
||||
// Helper to:
|
||||
// - Apply the empty base optimisation to the executor.
|
||||
// - Perform uses_executor construction of the target type, if required.
|
||||
|
||||
template <typename T, typename Executor, bool UsesExecutor>
|
||||
class executor_binder_base;
|
||||
|
||||
template <typename T, typename Executor>
|
||||
class executor_binder_base<T, Executor, true>
|
||||
: protected Executor
|
||||
{
|
||||
protected:
|
||||
template <typename E, typename U>
|
||||
executor_binder_base(BOOST_ASIO_MOVE_ARG(E) e, BOOST_ASIO_MOVE_ARG(U) u)
|
||||
: executor_(BOOST_ASIO_MOVE_CAST(E)(e)),
|
||||
target_(executor_arg_t(), executor_, BOOST_ASIO_MOVE_CAST(U)(u))
|
||||
{
|
||||
}
|
||||
|
||||
Executor executor_;
|
||||
T target_;
|
||||
};
|
||||
|
||||
template <typename T, typename Executor>
|
||||
class executor_binder_base<T, Executor, false>
|
||||
{
|
||||
protected:
|
||||
template <typename E, typename U>
|
||||
executor_binder_base(BOOST_ASIO_MOVE_ARG(E) e, BOOST_ASIO_MOVE_ARG(U) u)
|
||||
: executor_(BOOST_ASIO_MOVE_CAST(E)(e)),
|
||||
target_(BOOST_ASIO_MOVE_CAST(U)(u))
|
||||
{
|
||||
}
|
||||
|
||||
Executor executor_;
|
||||
T target_;
|
||||
};
|
||||
|
||||
// Helper to enable SFINAE on zero-argument operator() below.
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct executor_binder_result_of0
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct executor_binder_result_of0<T,
|
||||
typename executor_binder_check<typename result_of<T()>::type>::type>
|
||||
{
|
||||
typedef typename result_of<T()>::type type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// A call wrapper type to bind an executor of type @c Executor to an object of
|
||||
/// type @c T.
|
||||
template <typename T, typename Executor>
|
||||
class executor_binder
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
: public detail::executor_binder_result_type<T>,
|
||||
public detail::executor_binder_argument_type<T>,
|
||||
public detail::executor_binder_argument_types<T>,
|
||||
private detail::executor_binder_base<
|
||||
T, Executor, uses_executor<T, Executor>::value>
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
{
|
||||
public:
|
||||
/// The type of the target object.
|
||||
typedef T target_type;
|
||||
|
||||
/// The type of the associated executor.
|
||||
typedef Executor executor_type;
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
/// The return type if a function.
|
||||
/**
|
||||
* The type of @c result_type is based on the type @c T of the wrapper's
|
||||
* target object:
|
||||
*
|
||||
* @li if @c T is a pointer to function type, @c result_type is a synonym for
|
||||
* the return type of @c T;
|
||||
*
|
||||
* @li if @c T is a class type with a member type @c result_type, then @c
|
||||
* result_type is a synonym for @c T::result_type;
|
||||
*
|
||||
* @li otherwise @c result_type is not defined.
|
||||
*/
|
||||
typedef see_below result_type;
|
||||
|
||||
/// The type of the function's argument.
|
||||
/**
|
||||
* The type of @c argument_type is based on the type @c T of the wrapper's
|
||||
* target object:
|
||||
*
|
||||
* @li if @c T is a pointer to a function type accepting a single argument,
|
||||
* @c argument_type is a synonym for the return type of @c T;
|
||||
*
|
||||
* @li if @c T is a class type with a member type @c argument_type, then @c
|
||||
* argument_type is a synonym for @c T::argument_type;
|
||||
*
|
||||
* @li otherwise @c argument_type is not defined.
|
||||
*/
|
||||
typedef see_below argument_type;
|
||||
|
||||
/// The type of the function's first argument.
|
||||
/**
|
||||
* The type of @c first_argument_type is based on the type @c T of the
|
||||
* wrapper's target object:
|
||||
*
|
||||
* @li if @c T is a pointer to a function type accepting two arguments, @c
|
||||
* first_argument_type is a synonym for the return type of @c T;
|
||||
*
|
||||
* @li if @c T is a class type with a member type @c first_argument_type,
|
||||
* then @c first_argument_type is a synonym for @c T::first_argument_type;
|
||||
*
|
||||
* @li otherwise @c first_argument_type is not defined.
|
||||
*/
|
||||
typedef see_below first_argument_type;
|
||||
|
||||
/// The type of the function's second argument.
|
||||
/**
|
||||
* The type of @c second_argument_type is based on the type @c T of the
|
||||
* wrapper's target object:
|
||||
*
|
||||
* @li if @c T is a pointer to a function type accepting two arguments, @c
|
||||
* second_argument_type is a synonym for the return type of @c T;
|
||||
*
|
||||
* @li if @c T is a class type with a member type @c first_argument_type,
|
||||
* then @c second_argument_type is a synonym for @c T::second_argument_type;
|
||||
*
|
||||
* @li otherwise @c second_argument_type is not defined.
|
||||
*/
|
||||
typedef see_below second_argument_type;
|
||||
#endif // defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Construct an executor wrapper for the specified object.
|
||||
/**
|
||||
* This constructor is only valid if the type @c T is constructible from type
|
||||
* @c U.
|
||||
*/
|
||||
template <typename U>
|
||||
executor_binder(executor_arg_t, const executor_type& e,
|
||||
BOOST_ASIO_MOVE_ARG(U) u)
|
||||
: base_type(e, BOOST_ASIO_MOVE_CAST(U)(u))
|
||||
{
|
||||
}
|
||||
|
||||
/// Copy constructor.
|
||||
executor_binder(const executor_binder& other)
|
||||
: base_type(other.get_executor(), other.get())
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a copy, but specify a different executor.
|
||||
executor_binder(executor_arg_t, const executor_type& e,
|
||||
const executor_binder& other)
|
||||
: base_type(e, other.get())
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a copy of a different executor wrapper type.
|
||||
/**
|
||||
* This constructor is only valid if the @c Executor type is constructible
|
||||
* from type @c OtherExecutor, and the type @c T is constructible from type
|
||||
* @c U.
|
||||
*/
|
||||
template <typename U, typename OtherExecutor>
|
||||
executor_binder(const executor_binder<U, OtherExecutor>& other)
|
||||
: base_type(other.get_executor(), other.get())
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a copy of a different executor wrapper type, but specify a
|
||||
/// different executor.
|
||||
/**
|
||||
* This constructor is only valid if the type @c T is constructible from type
|
||||
* @c U.
|
||||
*/
|
||||
template <typename U, typename OtherExecutor>
|
||||
executor_binder(executor_arg_t, const executor_type& e,
|
||||
const executor_binder<U, OtherExecutor>& other)
|
||||
: base_type(e, other.get())
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Move constructor.
|
||||
executor_binder(executor_binder&& other)
|
||||
: base_type(BOOST_ASIO_MOVE_CAST(executor_type)(other.get_executor()),
|
||||
BOOST_ASIO_MOVE_CAST(T)(other.get()))
|
||||
{
|
||||
}
|
||||
|
||||
/// Move construct the target object, but specify a different executor.
|
||||
executor_binder(executor_arg_t, const executor_type& e,
|
||||
executor_binder&& other)
|
||||
: base_type(e, BOOST_ASIO_MOVE_CAST(T)(other.get()))
|
||||
{
|
||||
}
|
||||
|
||||
/// Move construct from a different executor wrapper type.
|
||||
template <typename U, typename OtherExecutor>
|
||||
executor_binder(executor_binder<U, OtherExecutor>&& other)
|
||||
: base_type(BOOST_ASIO_MOVE_CAST(OtherExecutor)(other.get_executor()),
|
||||
BOOST_ASIO_MOVE_CAST(U)(other.get()))
|
||||
{
|
||||
}
|
||||
|
||||
/// Move construct from a different executor wrapper type, but specify a
|
||||
/// different executor.
|
||||
template <typename U, typename OtherExecutor>
|
||||
executor_binder(executor_arg_t, const executor_type& e,
|
||||
executor_binder<U, OtherExecutor>&& other)
|
||||
: base_type(e, BOOST_ASIO_MOVE_CAST(U)(other.get()))
|
||||
{
|
||||
}
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Destructor.
|
||||
~executor_binder()
|
||||
{
|
||||
}
|
||||
|
||||
/// Obtain a reference to the target object.
|
||||
target_type& get() BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return this->target_;
|
||||
}
|
||||
|
||||
/// Obtain a reference to the target object.
|
||||
const target_type& get() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return this->target_;
|
||||
}
|
||||
|
||||
/// Obtain the associated executor.
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return this->executor_;
|
||||
}
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename... Args> auto operator()(Args&& ...);
|
||||
template <typename... Args> auto operator()(Args&& ...) const;
|
||||
|
||||
#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
/// Forwarding function call operator.
|
||||
template <typename... Args>
|
||||
typename result_of<T(Args...)>::type operator()(
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||
{
|
||||
return this->target_(BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
|
||||
/// Forwarding function call operator.
|
||||
template <typename... Args>
|
||||
typename result_of<T(Args...)>::type operator()(
|
||||
BOOST_ASIO_MOVE_ARG(Args)... args) const
|
||||
{
|
||||
return this->target_(BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||
}
|
||||
|
||||
#elif defined(BOOST_ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)
|
||||
|
||||
typename detail::executor_binder_result_of0<T>::type operator()()
|
||||
{
|
||||
return this->target_();
|
||||
}
|
||||
|
||||
typename detail::executor_binder_result_of0<T>::type operator()() const
|
||||
{
|
||||
return this->target_();
|
||||
}
|
||||
|
||||
#define BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF(n) \
|
||||
template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
typename result_of<T(BOOST_ASIO_VARIADIC_TARGS(n))>::type operator()( \
|
||||
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||
{ \
|
||||
return this->target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||
} \
|
||||
\
|
||||
template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
typename result_of<T(BOOST_ASIO_VARIADIC_TARGS(n))>::type operator()( \
|
||||
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \
|
||||
{ \
|
||||
return this->target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||
} \
|
||||
/**/
|
||||
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF)
|
||||
#undef BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF
|
||||
|
||||
#else // defined(BOOST_ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)
|
||||
|
||||
typedef typename detail::executor_binder_result_type<T>::result_type_or_void
|
||||
result_type_or_void;
|
||||
|
||||
result_type_or_void operator()()
|
||||
{
|
||||
return this->target_();
|
||||
}
|
||||
|
||||
result_type_or_void operator()() const
|
||||
{
|
||||
return this->target_();
|
||||
}
|
||||
|
||||
#define BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF(n) \
|
||||
template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
result_type_or_void operator()( \
|
||||
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||
{ \
|
||||
return this->target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||
} \
|
||||
\
|
||||
template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||
result_type_or_void operator()( \
|
||||
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \
|
||||
{ \
|
||||
return this->target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||
} \
|
||||
/**/
|
||||
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF)
|
||||
#undef BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)
|
||||
|
||||
private:
|
||||
typedef detail::executor_binder_base<T, Executor,
|
||||
uses_executor<T, Executor>::value> base_type;
|
||||
};
|
||||
|
||||
/// Associate an object of type @c T with an executor of type @c Executor.
|
||||
template <typename Executor, typename T>
|
||||
inline executor_binder<typename decay<T>::type, Executor>
|
||||
bind_executor(const Executor& ex, BOOST_ASIO_MOVE_ARG(T) t,
|
||||
typename enable_if<is_executor<Executor>::value>::type* = 0)
|
||||
{
|
||||
return executor_binder<typename decay<T>::type, Executor>(
|
||||
executor_arg_t(), ex, BOOST_ASIO_MOVE_CAST(T)(t));
|
||||
}
|
||||
|
||||
/// Associate an object of type @c T with an execution context's executor.
|
||||
template <typename ExecutionContext, typename T>
|
||||
inline executor_binder<typename decay<T>::type,
|
||||
typename ExecutionContext::executor_type>
|
||||
bind_executor(ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(T) t,
|
||||
typename enable_if<is_convertible<
|
||||
ExecutionContext&, execution_context&>::value>::type* = 0)
|
||||
{
|
||||
return executor_binder<typename decay<T>::type,
|
||||
typename ExecutionContext::executor_type>(
|
||||
executor_arg_t(), ctx.get_executor(), BOOST_ASIO_MOVE_CAST(T)(t));
|
||||
}
|
||||
|
||||
#if !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
template <typename T, typename Executor>
|
||||
struct uses_executor<executor_binder<T, Executor>, Executor>
|
||||
: true_type {};
|
||||
|
||||
template <typename T, typename Executor, typename Signature>
|
||||
class async_result<executor_binder<T, Executor>, Signature>
|
||||
{
|
||||
public:
|
||||
typedef executor_binder<
|
||||
typename async_result<T, Signature>::completion_handler_type, Executor>
|
||||
completion_handler_type;
|
||||
|
||||
typedef typename async_result<T, Signature>::return_type return_type;
|
||||
|
||||
explicit async_result(executor_binder<T, Executor>& b)
|
||||
: target_(b.get())
|
||||
{
|
||||
}
|
||||
|
||||
return_type get()
|
||||
{
|
||||
return target_.get();
|
||||
}
|
||||
|
||||
private:
|
||||
async_result(const async_result&) BOOST_ASIO_DELETED;
|
||||
async_result& operator=(const async_result&) BOOST_ASIO_DELETED;
|
||||
|
||||
async_result<T, Signature> target_;
|
||||
};
|
||||
|
||||
template <typename T, typename Executor, typename Allocator>
|
||||
struct associated_allocator<executor_binder<T, Executor>, Allocator>
|
||||
{
|
||||
typedef typename associated_allocator<T, Allocator>::type type;
|
||||
|
||||
static type get(const executor_binder<T, Executor>& b,
|
||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_allocator<T, Allocator>::get(b.get(), a);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Executor, typename Executor1>
|
||||
struct associated_executor<executor_binder<T, Executor>, Executor1>
|
||||
{
|
||||
typedef Executor type;
|
||||
|
||||
static type get(const executor_binder<T, Executor>& b,
|
||||
const Executor1& = Executor1()) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return b.get_executor();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_BIND_EXECUTOR_HPP
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
// buffered_read_stream.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -26,7 +26,6 @@
|
||||
#include <boost/asio/detail/noncopyable.hpp>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
@@ -56,6 +55,9 @@ public:
|
||||
/// The type of the lowest layer.
|
||||
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
||||
|
||||
/// The type of the executor associated with the object.
|
||||
typedef typename lowest_layer_type::executor_type executor_type;
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
/// The default buffer size.
|
||||
static const std::size_t default_buffer_size = implementation_defined;
|
||||
@@ -97,10 +99,10 @@ public:
|
||||
return next_layer_.lowest_layer();
|
||||
}
|
||||
|
||||
/// Get the io_service associated with the object.
|
||||
boost::asio::io_service& get_io_service()
|
||||
/// Get the executor associated with the object.
|
||||
executor_type get_executor() BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return next_layer_.get_io_service();
|
||||
return next_layer_.lowest_layer().get_executor();
|
||||
}
|
||||
|
||||
/// Close the stream.
|
||||
@@ -110,9 +112,10 @@ public:
|
||||
}
|
||||
|
||||
/// Close the stream.
|
||||
boost::system::error_code close(boost::system::error_code& ec)
|
||||
BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
|
||||
{
|
||||
return next_layer_.close(ec);
|
||||
next_layer_.close(ec);
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
/// Write the given data to the stream. Returns the number of bytes written.
|
||||
@@ -140,15 +143,8 @@ public:
|
||||
async_write_some(const ConstBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
detail::async_result_init<
|
||||
WriteHandler, void (boost::system::error_code, std::size_t)> init(
|
||||
return next_layer_.async_write_some(buffers,
|
||||
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
|
||||
next_layer_.async_write_some(buffers,
|
||||
BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(WriteHandler,
|
||||
void (boost::system::error_code, std::size_t)))(init.handler));
|
||||
|
||||
return init.result.get();
|
||||
}
|
||||
|
||||
/// Fill the buffer with some data. Returns the number of bytes placed in the
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// buffered_read_stream_fwd.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// buffered_stream.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <boost/asio/buffered_stream_fwd.hpp>
|
||||
#include <boost/asio/detail/noncopyable.hpp>
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
@@ -53,6 +52,9 @@ public:
|
||||
/// The type of the lowest layer.
|
||||
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
||||
|
||||
/// The type of the executor associated with the object.
|
||||
typedef typename lowest_layer_type::executor_type executor_type;
|
||||
|
||||
/// Construct, passing the specified argument to initialise the next layer.
|
||||
template <typename Arg>
|
||||
explicit buffered_stream(Arg& a)
|
||||
@@ -88,10 +90,10 @@ public:
|
||||
return stream_impl_.lowest_layer();
|
||||
}
|
||||
|
||||
/// Get the io_service associated with the object.
|
||||
boost::asio::io_service& get_io_service()
|
||||
/// Get the executor associated with the object.
|
||||
executor_type get_executor() BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return stream_impl_.get_io_service();
|
||||
return stream_impl_.lowest_layer().get_executor();
|
||||
}
|
||||
|
||||
/// Close the stream.
|
||||
@@ -101,9 +103,10 @@ public:
|
||||
}
|
||||
|
||||
/// Close the stream.
|
||||
boost::system::error_code close(boost::system::error_code& ec)
|
||||
BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
|
||||
{
|
||||
return stream_impl_.close(ec);
|
||||
stream_impl_.close(ec);
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
/// Flush all data from the buffer to the next layer. Returns the number of
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// buffered_stream_fwd.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// buffered_write_stream.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <boost/asio/detail/noncopyable.hpp>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/write.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
@@ -56,6 +55,9 @@ public:
|
||||
/// The type of the lowest layer.
|
||||
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
||||
|
||||
/// The type of the executor associated with the object.
|
||||
typedef typename lowest_layer_type::executor_type executor_type;
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
/// The default buffer size.
|
||||
static const std::size_t default_buffer_size = implementation_defined;
|
||||
@@ -97,10 +99,10 @@ public:
|
||||
return next_layer_.lowest_layer();
|
||||
}
|
||||
|
||||
/// Get the io_service associated with the object.
|
||||
boost::asio::io_service& get_io_service()
|
||||
/// Get the executor associated with the object.
|
||||
executor_type get_executor() BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return next_layer_.get_io_service();
|
||||
return next_layer_.lowest_layer().get_executor();
|
||||
}
|
||||
|
||||
/// Close the stream.
|
||||
@@ -110,9 +112,10 @@ public:
|
||||
}
|
||||
|
||||
/// Close the stream.
|
||||
boost::system::error_code close(boost::system::error_code& ec)
|
||||
BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
|
||||
{
|
||||
return next_layer_.close(ec);
|
||||
next_layer_.close(ec);
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
/// Flush all data from the buffer to the next layer. Returns the number of
|
||||
@@ -175,15 +178,8 @@ public:
|
||||
async_read_some(const MutableBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
detail::async_result_init<
|
||||
ReadHandler, void (boost::system::error_code, std::size_t)> init(
|
||||
return next_layer_.async_read_some(buffers,
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
|
||||
next_layer_.async_read_some(buffers,
|
||||
BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(ReadHandler,
|
||||
void (boost::system::error_code, std::size_t)))(init.handler));
|
||||
|
||||
return init.result.get();
|
||||
}
|
||||
|
||||
/// Peek at the incoming data on the stream. Returns the number of bytes read.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// buffered_write_stream_fwd.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// buffers_iterator.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -66,7 +66,44 @@ namespace detail
|
||||
typedef buffers_iterator_types_helper<is_mutable> helper;
|
||||
typedef typename helper::buffer_type buffer_type;
|
||||
typedef typename helper::template byte_type<ByteType>::type byte_type;
|
||||
typedef typename BufferSequence::const_iterator const_iterator;
|
||||
};
|
||||
|
||||
template <typename ByteType>
|
||||
struct buffers_iterator_types<mutable_buffer, ByteType>
|
||||
{
|
||||
typedef mutable_buffer buffer_type;
|
||||
typedef ByteType byte_type;
|
||||
typedef const mutable_buffer* const_iterator;
|
||||
};
|
||||
|
||||
template <typename ByteType>
|
||||
struct buffers_iterator_types<const_buffer, ByteType>
|
||||
{
|
||||
typedef const_buffer buffer_type;
|
||||
typedef typename add_const<ByteType>::type byte_type;
|
||||
typedef const const_buffer* const_iterator;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
template <typename ByteType>
|
||||
struct buffers_iterator_types<mutable_buffers_1, ByteType>
|
||||
{
|
||||
typedef mutable_buffer buffer_type;
|
||||
typedef ByteType byte_type;
|
||||
typedef const mutable_buffer* const_iterator;
|
||||
};
|
||||
|
||||
template <typename ByteType>
|
||||
struct buffers_iterator_types<const_buffers_1, ByteType>
|
||||
{
|
||||
typedef const_buffer buffer_type;
|
||||
typedef typename add_const<ByteType>::type byte_type;
|
||||
typedef const const_buffer* const_iterator;
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
/// A random access iterator over the bytes in a buffer sequence.
|
||||
@@ -77,6 +114,9 @@ private:
|
||||
typedef typename detail::buffers_iterator_types<
|
||||
BufferSequence, ByteType>::buffer_type buffer_type;
|
||||
|
||||
typedef typename detail::buffers_iterator_types<BufferSequence,
|
||||
ByteType>::const_iterator buffer_sequence_iterator_type;
|
||||
|
||||
public:
|
||||
/// The type used for the distance between two iterators.
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
@@ -131,13 +171,13 @@ public:
|
||||
#endif // defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
|
||||
{
|
||||
buffers_iterator new_iter;
|
||||
new_iter.begin_ = buffers.begin();
|
||||
new_iter.current_ = buffers.begin();
|
||||
new_iter.end_ = buffers.end();
|
||||
new_iter.begin_ = boost::asio::buffer_sequence_begin(buffers);
|
||||
new_iter.current_ = boost::asio::buffer_sequence_begin(buffers);
|
||||
new_iter.end_ = boost::asio::buffer_sequence_end(buffers);
|
||||
while (new_iter.current_ != new_iter.end_)
|
||||
{
|
||||
new_iter.current_buffer_ = *new_iter.current_;
|
||||
if (boost::asio::buffer_size(new_iter.current_buffer_) > 0)
|
||||
if (new_iter.current_buffer_.size() > 0)
|
||||
break;
|
||||
++new_iter.current_;
|
||||
}
|
||||
@@ -151,13 +191,13 @@ public:
|
||||
#endif // defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
|
||||
{
|
||||
buffers_iterator new_iter;
|
||||
new_iter.begin_ = buffers.begin();
|
||||
new_iter.current_ = buffers.begin();
|
||||
new_iter.end_ = buffers.end();
|
||||
new_iter.begin_ = boost::asio::buffer_sequence_begin(buffers);
|
||||
new_iter.current_ = boost::asio::buffer_sequence_begin(buffers);
|
||||
new_iter.end_ = boost::asio::buffer_sequence_end(buffers);
|
||||
while (new_iter.current_ != new_iter.end_)
|
||||
{
|
||||
buffer_type buffer = *new_iter.current_;
|
||||
new_iter.position_ += boost::asio::buffer_size(buffer);
|
||||
new_iter.position_ += buffer.size();
|
||||
++new_iter.current_;
|
||||
}
|
||||
return new_iter;
|
||||
@@ -301,7 +341,8 @@ private:
|
||||
// Dereference the iterator.
|
||||
reference dereference() const
|
||||
{
|
||||
return buffer_cast<pointer>(current_buffer_)[current_buffer_position_];
|
||||
return static_cast<pointer>(
|
||||
current_buffer_.data())[current_buffer_position_];
|
||||
}
|
||||
|
||||
// Compare two iterators for equality.
|
||||
@@ -318,7 +359,7 @@ private:
|
||||
|
||||
// Check if the increment can be satisfied by the current buffer.
|
||||
++current_buffer_position_;
|
||||
if (current_buffer_position_ != boost::asio::buffer_size(current_buffer_))
|
||||
if (current_buffer_position_ != current_buffer_.size())
|
||||
return;
|
||||
|
||||
// Find the next non-empty buffer.
|
||||
@@ -327,7 +368,7 @@ private:
|
||||
while (current_ != end_)
|
||||
{
|
||||
current_buffer_ = *current_;
|
||||
if (boost::asio::buffer_size(current_buffer_) > 0)
|
||||
if (current_buffer_.size() > 0)
|
||||
return;
|
||||
++current_;
|
||||
}
|
||||
@@ -347,12 +388,12 @@ private:
|
||||
}
|
||||
|
||||
// Find the previous non-empty buffer.
|
||||
typename BufferSequence::const_iterator iter = current_;
|
||||
buffer_sequence_iterator_type iter = current_;
|
||||
while (iter != begin_)
|
||||
{
|
||||
--iter;
|
||||
buffer_type buffer = *iter;
|
||||
std::size_t buffer_size = boost::asio::buffer_size(buffer);
|
||||
std::size_t buffer_size = buffer.size();
|
||||
if (buffer_size > 0)
|
||||
{
|
||||
current_ = iter;
|
||||
@@ -372,8 +413,7 @@ private:
|
||||
for (;;)
|
||||
{
|
||||
std::ptrdiff_t current_buffer_balance
|
||||
= boost::asio::buffer_size(current_buffer_)
|
||||
- current_buffer_position_;
|
||||
= current_buffer_.size() - current_buffer_position_;
|
||||
|
||||
// Check if the advance can be satisfied by the current buffer.
|
||||
if (current_buffer_balance > n)
|
||||
@@ -427,12 +467,12 @@ private:
|
||||
}
|
||||
|
||||
// Find the previous non-empty buffer.
|
||||
typename BufferSequence::const_iterator iter = current_;
|
||||
buffer_sequence_iterator_type iter = current_;
|
||||
while (iter != begin_)
|
||||
{
|
||||
--iter;
|
||||
buffer_type buffer = *iter;
|
||||
std::size_t buffer_size = boost::asio::buffer_size(buffer);
|
||||
std::size_t buffer_size = buffer.size();
|
||||
if (buffer_size > 0)
|
||||
{
|
||||
current_ = iter;
|
||||
@@ -453,9 +493,9 @@ private:
|
||||
|
||||
buffer_type current_buffer_;
|
||||
std::size_t current_buffer_position_;
|
||||
typename BufferSequence::const_iterator begin_;
|
||||
typename BufferSequence::const_iterator current_;
|
||||
typename BufferSequence::const_iterator end_;
|
||||
buffer_sequence_iterator_type begin_;
|
||||
buffer_sequence_iterator_type current_;
|
||||
buffer_sequence_iterator_type end_;
|
||||
std::size_t position_;
|
||||
};
|
||||
|
||||
|
||||
90
winx64/include/boost/asio/co_spawn.hpp
Normal file
90
winx64/include/boost/asio/co_spawn.hpp
Normal file
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// co_spawn.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_CO_SPAWN_HPP
|
||||
#define BOOST_ASIO_CO_SPAWN_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_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
#include <boost/asio/awaitable.hpp>
|
||||
#include <boost/asio/execution_context.hpp>
|
||||
#include <boost/asio/is_executor.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct awaitable_signature;
|
||||
|
||||
template <typename T, typename Executor>
|
||||
struct awaitable_signature<awaitable<T, Executor>>
|
||||
{
|
||||
typedef void type(std::exception_ptr, T);
|
||||
};
|
||||
|
||||
template <typename Executor>
|
||||
struct awaitable_signature<awaitable<void, Executor>>
|
||||
{
|
||||
typedef void type(std::exception_ptr);
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// Spawn a new thread of execution.
|
||||
/**
|
||||
* The entry point function object @c f must have the signature:
|
||||
*
|
||||
* @code awaitable<void, E> f(); @endcode
|
||||
*
|
||||
* where @c E is convertible from @c Executor.
|
||||
*/
|
||||
template <typename Executor, typename F, typename CompletionToken>
|
||||
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* = 0);
|
||||
|
||||
/// Spawn a new thread of execution.
|
||||
/**
|
||||
* The entry point function object @c f must have the signature:
|
||||
*
|
||||
* @code awaitable<void, E> f(); @endcode
|
||||
*
|
||||
* where @c E is convertible from @c ExecutionContext::executor_type.
|
||||
*/
|
||||
template <typename ExecutionContext, typename F, typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken,
|
||||
typename detail::awaitable_signature<typename result_of<F()>::type>::type)
|
||||
co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token,
|
||||
typename enable_if<
|
||||
is_convertible<ExecutionContext&, execution_context&>::value
|
||||
>::type* = 0);
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#include <boost/asio/impl/co_spawn.hpp>
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
#endif // BOOST_ASIO_CO_SPAWN_HPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// completion_condition.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
138
winx64/include/boost/asio/compose.hpp
Normal file
138
winx64/include/boost/asio/compose.hpp
Normal file
@@ -0,0 +1,138 @@
|
||||
//
|
||||
// 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_COMPOSE_HPP
|
||||
#define BOOST_ASIO_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/async_result.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \
|
||||
|| defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Launch an asynchronous operation with a stateful implementation.
|
||||
/**
|
||||
* The async_compose function simplifies the implementation of composed
|
||||
* asynchronous operations automatically wrapping a stateful function object
|
||||
* with a conforming intermediate completion handler.
|
||||
*
|
||||
* @param implementation A function object that contains the implementation of
|
||||
* the composed asynchronous operation. The first argument to the function
|
||||
* object is a non-const reference to the enclosing intermediate completion
|
||||
* handler. The remaining arguments are any arguments that originate from the
|
||||
* completion handlers of any asynchronous operations performed by the
|
||||
* implementation.
|
||||
|
||||
* @param token The completion token.
|
||||
*
|
||||
* @param io_objects_or_executors Zero or more I/O objects or I/O executors for
|
||||
* which outstanding work must be maintained.
|
||||
*
|
||||
* @par Example:
|
||||
*
|
||||
* @code struct async_echo_implementation
|
||||
* {
|
||||
* tcp::socket& socket_;
|
||||
* boost::asio::mutable_buffer buffer_;
|
||||
* enum { starting, reading, writing } state_;
|
||||
*
|
||||
* template <typename Self>
|
||||
* void operator()(Self& self,
|
||||
* boost::system::error_code error = {},
|
||||
* std::size_t n = 0)
|
||||
* {
|
||||
* switch (state_)
|
||||
* {
|
||||
* case starting:
|
||||
* state_ = reading;
|
||||
* socket_.async_read_some(
|
||||
* buffer_, std::move(self));
|
||||
* break;
|
||||
* case reading:
|
||||
* if (error)
|
||||
* {
|
||||
* self.complete(error, 0);
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* state_ = writing;
|
||||
* boost::asio::async_write(socket_, buffer_,
|
||||
* boost::asio::transfer_exactly(n),
|
||||
* std::move(self));
|
||||
* }
|
||||
* break;
|
||||
* case writing:
|
||||
* self.complete(error, n);
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* template <typename CompletionToken>
|
||||
* auto async_echo(tcp::socket& socket,
|
||||
* boost::asio::mutable_buffer buffer,
|
||||
* CompletionToken&& token) ->
|
||||
* typename boost::asio::async_result<
|
||||
* typename std::decay<CompletionToken>::type,
|
||||
* void(boost::system::error_code, std::size_t)>::return_type
|
||||
* {
|
||||
* return boost::asio::async_compose<CompletionToken,
|
||||
* void(boost::system::error_code, std::size_t)>(
|
||||
* async_echo_implementation{socket, buffer,
|
||||
* async_echo_implementation::starting},
|
||||
* token, socket);
|
||||
* } @endcode
|
||||
*/
|
||||
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);
|
||||
|
||||
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
// || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
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);
|
||||
|
||||
#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));
|
||||
/**/
|
||||
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF)
|
||||
#undef BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
// || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#include <boost/asio/impl/compose.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_COMPOSE_HPP
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
// coroutine.hpp
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -206,7 +206,7 @@ class coroutine_ref;
|
||||
* {
|
||||
* do
|
||||
* {
|
||||
* socket_.reset(new tcp::socket(io_service_));
|
||||
* socket_.reset(new tcp::socket(my_context_));
|
||||
* yield acceptor->async_accept(*socket_, *this);
|
||||
* fork server(*this)();
|
||||
* } while (is_parent());
|
||||
@@ -228,7 +228,7 @@ class coroutine_ref;
|
||||
* Note that @c fork doesn't do the actual forking by itself. It is the
|
||||
* application's responsibility to create a clone of the coroutine and call it.
|
||||
* The clone can be called immediately, as above, or scheduled for delayed
|
||||
* execution using something like io_service::post().
|
||||
* execution using something like boost::asio::post().
|
||||
*
|
||||
* @par Alternate macro names
|
||||
*
|
||||
@@ -291,7 +291,7 @@ private:
|
||||
bail_out_of_coroutine: \
|
||||
break; \
|
||||
} \
|
||||
else case 0:
|
||||
else /* fall-through */ case 0:
|
||||
|
||||
#define BOOST_ASIO_CORO_YIELD_IMPL(n) \
|
||||
for (_coro_value = (n);;) \
|
||||
@@ -303,12 +303,12 @@ private:
|
||||
else \
|
||||
switch (_coro_value ? 0 : 1) \
|
||||
for (;;) \
|
||||
case -1: if (_coro_value) \
|
||||
/* fall-through */ case -1: if (_coro_value) \
|
||||
goto terminate_coroutine; \
|
||||
else for (;;) \
|
||||
case 1: if (_coro_value) \
|
||||
/* fall-through */ case 1: if (_coro_value) \
|
||||
goto bail_out_of_coroutine; \
|
||||
else case 0:
|
||||
else /* fall-through */ case 0:
|
||||
|
||||
#define BOOST_ASIO_CORO_FORK_IMPL(n) \
|
||||
for (_coro_value = -(n);; _coro_value = (n)) \
|
||||
|
||||
@@ -1,438 +0,0 @@
|
||||
//
|
||||
// datagram_socket_service.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 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_DATAGRAM_SOCKET_SERVICE_HPP
|
||||
#define BOOST_ASIO_DATAGRAM_SOCKET_SERVICE_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <cstddef>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
|
||||
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
||||
# include <boost/asio/detail/null_socket_service.hpp>
|
||||
#elif defined(BOOST_ASIO_HAS_IOCP)
|
||||
# include <boost/asio/detail/win_iocp_socket_service.hpp>
|
||||
#else
|
||||
# include <boost/asio/detail/reactive_socket_service.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
/// Default service implementation for a datagram socket.
|
||||
template <typename Protocol>
|
||||
class datagram_socket_service
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
: public boost::asio::io_service::service
|
||||
#else
|
||||
: public boost::asio::detail::service_base<datagram_socket_service<Protocol> >
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
/// The unique service identifier.
|
||||
static boost::asio::io_service::id id;
|
||||
#endif
|
||||
|
||||
/// The protocol type.
|
||||
typedef Protocol protocol_type;
|
||||
|
||||
/// The endpoint type.
|
||||
typedef typename Protocol::endpoint endpoint_type;
|
||||
|
||||
private:
|
||||
// The type of the platform-specific implementation.
|
||||
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
||||
typedef detail::null_socket_service<Protocol> service_impl_type;
|
||||
#elif defined(BOOST_ASIO_HAS_IOCP)
|
||||
typedef detail::win_iocp_socket_service<Protocol> service_impl_type;
|
||||
#else
|
||||
typedef detail::reactive_socket_service<Protocol> service_impl_type;
|
||||
#endif
|
||||
|
||||
public:
|
||||
/// The type of a datagram socket.
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
typedef implementation_defined implementation_type;
|
||||
#else
|
||||
typedef typename service_impl_type::implementation_type implementation_type;
|
||||
#endif
|
||||
|
||||
/// (Deprecated: Use native_handle_type.) The native socket type.
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
typedef implementation_defined native_type;
|
||||
#else
|
||||
typedef typename service_impl_type::native_handle_type native_type;
|
||||
#endif
|
||||
|
||||
/// The native socket type.
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
typedef implementation_defined native_handle_type;
|
||||
#else
|
||||
typedef typename service_impl_type::native_handle_type native_handle_type;
|
||||
#endif
|
||||
|
||||
/// Construct a new datagram socket service for the specified io_service.
|
||||
explicit datagram_socket_service(boost::asio::io_service& io_service)
|
||||
: boost::asio::detail::service_base<
|
||||
datagram_socket_service<Protocol> >(io_service),
|
||||
service_impl_(io_service)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a new datagram socket implementation.
|
||||
void construct(implementation_type& impl)
|
||||
{
|
||||
service_impl_.construct(impl);
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
/// Move-construct a new datagram socket implementation.
|
||||
void move_construct(implementation_type& impl,
|
||||
implementation_type& other_impl)
|
||||
{
|
||||
service_impl_.move_construct(impl, other_impl);
|
||||
}
|
||||
|
||||
/// Move-assign from another datagram socket implementation.
|
||||
void move_assign(implementation_type& impl,
|
||||
datagram_socket_service& other_service,
|
||||
implementation_type& other_impl)
|
||||
{
|
||||
service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
|
||||
}
|
||||
|
||||
// All socket services have access to each other's implementations.
|
||||
template <typename Protocol1> friend class datagram_socket_service;
|
||||
|
||||
/// Move-construct a new datagram socket implementation from another protocol
|
||||
/// type.
|
||||
template <typename Protocol1>
|
||||
void converting_move_construct(implementation_type& impl,
|
||||
datagram_socket_service<Protocol1>& other_service,
|
||||
typename datagram_socket_service<
|
||||
Protocol1>::implementation_type& other_impl,
|
||||
typename enable_if<is_convertible<
|
||||
Protocol1, Protocol>::value>::type* = 0)
|
||||
{
|
||||
service_impl_.template converting_move_construct<Protocol1>(
|
||||
impl, other_service.service_impl_, other_impl);
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Destroy a datagram socket implementation.
|
||||
void destroy(implementation_type& impl)
|
||||
{
|
||||
service_impl_.destroy(impl);
|
||||
}
|
||||
|
||||
// Open a new datagram socket implementation.
|
||||
boost::system::error_code open(implementation_type& impl,
|
||||
const protocol_type& protocol, boost::system::error_code& ec)
|
||||
{
|
||||
if (protocol.type() == BOOST_ASIO_OS_DEF(SOCK_DGRAM))
|
||||
service_impl_.open(impl, protocol, ec);
|
||||
else
|
||||
ec = boost::asio::error::invalid_argument;
|
||||
return ec;
|
||||
}
|
||||
|
||||
/// Assign an existing native socket to a datagram socket.
|
||||
boost::system::error_code assign(implementation_type& impl,
|
||||
const protocol_type& protocol, const native_handle_type& native_socket,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return service_impl_.assign(impl, protocol, native_socket, ec);
|
||||
}
|
||||
|
||||
/// Determine whether the socket is open.
|
||||
bool is_open(const implementation_type& impl) const
|
||||
{
|
||||
return service_impl_.is_open(impl);
|
||||
}
|
||||
|
||||
/// Close a datagram socket implementation.
|
||||
boost::system::error_code close(implementation_type& impl,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return service_impl_.close(impl, ec);
|
||||
}
|
||||
|
||||
/// (Deprecated: Use native_handle().) Get the native socket implementation.
|
||||
native_type native(implementation_type& impl)
|
||||
{
|
||||
return service_impl_.native_handle(impl);
|
||||
}
|
||||
|
||||
/// Get the native socket implementation.
|
||||
native_handle_type native_handle(implementation_type& impl)
|
||||
{
|
||||
return service_impl_.native_handle(impl);
|
||||
}
|
||||
|
||||
/// Cancel all asynchronous operations associated with the socket.
|
||||
boost::system::error_code cancel(implementation_type& impl,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return service_impl_.cancel(impl, ec);
|
||||
}
|
||||
|
||||
/// Determine whether the socket is at the out-of-band data mark.
|
||||
bool at_mark(const implementation_type& impl,
|
||||
boost::system::error_code& ec) const
|
||||
{
|
||||
return service_impl_.at_mark(impl, ec);
|
||||
}
|
||||
|
||||
/// Determine the number of bytes available for reading.
|
||||
std::size_t available(const implementation_type& impl,
|
||||
boost::system::error_code& ec) const
|
||||
{
|
||||
return service_impl_.available(impl, ec);
|
||||
}
|
||||
|
||||
// Bind the datagram socket to the specified local endpoint.
|
||||
boost::system::error_code bind(implementation_type& impl,
|
||||
const endpoint_type& endpoint, boost::system::error_code& ec)
|
||||
{
|
||||
return service_impl_.bind(impl, endpoint, ec);
|
||||
}
|
||||
|
||||
/// Connect the datagram socket to the specified endpoint.
|
||||
boost::system::error_code connect(implementation_type& impl,
|
||||
const endpoint_type& peer_endpoint, boost::system::error_code& ec)
|
||||
{
|
||||
return service_impl_.connect(impl, peer_endpoint, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous connect.
|
||||
template <typename ConnectHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler,
|
||||
void (boost::system::error_code))
|
||||
async_connect(implementation_type& impl,
|
||||
const endpoint_type& peer_endpoint,
|
||||
BOOST_ASIO_MOVE_ARG(ConnectHandler) handler)
|
||||
{
|
||||
detail::async_result_init<
|
||||
ConnectHandler, void (boost::system::error_code)> init(
|
||||
BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler));
|
||||
|
||||
service_impl_.async_connect(impl, peer_endpoint, init.handler);
|
||||
|
||||
return init.result.get();
|
||||
}
|
||||
|
||||
/// Set a socket option.
|
||||
template <typename SettableSocketOption>
|
||||
boost::system::error_code set_option(implementation_type& impl,
|
||||
const SettableSocketOption& option, boost::system::error_code& ec)
|
||||
{
|
||||
return service_impl_.set_option(impl, option, ec);
|
||||
}
|
||||
|
||||
/// Get a socket option.
|
||||
template <typename GettableSocketOption>
|
||||
boost::system::error_code get_option(const implementation_type& impl,
|
||||
GettableSocketOption& option, boost::system::error_code& ec) const
|
||||
{
|
||||
return service_impl_.get_option(impl, option, ec);
|
||||
}
|
||||
|
||||
/// Perform an IO control command on the socket.
|
||||
template <typename IoControlCommand>
|
||||
boost::system::error_code io_control(implementation_type& impl,
|
||||
IoControlCommand& command, boost::system::error_code& ec)
|
||||
{
|
||||
return service_impl_.io_control(impl, command, ec);
|
||||
}
|
||||
|
||||
/// Gets the non-blocking mode of the socket.
|
||||
bool non_blocking(const implementation_type& impl) const
|
||||
{
|
||||
return service_impl_.non_blocking(impl);
|
||||
}
|
||||
|
||||
/// Sets the non-blocking mode of the socket.
|
||||
boost::system::error_code non_blocking(implementation_type& impl,
|
||||
bool mode, boost::system::error_code& ec)
|
||||
{
|
||||
return service_impl_.non_blocking(impl, mode, ec);
|
||||
}
|
||||
|
||||
/// Gets the non-blocking mode of the native socket implementation.
|
||||
bool native_non_blocking(const implementation_type& impl) const
|
||||
{
|
||||
return service_impl_.native_non_blocking(impl);
|
||||
}
|
||||
|
||||
/// Sets the non-blocking mode of the native socket implementation.
|
||||
boost::system::error_code native_non_blocking(implementation_type& impl,
|
||||
bool mode, boost::system::error_code& ec)
|
||||
{
|
||||
return service_impl_.native_non_blocking(impl, mode, ec);
|
||||
}
|
||||
|
||||
/// Get the local endpoint.
|
||||
endpoint_type local_endpoint(const implementation_type& impl,
|
||||
boost::system::error_code& ec) const
|
||||
{
|
||||
return service_impl_.local_endpoint(impl, ec);
|
||||
}
|
||||
|
||||
/// Get the remote endpoint.
|
||||
endpoint_type remote_endpoint(const implementation_type& impl,
|
||||
boost::system::error_code& ec) const
|
||||
{
|
||||
return service_impl_.remote_endpoint(impl, ec);
|
||||
}
|
||||
|
||||
/// Disable sends or receives on the socket.
|
||||
boost::system::error_code shutdown(implementation_type& impl,
|
||||
socket_base::shutdown_type what, boost::system::error_code& ec)
|
||||
{
|
||||
return service_impl_.shutdown(impl, what, ec);
|
||||
}
|
||||
|
||||
/// Send the given data to the peer.
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t send(implementation_type& impl,
|
||||
const ConstBufferSequence& buffers,
|
||||
socket_base::message_flags flags, boost::system::error_code& ec)
|
||||
{
|
||||
return service_impl_.send(impl, buffers, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous send.
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
async_send(implementation_type& impl, const ConstBufferSequence& buffers,
|
||||
socket_base::message_flags flags,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
detail::async_result_init<
|
||||
WriteHandler, void (boost::system::error_code, std::size_t)> init(
|
||||
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
|
||||
service_impl_.async_send(impl, buffers, flags, init.handler);
|
||||
|
||||
return init.result.get();
|
||||
}
|
||||
|
||||
/// Send a datagram to the specified endpoint.
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t send_to(implementation_type& impl,
|
||||
const ConstBufferSequence& buffers, const endpoint_type& destination,
|
||||
socket_base::message_flags flags, boost::system::error_code& ec)
|
||||
{
|
||||
return service_impl_.send_to(impl, buffers, destination, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous send.
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
async_send_to(implementation_type& impl,
|
||||
const ConstBufferSequence& buffers, const endpoint_type& destination,
|
||||
socket_base::message_flags flags,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
detail::async_result_init<
|
||||
WriteHandler, void (boost::system::error_code, std::size_t)> init(
|
||||
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
|
||||
service_impl_.async_send_to(impl, buffers,
|
||||
destination, flags, init.handler);
|
||||
|
||||
return init.result.get();
|
||||
}
|
||||
|
||||
/// Receive some data from the peer.
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t receive(implementation_type& impl,
|
||||
const MutableBufferSequence& buffers,
|
||||
socket_base::message_flags flags, boost::system::error_code& ec)
|
||||
{
|
||||
return service_impl_.receive(impl, buffers, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive.
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
async_receive(implementation_type& impl,
|
||||
const MutableBufferSequence& buffers,
|
||||
socket_base::message_flags flags,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
detail::async_result_init<
|
||||
ReadHandler, void (boost::system::error_code, std::size_t)> init(
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
|
||||
service_impl_.async_receive(impl, buffers, flags, init.handler);
|
||||
|
||||
return init.result.get();
|
||||
}
|
||||
|
||||
/// Receive a datagram with the endpoint of the sender.
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t receive_from(implementation_type& impl,
|
||||
const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
|
||||
socket_base::message_flags flags, boost::system::error_code& ec)
|
||||
{
|
||||
return service_impl_.receive_from(impl, buffers, sender_endpoint, flags,
|
||||
ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive that will get the endpoint of the sender.
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
async_receive_from(implementation_type& impl,
|
||||
const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
|
||||
socket_base::message_flags flags,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
detail::async_result_init<
|
||||
ReadHandler, void (boost::system::error_code, std::size_t)> init(
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
|
||||
service_impl_.async_receive_from(impl, buffers,
|
||||
sender_endpoint, flags, init.handler);
|
||||
|
||||
return init.result.get();
|
||||
}
|
||||
|
||||
private:
|
||||
// Destroy all user-defined handler objects owned by the service.
|
||||
void shutdown_service()
|
||||
{
|
||||
service_impl_.shutdown_service();
|
||||
}
|
||||
|
||||
// The platform-specific implementation.
|
||||
service_impl_type service_impl_;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_DATAGRAM_SOCKET_SERVICE_HPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// deadline_timer.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
//
|
||||
// deadline_timer_service.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 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_DEADLINE_TIMER_SERVICE_HPP
|
||||
#define BOOST_ASIO_DEADLINE_TIMER_SERVICE_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_BOOST_DATE_TIME) \
|
||||
|| defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/detail/deadline_timer_service.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/time_traits.hpp>
|
||||
#include <boost/asio/detail/timer_queue_ptime.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
/// Default service implementation for a timer.
|
||||
template <typename TimeType,
|
||||
typename TimeTraits = boost::asio::time_traits<TimeType> >
|
||||
class deadline_timer_service
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
: public boost::asio::io_service::service
|
||||
#else
|
||||
: public boost::asio::detail::service_base<
|
||||
deadline_timer_service<TimeType, TimeTraits> >
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
/// The unique service identifier.
|
||||
static boost::asio::io_service::id id;
|
||||
#endif
|
||||
|
||||
/// The time traits type.
|
||||
typedef TimeTraits traits_type;
|
||||
|
||||
/// The time type.
|
||||
typedef typename traits_type::time_type time_type;
|
||||
|
||||
/// The duration type.
|
||||
typedef typename traits_type::duration_type duration_type;
|
||||
|
||||
private:
|
||||
// The type of the platform-specific implementation.
|
||||
typedef detail::deadline_timer_service<traits_type> service_impl_type;
|
||||
|
||||
public:
|
||||
/// The implementation type of the deadline timer.
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
typedef implementation_defined implementation_type;
|
||||
#else
|
||||
typedef typename service_impl_type::implementation_type implementation_type;
|
||||
#endif
|
||||
|
||||
/// Construct a new timer service for the specified io_service.
|
||||
explicit deadline_timer_service(boost::asio::io_service& io_service)
|
||||
: boost::asio::detail::service_base<
|
||||
deadline_timer_service<TimeType, TimeTraits> >(io_service),
|
||||
service_impl_(io_service)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a new timer implementation.
|
||||
void construct(implementation_type& impl)
|
||||
{
|
||||
service_impl_.construct(impl);
|
||||
}
|
||||
|
||||
/// Destroy a timer implementation.
|
||||
void destroy(implementation_type& impl)
|
||||
{
|
||||
service_impl_.destroy(impl);
|
||||
}
|
||||
|
||||
/// Cancel any asynchronous wait operations associated with the timer.
|
||||
std::size_t cancel(implementation_type& impl, boost::system::error_code& ec)
|
||||
{
|
||||
return service_impl_.cancel(impl, ec);
|
||||
}
|
||||
|
||||
/// Cancels one asynchronous wait operation associated with the timer.
|
||||
std::size_t cancel_one(implementation_type& impl,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return service_impl_.cancel_one(impl, ec);
|
||||
}
|
||||
|
||||
/// Get the expiry time for the timer as an absolute time.
|
||||
time_type expires_at(const implementation_type& impl) const
|
||||
{
|
||||
return service_impl_.expires_at(impl);
|
||||
}
|
||||
|
||||
/// Set the expiry time for the timer as an absolute time.
|
||||
std::size_t expires_at(implementation_type& impl,
|
||||
const time_type& expiry_time, boost::system::error_code& ec)
|
||||
{
|
||||
return service_impl_.expires_at(impl, expiry_time, ec);
|
||||
}
|
||||
|
||||
/// Get the expiry time for the timer relative to now.
|
||||
duration_type expires_from_now(const implementation_type& impl) const
|
||||
{
|
||||
return service_impl_.expires_from_now(impl);
|
||||
}
|
||||
|
||||
/// Set the expiry time for the timer relative to now.
|
||||
std::size_t expires_from_now(implementation_type& impl,
|
||||
const duration_type& expiry_time, boost::system::error_code& ec)
|
||||
{
|
||||
return service_impl_.expires_from_now(impl, expiry_time, ec);
|
||||
}
|
||||
|
||||
// Perform a blocking wait on the timer.
|
||||
void wait(implementation_type& impl, boost::system::error_code& ec)
|
||||
{
|
||||
service_impl_.wait(impl, ec);
|
||||
}
|
||||
|
||||
// Start an asynchronous wait on the timer.
|
||||
template <typename WaitHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
|
||||
void (boost::system::error_code))
|
||||
async_wait(implementation_type& impl,
|
||||
BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
|
||||
{
|
||||
detail::async_result_init<
|
||||
WaitHandler, void (boost::system::error_code)> init(
|
||||
BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
|
||||
|
||||
service_impl_.async_wait(impl, init.handler);
|
||||
|
||||
return init.result.get();
|
||||
}
|
||||
|
||||
private:
|
||||
// Destroy all user-defined handler objects owned by the service.
|
||||
void shutdown_service()
|
||||
{
|
||||
service_impl_.shutdown_service();
|
||||
}
|
||||
|
||||
// The platform-specific implementation.
|
||||
service_impl_type service_impl_;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
// || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
#endif // BOOST_ASIO_DEADLINE_TIMER_SERVICE_HPP
|
||||
119
winx64/include/boost/asio/defer.hpp
Normal file
119
winx64/include/boost/asio/defer.hpp
Normal file
@@ -0,0 +1,119 @@
|
||||
//
|
||||
// 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_DEFER_HPP
|
||||
#define BOOST_ASIO_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/async_result.hpp>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
#include <boost/asio/execution_context.hpp>
|
||||
#include <boost/asio/is_executor.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
/// Submits a completion token or function object for execution.
|
||||
/**
|
||||
* This function submits an object for execution using the object's associated
|
||||
* executor. The function object is queued for execution, and is never called
|
||||
* from the current thread prior to returning from <tt>defer()</tt>.
|
||||
*
|
||||
* The use of @c defer(), rather than @ref post(), indicates the caller's
|
||||
* preference that the executor defer the queueing of the function object. This
|
||||
* may allow the executor to optimise queueing for cases when the function
|
||||
* object represents a continuation of the current call context.
|
||||
*
|
||||
* This function has the following effects:
|
||||
*
|
||||
* @li Constructs a function object handler of type @c Handler, initialized
|
||||
* with <tt>handler(forward<CompletionToken>(token))</tt>.
|
||||
*
|
||||
* @li Constructs an object @c result of type <tt>async_result<Handler></tt>,
|
||||
* initializing the object as <tt>result(handler)</tt>.
|
||||
*
|
||||
* @li Obtains the handler's associated executor object @c ex by performing
|
||||
* <tt>get_associated_executor(handler)</tt>.
|
||||
*
|
||||
* @li Obtains the handler's associated allocator object @c alloc by performing
|
||||
* <tt>get_associated_allocator(handler)</tt>.
|
||||
*
|
||||
* @li Performs <tt>ex.defer(std::move(handler), alloc)</tt>.
|
||||
*
|
||||
* @li Returns <tt>result.get()</tt>.
|
||||
*/
|
||||
template <typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
|
||||
BOOST_ASIO_MOVE_ARG(CompletionToken) token);
|
||||
|
||||
/// Submits a completion token or function object for execution.
|
||||
/**
|
||||
* This function submits an object for execution using the specified executor.
|
||||
* The function object is queued for execution, and is never called from the
|
||||
* current thread prior to returning from <tt>defer()</tt>.
|
||||
*
|
||||
* The use of @c defer(), rather than @ref post(), indicates the caller's
|
||||
* preference that the executor defer the queueing of the function object. This
|
||||
* may allow the executor to optimise queueing for cases when the function
|
||||
* object represents a continuation of the current call context.
|
||||
*
|
||||
* This function has the following effects:
|
||||
*
|
||||
* @li Constructs a function object handler of type @c Handler, initialized
|
||||
* with <tt>handler(forward<CompletionToken>(token))</tt>.
|
||||
*
|
||||
* @li Constructs an object @c result of type <tt>async_result<Handler></tt>,
|
||||
* initializing the object as <tt>result(handler)</tt>.
|
||||
*
|
||||
* @li Obtains the handler's associated executor object @c ex1 by performing
|
||||
* <tt>get_associated_executor(handler)</tt>.
|
||||
*
|
||||
* @li Creates a work object @c w by performing <tt>make_work(ex1)</tt>.
|
||||
*
|
||||
* @li Obtains the handler's associated allocator object @c alloc by performing
|
||||
* <tt>get_associated_allocator(handler)</tt>.
|
||||
*
|
||||
* @li Constructs a function object @c f with a function call operator that
|
||||
* performs <tt>ex1.dispatch(std::move(handler), alloc)</tt> followed by
|
||||
* <tt>w.reset()</tt>.
|
||||
*
|
||||
* @li Performs <tt>Executor(ex).defer(std::move(f), alloc)</tt>.
|
||||
*
|
||||
* @li Returns <tt>result.get()</tt>.
|
||||
*/
|
||||
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* = 0);
|
||||
|
||||
/// Submits a completion token or function object for execution.
|
||||
/**
|
||||
* @returns <tt>defer(ctx.get_executor(), forward<CompletionToken>(token))</tt>.
|
||||
*/
|
||||
template <typename ExecutionContext, typename CompletionToken>
|
||||
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* = 0);
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#include <boost/asio/impl/defer.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_DEFER_HPP
|
||||
64
winx64/include/boost/asio/detached.hpp
Normal file
64
winx64/include/boost/asio/detached.hpp
Normal file
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// detached.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_DETACHED_HPP
|
||||
#define BOOST_ASIO_DETACHED_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
/// Class used to specify that an asynchronous operation is detached.
|
||||
/**
|
||||
|
||||
* The detached_t class is used to indicate that an asynchronous operation is
|
||||
* detached. That is, there is no completion handler waiting for the
|
||||
* operation's result. A detached_t object may be passed as a handler to an
|
||||
* asynchronous operation, typically using the special value
|
||||
* @c boost::asio::detached. For example:
|
||||
|
||||
* @code my_socket.async_send(my_buffer, boost::asio::detached);
|
||||
* @endcode
|
||||
*/
|
||||
class detached_t
|
||||
{
|
||||
public:
|
||||
/// Constructor.
|
||||
BOOST_ASIO_CONSTEXPR detached_t()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/// A special value, similar to std::nothrow.
|
||||
/**
|
||||
* See the documentation for boost::asio::detached_t for a usage example.
|
||||
*/
|
||||
#if defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
|
||||
constexpr detached_t detached;
|
||||
#elif defined(BOOST_ASIO_MSVC)
|
||||
__declspec(selectany) detached_t detached;
|
||||
#endif
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#include <boost/asio/impl/detached.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_DETACHED_HPP
|
||||
@@ -1,40 +0,0 @@
|
||||
//
|
||||
// detail/addressof.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 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_DETAIL_ADDRESSOF_HPP
|
||||
#define BOOST_ASIO_DETAIL_ADDRESSOF_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_STD_ADDRESSOF)
|
||||
# include <memory>
|
||||
#else // defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
|
||||
# include <boost/utility/addressof.hpp>
|
||||
#endif // defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
|
||||
using std::addressof;
|
||||
#else // defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
|
||||
using boost::addressof;
|
||||
#endif // defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_ADDRESSOF_HPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/array.hpp
|
||||
// ~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/array_fwd.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/assert.hpp
|
||||
// ~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/atomic_count.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/base_from_completion_cond.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -28,8 +28,9 @@ template <typename CompletionCondition>
|
||||
class base_from_completion_cond
|
||||
{
|
||||
protected:
|
||||
explicit base_from_completion_cond(CompletionCondition completion_condition)
|
||||
: completion_condition_(completion_condition)
|
||||
explicit base_from_completion_cond(CompletionCondition& completion_condition)
|
||||
: completion_condition_(
|
||||
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/bind_handler.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -16,9 +16,12 @@
|
||||
#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/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/push_options.hpp>
|
||||
|
||||
@@ -30,8 +33,9 @@ template <typename Handler, typename Arg1>
|
||||
class binder1
|
||||
{
|
||||
public:
|
||||
binder1(const Handler& handler, const Arg1& arg1)
|
||||
: handler_(handler),
|
||||
template <typename T>
|
||||
binder1(int, BOOST_ASIO_MOVE_ARG(T) handler, const Arg1& arg1)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
|
||||
arg1_(arg1)
|
||||
{
|
||||
}
|
||||
@@ -42,6 +46,20 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
binder1(const binder1& other)
|
||||
: handler_(other.handler_),
|
||||
arg1_(other.arg1_)
|
||||
{
|
||||
}
|
||||
|
||||
binder1(binder1&& other)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
|
||||
arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_))
|
||||
{
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
void operator()()
|
||||
{
|
||||
handler_(static_cast<const Arg1&>(arg1_));
|
||||
@@ -98,18 +116,21 @@ inline void asio_handler_invoke(const Function& function,
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1>
|
||||
inline binder1<Handler, Arg1> bind_handler(Handler handler,
|
||||
const Arg1& arg1)
|
||||
inline binder1<typename decay<Handler>::type, Arg1> bind_handler(
|
||||
BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1)
|
||||
{
|
||||
return binder1<Handler, Arg1>(handler, arg1);
|
||||
return binder1<typename decay<Handler>::type, Arg1>(0,
|
||||
BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2>
|
||||
class binder2
|
||||
{
|
||||
public:
|
||||
binder2(const Handler& handler, const Arg1& arg1, const Arg2& arg2)
|
||||
: handler_(handler),
|
||||
template <typename T>
|
||||
binder2(int, BOOST_ASIO_MOVE_ARG(T) handler,
|
||||
const Arg1& arg1, const Arg2& arg2)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
|
||||
arg1_(arg1),
|
||||
arg2_(arg2)
|
||||
{
|
||||
@@ -122,6 +143,22 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
binder2(const binder2& other)
|
||||
: handler_(other.handler_),
|
||||
arg1_(other.arg1_),
|
||||
arg2_(other.arg2_)
|
||||
{
|
||||
}
|
||||
|
||||
binder2(binder2&& other)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
|
||||
arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
|
||||
arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_))
|
||||
{
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
void operator()()
|
||||
{
|
||||
handler_(static_cast<const Arg1&>(arg1_),
|
||||
@@ -180,27 +217,29 @@ inline void asio_handler_invoke(const Function& function,
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2>
|
||||
inline binder2<Handler, Arg1, Arg2> bind_handler(Handler handler,
|
||||
const Arg1& arg1, const Arg2& arg2)
|
||||
inline binder2<typename decay<Handler>::type, Arg1, Arg2> bind_handler(
|
||||
BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2)
|
||||
{
|
||||
return binder2<Handler, Arg1, Arg2>(handler, arg1, arg2);
|
||||
return binder2<typename decay<Handler>::type, Arg1, Arg2>(0,
|
||||
BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1, arg2);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
|
||||
class binder3
|
||||
{
|
||||
public:
|
||||
binder3(const Handler& handler, const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3)
|
||||
: handler_(handler),
|
||||
template <typename T>
|
||||
binder3(int, BOOST_ASIO_MOVE_ARG(T) handler, const Arg1& arg1,
|
||||
const Arg2& arg2, const Arg3& arg3)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
|
||||
arg1_(arg1),
|
||||
arg2_(arg2),
|
||||
arg3_(arg3)
|
||||
{
|
||||
}
|
||||
|
||||
binder3(Handler& handler, const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3)
|
||||
binder3(Handler& handler, const Arg1& arg1,
|
||||
const Arg2& arg2, const Arg3& arg3)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
|
||||
arg1_(arg1),
|
||||
arg2_(arg2),
|
||||
@@ -208,11 +247,28 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
binder3(const binder3& other)
|
||||
: handler_(other.handler_),
|
||||
arg1_(other.arg1_),
|
||||
arg2_(other.arg2_),
|
||||
arg3_(other.arg3_)
|
||||
{
|
||||
}
|
||||
|
||||
binder3(binder3&& other)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
|
||||
arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
|
||||
arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_)),
|
||||
arg3_(BOOST_ASIO_MOVE_CAST(Arg3)(other.arg3_))
|
||||
{
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
void operator()()
|
||||
{
|
||||
handler_(static_cast<const Arg1&>(arg1_),
|
||||
static_cast<const Arg2&>(arg2_),
|
||||
static_cast<const Arg3&>(arg3_));
|
||||
static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_));
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
@@ -251,8 +307,8 @@ inline bool asio_handler_is_continuation(
|
||||
this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3>
|
||||
template <typename Function, typename Handler,
|
||||
typename Arg1, typename Arg2, typename Arg3>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
|
||||
{
|
||||
@@ -260,8 +316,8 @@ inline void asio_handler_invoke(Function& function,
|
||||
function, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3>
|
||||
template <typename Function, typename Handler,
|
||||
typename Arg1, typename Arg2, typename Arg3>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
|
||||
{
|
||||
@@ -270,20 +326,23 @@ inline void asio_handler_invoke(const Function& function,
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
|
||||
inline binder3<Handler, Arg1, Arg2, Arg3> bind_handler(Handler handler,
|
||||
const Arg1& arg1, const Arg2& arg2, const Arg3& arg3)
|
||||
inline binder3<typename decay<Handler>::type, Arg1, Arg2, Arg3> bind_handler(
|
||||
BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3)
|
||||
{
|
||||
return binder3<Handler, Arg1, Arg2, Arg3>(handler, arg1, arg2, arg3);
|
||||
return binder3<typename decay<Handler>::type, Arg1, Arg2, Arg3>(0,
|
||||
BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4>
|
||||
template <typename Handler, typename Arg1,
|
||||
typename Arg2, typename Arg3, typename Arg4>
|
||||
class binder4
|
||||
{
|
||||
public:
|
||||
binder4(const Handler& handler, const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3, const Arg4& arg4)
|
||||
: handler_(handler),
|
||||
template <typename T>
|
||||
binder4(int, BOOST_ASIO_MOVE_ARG(T) handler, const Arg1& arg1,
|
||||
const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
|
||||
arg1_(arg1),
|
||||
arg2_(arg2),
|
||||
arg3_(arg3),
|
||||
@@ -291,8 +350,8 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
binder4(Handler& handler, const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3, const Arg4& arg4)
|
||||
binder4(Handler& handler, const Arg1& arg1,
|
||||
const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
|
||||
arg1_(arg1),
|
||||
arg2_(arg2),
|
||||
@@ -301,11 +360,30 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
binder4(const binder4& other)
|
||||
: handler_(other.handler_),
|
||||
arg1_(other.arg1_),
|
||||
arg2_(other.arg2_),
|
||||
arg3_(other.arg3_),
|
||||
arg4_(other.arg4_)
|
||||
{
|
||||
}
|
||||
|
||||
binder4(binder4&& other)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
|
||||
arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
|
||||
arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_)),
|
||||
arg3_(BOOST_ASIO_MOVE_CAST(Arg3)(other.arg3_)),
|
||||
arg4_(BOOST_ASIO_MOVE_CAST(Arg4)(other.arg4_))
|
||||
{
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
void operator()()
|
||||
{
|
||||
handler_(static_cast<const Arg1&>(arg1_),
|
||||
static_cast<const Arg2&>(arg2_),
|
||||
static_cast<const Arg3&>(arg3_),
|
||||
static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_),
|
||||
static_cast<const Arg4&>(arg4_));
|
||||
}
|
||||
|
||||
@@ -322,8 +400,8 @@ public:
|
||||
Arg4 arg4_;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4>
|
||||
template <typename Handler, typename Arg1,
|
||||
typename Arg2, typename Arg3, typename Arg4>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
|
||||
{
|
||||
@@ -331,8 +409,8 @@ inline void* asio_handler_allocate(std::size_t size,
|
||||
size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4>
|
||||
template <typename Handler, typename Arg1,
|
||||
typename Arg2, typename Arg3, typename Arg4>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
|
||||
{
|
||||
@@ -340,8 +418,8 @@ inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
pointer, size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4>
|
||||
template <typename Handler, typename Arg1,
|
||||
typename Arg2, typename Arg3, typename Arg4>
|
||||
inline bool asio_handler_is_continuation(
|
||||
binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
|
||||
{
|
||||
@@ -349,8 +427,8 @@ inline bool asio_handler_is_continuation(
|
||||
this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3, typename Arg4>
|
||||
template <typename Function, typename Handler, typename Arg1,
|
||||
typename Arg2, typename Arg3, typename Arg4>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
|
||||
{
|
||||
@@ -358,8 +436,8 @@ inline void asio_handler_invoke(Function& function,
|
||||
function, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3, typename Arg4>
|
||||
template <typename Function, typename Handler, typename Arg1,
|
||||
typename Arg2, typename Arg3, typename Arg4>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
|
||||
{
|
||||
@@ -367,24 +445,25 @@ inline void asio_handler_invoke(const Function& function,
|
||||
function, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4>
|
||||
inline binder4<Handler, Arg1, Arg2, Arg3, Arg4> bind_handler(
|
||||
Handler handler, const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3, const Arg4& arg4)
|
||||
template <typename Handler, typename Arg1,
|
||||
typename Arg2, typename Arg3, typename Arg4>
|
||||
inline binder4<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4>
|
||||
bind_handler(BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1,
|
||||
const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
|
||||
{
|
||||
return binder4<Handler, Arg1, Arg2, Arg3, Arg4>(handler, arg1, arg2, arg3,
|
||||
arg4);
|
||||
return binder4<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4>(0,
|
||||
BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5>
|
||||
template <typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3, typename Arg4, typename Arg5>
|
||||
class binder5
|
||||
{
|
||||
public:
|
||||
binder5(const Handler& handler, const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
|
||||
: handler_(handler),
|
||||
template <typename T>
|
||||
binder5(int, BOOST_ASIO_MOVE_ARG(T) handler, const Arg1& arg1,
|
||||
const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
|
||||
arg1_(arg1),
|
||||
arg2_(arg2),
|
||||
arg3_(arg3),
|
||||
@@ -404,13 +483,33 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
binder5(const binder5& other)
|
||||
: handler_(other.handler_),
|
||||
arg1_(other.arg1_),
|
||||
arg2_(other.arg2_),
|
||||
arg3_(other.arg3_),
|
||||
arg4_(other.arg4_),
|
||||
arg5_(other.arg5_)
|
||||
{
|
||||
}
|
||||
|
||||
binder5(binder5&& other)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
|
||||
arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
|
||||
arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_)),
|
||||
arg3_(BOOST_ASIO_MOVE_CAST(Arg3)(other.arg3_)),
|
||||
arg4_(BOOST_ASIO_MOVE_CAST(Arg4)(other.arg4_)),
|
||||
arg5_(BOOST_ASIO_MOVE_CAST(Arg5)(other.arg5_))
|
||||
{
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
void operator()()
|
||||
{
|
||||
handler_(static_cast<const Arg1&>(arg1_),
|
||||
static_cast<const Arg2&>(arg2_),
|
||||
static_cast<const Arg3&>(arg3_),
|
||||
static_cast<const Arg4&>(arg4_),
|
||||
static_cast<const Arg5&>(arg5_));
|
||||
static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_),
|
||||
static_cast<const Arg4&>(arg4_), static_cast<const Arg5&>(arg5_));
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
@@ -427,8 +526,8 @@ public:
|
||||
Arg5 arg5_;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5>
|
||||
template <typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3, typename Arg4, typename Arg5>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
|
||||
{
|
||||
@@ -436,8 +535,8 @@ inline void* asio_handler_allocate(std::size_t size,
|
||||
size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5>
|
||||
template <typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3, typename Arg4, typename Arg5>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
|
||||
{
|
||||
@@ -445,8 +544,8 @@ inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
pointer, size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5>
|
||||
template <typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3, typename Arg4, typename Arg5>
|
||||
inline bool asio_handler_is_continuation(
|
||||
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
|
||||
{
|
||||
@@ -454,8 +553,8 @@ inline bool asio_handler_is_continuation(
|
||||
this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3, typename Arg4, typename Arg5>
|
||||
template <typename Function, typename Handler, typename Arg1,
|
||||
typename Arg2, typename Arg3, typename Arg4, typename Arg5>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
|
||||
{
|
||||
@@ -463,8 +562,8 @@ inline void asio_handler_invoke(Function& function,
|
||||
function, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3, typename Arg4, typename Arg5>
|
||||
template <typename Function, typename Handler, typename Arg1,
|
||||
typename Arg2, typename Arg3, typename Arg4, typename Arg5>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
|
||||
{
|
||||
@@ -472,17 +571,245 @@ inline void asio_handler_invoke(const Function& function,
|
||||
function, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5>
|
||||
inline binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5> bind_handler(
|
||||
Handler handler, const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
|
||||
template <typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3, typename Arg4, typename Arg5>
|
||||
inline binder5<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4, Arg5>
|
||||
bind_handler(BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1,
|
||||
const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
|
||||
{
|
||||
return binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>(handler, arg1, arg2,
|
||||
arg3, arg4, arg5);
|
||||
return binder5<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4, Arg5>(0,
|
||||
BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4, arg5);
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
template <typename Handler, typename Arg1>
|
||||
class move_binder1
|
||||
{
|
||||
public:
|
||||
move_binder1(int, BOOST_ASIO_MOVE_ARG(Handler) handler,
|
||||
BOOST_ASIO_MOVE_ARG(Arg1) arg1)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
|
||||
arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(arg1))
|
||||
{
|
||||
}
|
||||
|
||||
move_binder1(move_binder1&& other)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
|
||||
arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_))
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
handler_(BOOST_ASIO_MOVE_CAST(Arg1)(arg1_));
|
||||
}
|
||||
|
||||
//private:
|
||||
Handler handler_;
|
||||
Arg1 arg1_;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
move_binder1<Handler, Arg1>* this_handler)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
move_binder1<Handler, Arg1>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1>
|
||||
inline bool asio_handler_is_continuation(
|
||||
move_binder1<Handler, Arg1>* this_handler)
|
||||
{
|
||||
return boost_asio_handler_cont_helpers::is_continuation(
|
||||
this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler, typename Arg1>
|
||||
inline void asio_handler_invoke(BOOST_ASIO_MOVE_ARG(Function) function,
|
||||
move_binder1<Handler, Arg1>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
BOOST_ASIO_MOVE_CAST(Function)(function), this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2>
|
||||
class move_binder2
|
||||
{
|
||||
public:
|
||||
move_binder2(int, BOOST_ASIO_MOVE_ARG(Handler) handler,
|
||||
const Arg1& arg1, BOOST_ASIO_MOVE_ARG(Arg2) arg2)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
|
||||
arg1_(arg1),
|
||||
arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(arg2))
|
||||
{
|
||||
}
|
||||
|
||||
move_binder2(move_binder2&& other)
|
||||
: handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
|
||||
arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
|
||||
arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_))
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
handler_(static_cast<const Arg1&>(arg1_),
|
||||
BOOST_ASIO_MOVE_CAST(Arg2)(arg2_));
|
||||
}
|
||||
|
||||
//private:
|
||||
Handler handler_;
|
||||
Arg1 arg1_;
|
||||
Arg2 arg2_;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
move_binder2<Handler, Arg1, Arg2>* this_handler)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
move_binder2<Handler, Arg1, Arg2>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2>
|
||||
inline bool asio_handler_is_continuation(
|
||||
move_binder2<Handler, Arg1, Arg2>* this_handler)
|
||||
{
|
||||
return boost_asio_handler_cont_helpers::is_continuation(
|
||||
this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler, typename Arg1, typename Arg2>
|
||||
inline void asio_handler_invoke(BOOST_ASIO_MOVE_ARG(Function) function,
|
||||
move_binder2<Handler, Arg1, Arg2>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
BOOST_ASIO_MOVE_CAST(Function)(function), this_handler->handler_);
|
||||
}
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Handler, typename Arg1, typename Allocator>
|
||||
struct associated_allocator<detail::binder1<Handler, Arg1>, Allocator>
|
||||
{
|
||||
typedef typename associated_allocator<Handler, Allocator>::type type;
|
||||
|
||||
static type get(const detail::binder1<Handler, Arg1>& h,
|
||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_allocator<Handler, Allocator>::get(h.handler_, a);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Allocator>
|
||||
struct associated_allocator<detail::binder2<Handler, Arg1, Arg2>, Allocator>
|
||||
{
|
||||
typedef typename associated_allocator<Handler, Allocator>::type type;
|
||||
|
||||
static type get(const detail::binder2<Handler, Arg1, Arg2>& h,
|
||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_allocator<Handler, Allocator>::get(h.handler_, a);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1, typename Executor>
|
||||
struct associated_executor<detail::binder1<Handler, Arg1>, Executor>
|
||||
{
|
||||
typedef typename associated_executor<Handler, Executor>::type type;
|
||||
|
||||
static type get(const detail::binder1<Handler, Arg1>& h,
|
||||
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_executor<Handler, Executor>::get(h.handler_, ex);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Executor>
|
||||
struct associated_executor<detail::binder2<Handler, Arg1, Arg2>, Executor>
|
||||
{
|
||||
typedef typename associated_executor<Handler, Executor>::type type;
|
||||
|
||||
static type get(const detail::binder2<Handler, Arg1, Arg2>& h,
|
||||
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_executor<Handler, Executor>::get(h.handler_, ex);
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
template <typename Handler, typename Arg1, typename Allocator>
|
||||
struct associated_allocator<detail::move_binder1<Handler, Arg1>, Allocator>
|
||||
{
|
||||
typedef typename associated_allocator<Handler, Allocator>::type type;
|
||||
|
||||
static type get(const detail::move_binder1<Handler, Arg1>& h,
|
||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_allocator<Handler, Allocator>::get(h.handler_, a);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Allocator>
|
||||
struct associated_allocator<
|
||||
detail::move_binder2<Handler, Arg1, Arg2>, Allocator>
|
||||
{
|
||||
typedef typename associated_allocator<Handler, Allocator>::type type;
|
||||
|
||||
static type get(const detail::move_binder2<Handler, Arg1, Arg2>& h,
|
||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_allocator<Handler, Allocator>::get(h.handler_, a);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1, typename Executor>
|
||||
struct associated_executor<detail::move_binder1<Handler, Arg1>, Executor>
|
||||
{
|
||||
typedef typename associated_executor<Handler, Executor>::type type;
|
||||
|
||||
static type get(const detail::move_binder1<Handler, Arg1>& h,
|
||||
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_executor<Handler, Executor>::get(h.handler_, ex);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Executor>
|
||||
struct associated_executor<detail::move_binder2<Handler, Arg1, Arg2>, Executor>
|
||||
{
|
||||
typedef typename associated_executor<Handler, Executor>::type type;
|
||||
|
||||
static type get(const detail::move_binder2<Handler, Arg1, Arg2>& h,
|
||||
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_executor<Handler, Executor>::get(h.handler_, ex);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/buffer_resize_guard.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/buffer_sequence_adapter.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -28,11 +28,12 @@ namespace detail {
|
||||
|
||||
class buffer_sequence_adapter_base
|
||||
{
|
||||
protected:
|
||||
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
||||
public:
|
||||
// The maximum number of buffers to support in a single operation.
|
||||
enum { max_buffers = 1 };
|
||||
|
||||
protected:
|
||||
typedef Windows::Storage::Streams::IBuffer^ native_buffer_type;
|
||||
|
||||
BOOST_ASIO_DECL static void init_native_buffer(
|
||||
@@ -43,28 +44,32 @@ protected:
|
||||
native_buffer_type& buf,
|
||||
const boost::asio::const_buffer& buffer);
|
||||
#elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
||||
public:
|
||||
// The maximum number of buffers to support in a single operation.
|
||||
enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
|
||||
|
||||
protected:
|
||||
typedef WSABUF native_buffer_type;
|
||||
|
||||
static void init_native_buffer(WSABUF& buf,
|
||||
const boost::asio::mutable_buffer& buffer)
|
||||
{
|
||||
buf.buf = boost::asio::buffer_cast<char*>(buffer);
|
||||
buf.len = static_cast<ULONG>(boost::asio::buffer_size(buffer));
|
||||
buf.buf = static_cast<char*>(buffer.data());
|
||||
buf.len = static_cast<ULONG>(buffer.size());
|
||||
}
|
||||
|
||||
static void init_native_buffer(WSABUF& buf,
|
||||
const boost::asio::const_buffer& buffer)
|
||||
{
|
||||
buf.buf = const_cast<char*>(boost::asio::buffer_cast<const char*>(buffer));
|
||||
buf.len = static_cast<ULONG>(boost::asio::buffer_size(buffer));
|
||||
buf.buf = const_cast<char*>(static_cast<const char*>(buffer.data()));
|
||||
buf.len = static_cast<ULONG>(buffer.size());
|
||||
}
|
||||
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
||||
public:
|
||||
// The maximum number of buffers to support in a single operation.
|
||||
enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
|
||||
|
||||
protected:
|
||||
typedef iovec native_buffer_type;
|
||||
|
||||
static void init_iov_base(void*& base, void* addr)
|
||||
@@ -81,16 +86,15 @@ protected:
|
||||
static void init_native_buffer(iovec& iov,
|
||||
const boost::asio::mutable_buffer& buffer)
|
||||
{
|
||||
init_iov_base(iov.iov_base, boost::asio::buffer_cast<void*>(buffer));
|
||||
iov.iov_len = boost::asio::buffer_size(buffer);
|
||||
init_iov_base(iov.iov_base, buffer.data());
|
||||
iov.iov_len = buffer.size();
|
||||
}
|
||||
|
||||
static void init_native_buffer(iovec& iov,
|
||||
const boost::asio::const_buffer& buffer)
|
||||
{
|
||||
init_iov_base(iov.iov_base, const_cast<void*>(
|
||||
boost::asio::buffer_cast<const void*>(buffer)));
|
||||
iov.iov_len = boost::asio::buffer_size(buffer);
|
||||
init_iov_base(iov.iov_base, const_cast<void*>(buffer.data()));
|
||||
iov.iov_len = buffer.size();
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
||||
};
|
||||
@@ -104,14 +108,9 @@ public:
|
||||
explicit buffer_sequence_adapter(const Buffers& buffer_sequence)
|
||||
: count_(0), total_buffer_size_(0)
|
||||
{
|
||||
typename Buffers::const_iterator iter = buffer_sequence.begin();
|
||||
typename Buffers::const_iterator end = buffer_sequence.end();
|
||||
for (; iter != end && count_ < max_buffers; ++iter, ++count_)
|
||||
{
|
||||
Buffer buffer(*iter);
|
||||
init_native_buffer(buffers_[count_], buffer);
|
||||
total_buffer_size_ += boost::asio::buffer_size(buffer);
|
||||
}
|
||||
buffer_sequence_adapter::init(
|
||||
boost::asio::buffer_sequence_begin(buffer_sequence),
|
||||
boost::asio::buffer_sequence_end(buffer_sequence));
|
||||
}
|
||||
|
||||
native_buffer_type* buffers()
|
||||
@@ -124,6 +123,11 @@ public:
|
||||
return count_;
|
||||
}
|
||||
|
||||
std::size_t total_size() const
|
||||
{
|
||||
return total_buffer_size_;
|
||||
}
|
||||
|
||||
bool all_empty() const
|
||||
{
|
||||
return total_buffer_size_ == 0;
|
||||
@@ -131,55 +135,88 @@ public:
|
||||
|
||||
static bool all_empty(const Buffers& buffer_sequence)
|
||||
{
|
||||
typename Buffers::const_iterator iter = buffer_sequence.begin();
|
||||
typename Buffers::const_iterator end = buffer_sequence.end();
|
||||
std::size_t i = 0;
|
||||
for (; iter != end && i < max_buffers; ++iter, ++i)
|
||||
if (boost::asio::buffer_size(Buffer(*iter)) > 0)
|
||||
return false;
|
||||
return true;
|
||||
return buffer_sequence_adapter::all_empty(
|
||||
boost::asio::buffer_sequence_begin(buffer_sequence),
|
||||
boost::asio::buffer_sequence_end(buffer_sequence));
|
||||
}
|
||||
|
||||
static void validate(const Buffers& buffer_sequence)
|
||||
{
|
||||
typename Buffers::const_iterator iter = buffer_sequence.begin();
|
||||
typename Buffers::const_iterator end = buffer_sequence.end();
|
||||
for (; iter != end; ++iter)
|
||||
{
|
||||
Buffer buffer(*iter);
|
||||
boost::asio::buffer_cast<const void*>(buffer);
|
||||
}
|
||||
buffer_sequence_adapter::validate(
|
||||
boost::asio::buffer_sequence_begin(buffer_sequence),
|
||||
boost::asio::buffer_sequence_end(buffer_sequence));
|
||||
}
|
||||
|
||||
static Buffer first(const Buffers& buffer_sequence)
|
||||
{
|
||||
typename Buffers::const_iterator iter = buffer_sequence.begin();
|
||||
typename Buffers::const_iterator end = buffer_sequence.end();
|
||||
return buffer_sequence_adapter::first(
|
||||
boost::asio::buffer_sequence_begin(buffer_sequence),
|
||||
boost::asio::buffer_sequence_end(buffer_sequence));
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Iterator>
|
||||
void init(Iterator begin, Iterator end)
|
||||
{
|
||||
Iterator iter = begin;
|
||||
for (; iter != end && count_ < max_buffers; ++iter, ++count_)
|
||||
{
|
||||
Buffer buffer(*iter);
|
||||
init_native_buffer(buffers_[count_], buffer);
|
||||
total_buffer_size_ += buffer.size();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
static bool all_empty(Iterator begin, Iterator end)
|
||||
{
|
||||
Iterator iter = begin;
|
||||
std::size_t i = 0;
|
||||
for (; iter != end && i < max_buffers; ++iter, ++i)
|
||||
if (Buffer(*iter).size() > 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
static void validate(Iterator begin, Iterator end)
|
||||
{
|
||||
Iterator iter = begin;
|
||||
for (; iter != end; ++iter)
|
||||
{
|
||||
Buffer buffer(*iter);
|
||||
if (boost::asio::buffer_size(buffer) != 0)
|
||||
buffer.data();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
static Buffer first(Iterator begin, Iterator end)
|
||||
{
|
||||
Iterator iter = begin;
|
||||
for (; iter != end; ++iter)
|
||||
{
|
||||
Buffer buffer(*iter);
|
||||
if (buffer.size() != 0)
|
||||
return buffer;
|
||||
}
|
||||
return Buffer();
|
||||
}
|
||||
|
||||
private:
|
||||
native_buffer_type buffers_[max_buffers];
|
||||
std::size_t count_;
|
||||
std::size_t total_buffer_size_;
|
||||
};
|
||||
|
||||
template <typename Buffer>
|
||||
class buffer_sequence_adapter<Buffer, boost::asio::mutable_buffers_1>
|
||||
class buffer_sequence_adapter<Buffer, boost::asio::mutable_buffer>
|
||||
: buffer_sequence_adapter_base
|
||||
{
|
||||
public:
|
||||
explicit buffer_sequence_adapter(
|
||||
const boost::asio::mutable_buffers_1& buffer_sequence)
|
||||
const boost::asio::mutable_buffer& buffer_sequence)
|
||||
{
|
||||
init_native_buffer(buffer_, Buffer(buffer_sequence));
|
||||
total_buffer_size_ = boost::asio::buffer_size(buffer_sequence);
|
||||
total_buffer_size_ = buffer_sequence.size();
|
||||
}
|
||||
|
||||
native_buffer_type* buffers()
|
||||
@@ -192,6 +229,117 @@ public:
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::size_t total_size() const
|
||||
{
|
||||
return total_buffer_size_;
|
||||
}
|
||||
|
||||
bool all_empty() const
|
||||
{
|
||||
return total_buffer_size_ == 0;
|
||||
}
|
||||
|
||||
static bool all_empty(const boost::asio::mutable_buffer& buffer_sequence)
|
||||
{
|
||||
return buffer_sequence.size() == 0;
|
||||
}
|
||||
|
||||
static void validate(const boost::asio::mutable_buffer& buffer_sequence)
|
||||
{
|
||||
buffer_sequence.data();
|
||||
}
|
||||
|
||||
static Buffer first(const boost::asio::mutable_buffer& buffer_sequence)
|
||||
{
|
||||
return Buffer(buffer_sequence);
|
||||
}
|
||||
|
||||
private:
|
||||
native_buffer_type buffer_;
|
||||
std::size_t total_buffer_size_;
|
||||
};
|
||||
|
||||
template <typename Buffer>
|
||||
class buffer_sequence_adapter<Buffer, boost::asio::const_buffer>
|
||||
: buffer_sequence_adapter_base
|
||||
{
|
||||
public:
|
||||
explicit buffer_sequence_adapter(
|
||||
const boost::asio::const_buffer& buffer_sequence)
|
||||
{
|
||||
init_native_buffer(buffer_, Buffer(buffer_sequence));
|
||||
total_buffer_size_ = buffer_sequence.size();
|
||||
}
|
||||
|
||||
native_buffer_type* buffers()
|
||||
{
|
||||
return &buffer_;
|
||||
}
|
||||
|
||||
std::size_t count() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::size_t total_size() const
|
||||
{
|
||||
return total_buffer_size_;
|
||||
}
|
||||
|
||||
bool all_empty() const
|
||||
{
|
||||
return total_buffer_size_ == 0;
|
||||
}
|
||||
|
||||
static bool all_empty(const boost::asio::const_buffer& buffer_sequence)
|
||||
{
|
||||
return buffer_sequence.size() == 0;
|
||||
}
|
||||
|
||||
static void validate(const boost::asio::const_buffer& buffer_sequence)
|
||||
{
|
||||
buffer_sequence.data();
|
||||
}
|
||||
|
||||
static Buffer first(const boost::asio::const_buffer& buffer_sequence)
|
||||
{
|
||||
return Buffer(buffer_sequence);
|
||||
}
|
||||
|
||||
private:
|
||||
native_buffer_type buffer_;
|
||||
std::size_t total_buffer_size_;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
template <typename Buffer>
|
||||
class buffer_sequence_adapter<Buffer, boost::asio::mutable_buffers_1>
|
||||
: buffer_sequence_adapter_base
|
||||
{
|
||||
public:
|
||||
explicit buffer_sequence_adapter(
|
||||
const boost::asio::mutable_buffers_1& buffer_sequence)
|
||||
{
|
||||
init_native_buffer(buffer_, Buffer(buffer_sequence));
|
||||
total_buffer_size_ = buffer_sequence.size();
|
||||
}
|
||||
|
||||
native_buffer_type* buffers()
|
||||
{
|
||||
return &buffer_;
|
||||
}
|
||||
|
||||
std::size_t count() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::size_t total_size() const
|
||||
{
|
||||
return total_buffer_size_;
|
||||
}
|
||||
|
||||
bool all_empty() const
|
||||
{
|
||||
return total_buffer_size_ == 0;
|
||||
@@ -199,12 +347,12 @@ public:
|
||||
|
||||
static bool all_empty(const boost::asio::mutable_buffers_1& buffer_sequence)
|
||||
{
|
||||
return boost::asio::buffer_size(buffer_sequence) == 0;
|
||||
return buffer_sequence.size() == 0;
|
||||
}
|
||||
|
||||
static void validate(const boost::asio::mutable_buffers_1& buffer_sequence)
|
||||
{
|
||||
boost::asio::buffer_cast<const void*>(buffer_sequence);
|
||||
buffer_sequence.data();
|
||||
}
|
||||
|
||||
static Buffer first(const boost::asio::mutable_buffers_1& buffer_sequence)
|
||||
@@ -226,7 +374,7 @@ public:
|
||||
const boost::asio::const_buffers_1& buffer_sequence)
|
||||
{
|
||||
init_native_buffer(buffer_, Buffer(buffer_sequence));
|
||||
total_buffer_size_ = boost::asio::buffer_size(buffer_sequence);
|
||||
total_buffer_size_ = buffer_sequence.size();
|
||||
}
|
||||
|
||||
native_buffer_type* buffers()
|
||||
@@ -239,6 +387,11 @@ public:
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::size_t total_size() const
|
||||
{
|
||||
return total_buffer_size_;
|
||||
}
|
||||
|
||||
bool all_empty() const
|
||||
{
|
||||
return total_buffer_size_ == 0;
|
||||
@@ -246,12 +399,12 @@ public:
|
||||
|
||||
static bool all_empty(const boost::asio::const_buffers_1& buffer_sequence)
|
||||
{
|
||||
return boost::asio::buffer_size(buffer_sequence) == 0;
|
||||
return buffer_sequence.size() == 0;
|
||||
}
|
||||
|
||||
static void validate(const boost::asio::const_buffers_1& buffer_sequence)
|
||||
{
|
||||
boost::asio::buffer_cast<const void*>(buffer_sequence);
|
||||
buffer_sequence.data();
|
||||
}
|
||||
|
||||
static Buffer first(const boost::asio::const_buffers_1& buffer_sequence)
|
||||
@@ -264,6 +417,8 @@ private:
|
||||
std::size_t total_buffer_size_;
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
template <typename Buffer, typename Elem>
|
||||
class buffer_sequence_adapter<Buffer, boost::array<Elem, 2> >
|
||||
: buffer_sequence_adapter_base
|
||||
@@ -274,8 +429,7 @@ public:
|
||||
{
|
||||
init_native_buffer(buffers_[0], Buffer(buffer_sequence[0]));
|
||||
init_native_buffer(buffers_[1], Buffer(buffer_sequence[1]));
|
||||
total_buffer_size_ = boost::asio::buffer_size(buffer_sequence[0])
|
||||
+ boost::asio::buffer_size(buffer_sequence[1]);
|
||||
total_buffer_size_ = buffer_sequence[0].size() + buffer_sequence[1].size();
|
||||
}
|
||||
|
||||
native_buffer_type* buffers()
|
||||
@@ -288,6 +442,11 @@ public:
|
||||
return 2;
|
||||
}
|
||||
|
||||
std::size_t total_size() const
|
||||
{
|
||||
return total_buffer_size_;
|
||||
}
|
||||
|
||||
bool all_empty() const
|
||||
{
|
||||
return total_buffer_size_ == 0;
|
||||
@@ -295,19 +454,18 @@ public:
|
||||
|
||||
static bool all_empty(const boost::array<Elem, 2>& buffer_sequence)
|
||||
{
|
||||
return boost::asio::buffer_size(buffer_sequence[0]) == 0
|
||||
&& boost::asio::buffer_size(buffer_sequence[1]) == 0;
|
||||
return buffer_sequence[0].size() == 0 && buffer_sequence[1].size() == 0;
|
||||
}
|
||||
|
||||
static void validate(const boost::array<Elem, 2>& buffer_sequence)
|
||||
{
|
||||
boost::asio::buffer_cast<const void*>(buffer_sequence[0]);
|
||||
boost::asio::buffer_cast<const void*>(buffer_sequence[1]);
|
||||
buffer_sequence[0].data();
|
||||
buffer_sequence[1].data();
|
||||
}
|
||||
|
||||
static Buffer first(const boost::array<Elem, 2>& buffer_sequence)
|
||||
{
|
||||
return Buffer(boost::asio::buffer_size(buffer_sequence[0]) != 0
|
||||
return Buffer(buffer_sequence[0].size() != 0
|
||||
? buffer_sequence[0] : buffer_sequence[1]);
|
||||
}
|
||||
|
||||
@@ -328,8 +486,7 @@ public:
|
||||
{
|
||||
init_native_buffer(buffers_[0], Buffer(buffer_sequence[0]));
|
||||
init_native_buffer(buffers_[1], Buffer(buffer_sequence[1]));
|
||||
total_buffer_size_ = boost::asio::buffer_size(buffer_sequence[0])
|
||||
+ boost::asio::buffer_size(buffer_sequence[1]);
|
||||
total_buffer_size_ = buffer_sequence[0].size() + buffer_sequence[1].size();
|
||||
}
|
||||
|
||||
native_buffer_type* buffers()
|
||||
@@ -342,6 +499,11 @@ public:
|
||||
return 2;
|
||||
}
|
||||
|
||||
std::size_t total_size() const
|
||||
{
|
||||
return total_buffer_size_;
|
||||
}
|
||||
|
||||
bool all_empty() const
|
||||
{
|
||||
return total_buffer_size_ == 0;
|
||||
@@ -349,19 +511,18 @@ public:
|
||||
|
||||
static bool all_empty(const std::array<Elem, 2>& buffer_sequence)
|
||||
{
|
||||
return boost::asio::buffer_size(buffer_sequence[0]) == 0
|
||||
&& boost::asio::buffer_size(buffer_sequence[1]) == 0;
|
||||
return buffer_sequence[0].size() == 0 && buffer_sequence[1].size() == 0;
|
||||
}
|
||||
|
||||
static void validate(const std::array<Elem, 2>& buffer_sequence)
|
||||
{
|
||||
boost::asio::buffer_cast<const void*>(buffer_sequence[0]);
|
||||
boost::asio::buffer_cast<const void*>(buffer_sequence[1]);
|
||||
buffer_sequence[0].data();
|
||||
buffer_sequence[1].data();
|
||||
}
|
||||
|
||||
static Buffer first(const std::array<Elem, 2>& buffer_sequence)
|
||||
{
|
||||
return Buffer(boost::asio::buffer_size(buffer_sequence[0]) != 0
|
||||
return Buffer(buffer_sequence[0].size() != 0
|
||||
? buffer_sequence[0] : buffer_sequence[1]);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/buffered_stream_storage.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/call_stack.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -26,7 +26,7 @@ namespace asio {
|
||||
namespace detail {
|
||||
|
||||
// Helper class to determine whether or not the current thread is inside an
|
||||
// invocation of io_service::run() for a specified io_service object.
|
||||
// invocation of io_context::run() for a specified io_context object.
|
||||
template <typename Key, typename Value = unsigned char>
|
||||
class call_stack
|
||||
{
|
||||
|
||||
68
winx64/include/boost/asio/detail/chrono.hpp
Normal file
68
winx64/include/boost/asio/detail/chrono.hpp
Normal file
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// detail/chrono.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_DETAIL_CHRONO_HPP
|
||||
#define BOOST_ASIO_DETAIL_CHRONO_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_STD_CHRONO)
|
||||
# include <chrono>
|
||||
#elif defined(BOOST_ASIO_HAS_BOOST_CHRONO)
|
||||
# include <boost/chrono/system_clocks.hpp>
|
||||
#endif // defined(BOOST_ASIO_HAS_BOOST_CHRONO)
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace chrono {
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_STD_CHRONO)
|
||||
using std::chrono::duration;
|
||||
using std::chrono::time_point;
|
||||
using std::chrono::duration_cast;
|
||||
using std::chrono::nanoseconds;
|
||||
using std::chrono::microseconds;
|
||||
using std::chrono::milliseconds;
|
||||
using std::chrono::seconds;
|
||||
using std::chrono::minutes;
|
||||
using std::chrono::hours;
|
||||
using std::chrono::time_point_cast;
|
||||
#if defined(BOOST_ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK)
|
||||
typedef std::chrono::monotonic_clock steady_clock;
|
||||
#else // defined(BOOST_ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK)
|
||||
using std::chrono::steady_clock;
|
||||
#endif // defined(BOOST_ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK)
|
||||
using std::chrono::system_clock;
|
||||
using std::chrono::high_resolution_clock;
|
||||
#elif defined(BOOST_ASIO_HAS_BOOST_CHRONO)
|
||||
using boost::chrono::duration;
|
||||
using boost::chrono::time_point;
|
||||
using boost::chrono::duration_cast;
|
||||
using boost::chrono::nanoseconds;
|
||||
using boost::chrono::microseconds;
|
||||
using boost::chrono::milliseconds;
|
||||
using boost::chrono::seconds;
|
||||
using boost::chrono::minutes;
|
||||
using boost::chrono::hours;
|
||||
using boost::chrono::time_point_cast;
|
||||
using boost::chrono::system_clock;
|
||||
using boost::chrono::steady_clock;
|
||||
using boost::chrono::high_resolution_clock;
|
||||
#endif // defined(BOOST_ASIO_HAS_BOOST_CHRONO)
|
||||
|
||||
} // namespace chrono
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_CHRONO_HPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/chrono_time_traits.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/completion_handler.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -15,11 +15,11 @@
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/addressof.hpp>
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <boost/asio/detail/fenced_block.hpp>
|
||||
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_work.hpp>
|
||||
#include <boost/asio/detail/memory.hpp>
|
||||
#include <boost/asio/detail/operation.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
@@ -38,17 +38,19 @@ public:
|
||||
: operation(&completion_handler::do_complete),
|
||||
handler_(BOOST_ASIO_MOVE_CAST(Handler)(h))
|
||||
{
|
||||
handler_work<Handler>::start(handler_);
|
||||
}
|
||||
|
||||
static void do_complete(io_service_impl* owner, operation* base,
|
||||
static void do_complete(void* owner, operation* base,
|
||||
const boost::system::error_code& /*ec*/,
|
||||
std::size_t /*bytes_transferred*/)
|
||||
{
|
||||
// Take ownership of the handler object.
|
||||
completion_handler* h(static_cast<completion_handler*>(base));
|
||||
ptr p = { boost::asio::detail::addressof(h->handler_), h, h };
|
||||
handler_work<Handler> w(h->handler_);
|
||||
|
||||
BOOST_ASIO_HANDLER_COMPLETION((h));
|
||||
BOOST_ASIO_HANDLER_COMPLETION((*h));
|
||||
|
||||
// Make a copy of the handler so that the memory can be deallocated before
|
||||
// the upcall is made. Even if we're not about to make an upcall, a
|
||||
@@ -65,7 +67,7 @@ public:
|
||||
{
|
||||
fenced_block b(fenced_block::half);
|
||||
BOOST_ASIO_HANDLER_INVOCATION_BEGIN(());
|
||||
boost_asio_handler_invoke_helpers::invoke(handler, handler);
|
||||
w.complete(handler, handler);
|
||||
BOOST_ASIO_HANDLER_INVOCATION_END;
|
||||
}
|
||||
}
|
||||
|
||||
94
winx64/include/boost/asio/detail/concurrency_hint.hpp
Normal file
94
winx64/include/boost/asio/detail/concurrency_hint.hpp
Normal file
@@ -0,0 +1,94 @@
|
||||
//
|
||||
// detail/concurrency_hint.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_DETAIL_CONCURRENCY_HINT_HPP
|
||||
#define BOOST_ASIO_DETAIL_CONCURRENCY_HINT_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/noncopyable.hpp>
|
||||
|
||||
// The concurrency hint ID and mask are used to identify when a "well-known"
|
||||
// concurrency hint value has been passed to the io_context.
|
||||
#define BOOST_ASIO_CONCURRENCY_HINT_ID 0xA5100000u
|
||||
#define BOOST_ASIO_CONCURRENCY_HINT_ID_MASK 0xFFFF0000u
|
||||
|
||||
// If set, this bit indicates that the scheduler should perform locking.
|
||||
#define BOOST_ASIO_CONCURRENCY_HINT_LOCKING_SCHEDULER 0x1u
|
||||
|
||||
// If set, this bit indicates that the reactor should perform locking when
|
||||
// managing descriptor registrations.
|
||||
#define BOOST_ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_REGISTRATION 0x2u
|
||||
|
||||
// If set, this bit indicates that the reactor should perform locking for I/O.
|
||||
#define BOOST_ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_IO 0x4u
|
||||
|
||||
// Helper macro to determine if we have a special concurrency hint.
|
||||
#define BOOST_ASIO_CONCURRENCY_HINT_IS_SPECIAL(hint) \
|
||||
((static_cast<unsigned>(hint) \
|
||||
& BOOST_ASIO_CONCURRENCY_HINT_ID_MASK) \
|
||||
== BOOST_ASIO_CONCURRENCY_HINT_ID)
|
||||
|
||||
// Helper macro to determine if locking is enabled for a given facility.
|
||||
#define BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(facility, hint) \
|
||||
(((static_cast<unsigned>(hint) \
|
||||
& (BOOST_ASIO_CONCURRENCY_HINT_ID_MASK \
|
||||
| BOOST_ASIO_CONCURRENCY_HINT_LOCKING_ ## facility)) \
|
||||
^ BOOST_ASIO_CONCURRENCY_HINT_ID) != 0)
|
||||
|
||||
// This special concurrency hint disables locking in both the scheduler and
|
||||
// reactor I/O. This hint has the following restrictions:
|
||||
//
|
||||
// - Care must be taken to ensure that all operations on the io_context and any
|
||||
// of its associated I/O objects (such as sockets and timers) occur in only
|
||||
// one thread at a time.
|
||||
//
|
||||
// - Asynchronous resolve operations fail with operation_not_supported.
|
||||
//
|
||||
// - If a signal_set is used with the io_context, signal_set objects cannot be
|
||||
// used with any other io_context in the program.
|
||||
#define BOOST_ASIO_CONCURRENCY_HINT_UNSAFE \
|
||||
static_cast<int>(BOOST_ASIO_CONCURRENCY_HINT_ID)
|
||||
|
||||
// This special concurrency hint disables locking in the reactor I/O. This hint
|
||||
// has the following restrictions:
|
||||
//
|
||||
// - Care must be taken to ensure that run functions on the io_context, and all
|
||||
// operations on the io_context's associated I/O objects (such as sockets and
|
||||
// timers), occur in only one thread at a time.
|
||||
#define BOOST_ASIO_CONCURRENCY_HINT_UNSAFE_IO \
|
||||
static_cast<int>(BOOST_ASIO_CONCURRENCY_HINT_ID \
|
||||
| BOOST_ASIO_CONCURRENCY_HINT_LOCKING_SCHEDULER \
|
||||
| BOOST_ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_REGISTRATION)
|
||||
|
||||
// The special concurrency hint provides full thread safety.
|
||||
#define BOOST_ASIO_CONCURRENCY_HINT_SAFE \
|
||||
static_cast<int>(BOOST_ASIO_CONCURRENCY_HINT_ID \
|
||||
| BOOST_ASIO_CONCURRENCY_HINT_LOCKING_SCHEDULER \
|
||||
| BOOST_ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_REGISTRATION \
|
||||
| BOOST_ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_IO)
|
||||
|
||||
// This #define may be overridden at compile time to specify a program-wide
|
||||
// default concurrency hint, used by the zero-argument io_context constructor.
|
||||
#if !defined(BOOST_ASIO_CONCURRENCY_HINT_DEFAULT)
|
||||
# define BOOST_ASIO_CONCURRENCY_HINT_DEFAULT -1
|
||||
#endif // !defined(BOOST_ASIO_CONCURRENCY_HINT_DEFAULT)
|
||||
|
||||
// This #define may be overridden at compile time to specify a program-wide
|
||||
// concurrency hint, used by the one-argument io_context constructor when
|
||||
// passed a value of 1.
|
||||
#if !defined(BOOST_ASIO_CONCURRENCY_HINT_1)
|
||||
# define BOOST_ASIO_CONCURRENCY_HINT_1 1
|
||||
#endif // !defined(BOOST_ASIO_CONCURRENCY_HINT_DEFAULT)
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_CONCURRENCY_HINT_HPP
|
||||
114
winx64/include/boost/asio/detail/conditionally_enabled_event.hpp
Normal file
114
winx64/include/boost/asio/detail/conditionally_enabled_event.hpp
Normal file
@@ -0,0 +1,114 @@
|
||||
//
|
||||
// detail/conditionally_enabled_event.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_DETAIL_CONDITIONALLY_ENABLED_EVENT_HPP
|
||||
#define BOOST_ASIO_DETAIL_CONDITIONALLY_ENABLED_EVENT_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/conditionally_enabled_mutex.hpp>
|
||||
#include <boost/asio/detail/event.hpp>
|
||||
#include <boost/asio/detail/noncopyable.hpp>
|
||||
#include <boost/asio/detail/null_event.hpp>
|
||||
#include <boost/asio/detail/scoped_lock.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
// Mutex adapter used to conditionally enable or disable locking.
|
||||
class conditionally_enabled_event
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
// Constructor.
|
||||
conditionally_enabled_event()
|
||||
{
|
||||
}
|
||||
|
||||
// Destructor.
|
||||
~conditionally_enabled_event()
|
||||
{
|
||||
}
|
||||
|
||||
// Signal the event. (Retained for backward compatibility.)
|
||||
void signal(conditionally_enabled_mutex::scoped_lock& lock)
|
||||
{
|
||||
if (lock.mutex_.enabled_)
|
||||
event_.signal(lock);
|
||||
}
|
||||
|
||||
// Signal all waiters.
|
||||
void signal_all(conditionally_enabled_mutex::scoped_lock& lock)
|
||||
{
|
||||
if (lock.mutex_.enabled_)
|
||||
event_.signal_all(lock);
|
||||
}
|
||||
|
||||
// Unlock the mutex and signal one waiter.
|
||||
void unlock_and_signal_one(
|
||||
conditionally_enabled_mutex::scoped_lock& lock)
|
||||
{
|
||||
if (lock.mutex_.enabled_)
|
||||
event_.unlock_and_signal_one(lock);
|
||||
}
|
||||
|
||||
// If there's a waiter, unlock the mutex and signal it.
|
||||
bool maybe_unlock_and_signal_one(
|
||||
conditionally_enabled_mutex::scoped_lock& lock)
|
||||
{
|
||||
if (lock.mutex_.enabled_)
|
||||
return event_.maybe_unlock_and_signal_one(lock);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reset the event.
|
||||
void clear(conditionally_enabled_mutex::scoped_lock& lock)
|
||||
{
|
||||
if (lock.mutex_.enabled_)
|
||||
event_.clear(lock);
|
||||
}
|
||||
|
||||
// Wait for the event to become signalled.
|
||||
void wait(conditionally_enabled_mutex::scoped_lock& lock)
|
||||
{
|
||||
if (lock.mutex_.enabled_)
|
||||
event_.wait(lock);
|
||||
else
|
||||
null_event().wait(lock);
|
||||
}
|
||||
|
||||
// Timed wait for the event to become signalled.
|
||||
bool wait_for_usec(
|
||||
conditionally_enabled_mutex::scoped_lock& lock, long usec)
|
||||
{
|
||||
if (lock.mutex_.enabled_)
|
||||
return event_.wait_for_usec(lock, usec);
|
||||
else
|
||||
return null_event().wait_for_usec(lock, usec);
|
||||
}
|
||||
|
||||
private:
|
||||
boost::asio::detail::event event_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_CONDITIONALLY_ENABLED_EVENT_HPP
|
||||
151
winx64/include/boost/asio/detail/conditionally_enabled_mutex.hpp
Normal file
151
winx64/include/boost/asio/detail/conditionally_enabled_mutex.hpp
Normal file
@@ -0,0 +1,151 @@
|
||||
//
|
||||
// detail/conditionally_enabled_mutex.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_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP
|
||||
#define BOOST_ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_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/mutex.hpp>
|
||||
#include <boost/asio/detail/noncopyable.hpp>
|
||||
#include <boost/asio/detail/scoped_lock.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
// Mutex adapter used to conditionally enable or disable locking.
|
||||
class conditionally_enabled_mutex
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
// Helper class to lock and unlock a mutex automatically.
|
||||
class scoped_lock
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
// Tag type used to distinguish constructors.
|
||||
enum adopt_lock_t { adopt_lock };
|
||||
|
||||
// Constructor adopts a lock that is already held.
|
||||
scoped_lock(conditionally_enabled_mutex& m, adopt_lock_t)
|
||||
: mutex_(m),
|
||||
locked_(m.enabled_)
|
||||
{
|
||||
}
|
||||
|
||||
// Constructor acquires the lock.
|
||||
explicit scoped_lock(conditionally_enabled_mutex& m)
|
||||
: mutex_(m)
|
||||
{
|
||||
if (m.enabled_)
|
||||
{
|
||||
mutex_.mutex_.lock();
|
||||
locked_ = true;
|
||||
}
|
||||
else
|
||||
locked_ = false;
|
||||
}
|
||||
|
||||
// Destructor releases the lock.
|
||||
~scoped_lock()
|
||||
{
|
||||
if (locked_)
|
||||
mutex_.mutex_.unlock();
|
||||
}
|
||||
|
||||
// Explicitly acquire the lock.
|
||||
void lock()
|
||||
{
|
||||
if (mutex_.enabled_ && !locked_)
|
||||
{
|
||||
mutex_.mutex_.lock();
|
||||
locked_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Explicitly release the lock.
|
||||
void unlock()
|
||||
{
|
||||
if (locked_)
|
||||
{
|
||||
mutex_.unlock();
|
||||
locked_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Test whether the lock is held.
|
||||
bool locked() const
|
||||
{
|
||||
return locked_;
|
||||
}
|
||||
|
||||
// Get the underlying mutex.
|
||||
boost::asio::detail::mutex& mutex()
|
||||
{
|
||||
return mutex_.mutex_;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class conditionally_enabled_event;
|
||||
conditionally_enabled_mutex& mutex_;
|
||||
bool locked_;
|
||||
};
|
||||
|
||||
// Constructor.
|
||||
explicit conditionally_enabled_mutex(bool enabled)
|
||||
: enabled_(enabled)
|
||||
{
|
||||
}
|
||||
|
||||
// Destructor.
|
||||
~conditionally_enabled_mutex()
|
||||
{
|
||||
}
|
||||
|
||||
// Determine whether locking is enabled.
|
||||
bool enabled() const
|
||||
{
|
||||
return enabled_;
|
||||
}
|
||||
|
||||
// Lock the mutex.
|
||||
void lock()
|
||||
{
|
||||
if (enabled_)
|
||||
mutex_.lock();
|
||||
}
|
||||
|
||||
// Unlock the mutex.
|
||||
void unlock()
|
||||
{
|
||||
if (enabled_)
|
||||
mutex_.unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
friend class scoped_lock;
|
||||
friend class conditionally_enabled_event;
|
||||
boost::asio::detail::mutex mutex_;
|
||||
const bool enabled_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/config.hpp
|
||||
// ~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -65,10 +65,11 @@
|
||||
#if !defined(BOOST_ASIO_MSVC)
|
||||
# if defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC)
|
||||
# define BOOST_ASIO_MSVC BOOST_MSVC
|
||||
# elif defined(_MSC_VER) && !defined(__MWERKS__) && !defined(__EDG_VERSION__)
|
||||
# elif defined(_MSC_VER) && (defined(__INTELLISENSE__) \
|
||||
|| (!defined(__MWERKS__) && !defined(__EDG_VERSION__)))
|
||||
# define BOOST_ASIO_MSVC _MSC_VER
|
||||
# endif // defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC)
|
||||
#endif // defined(BOOST_ASIO_MSVC)
|
||||
#endif // !defined(BOOST_ASIO_MSVC)
|
||||
|
||||
// Clang / libc++ detection.
|
||||
#if defined(__clang__)
|
||||
@@ -82,6 +83,11 @@
|
||||
# endif // (__cplusplus >= 201103)
|
||||
#endif // defined(__clang__)
|
||||
|
||||
// Android platform detection.
|
||||
#if defined(__ANDROID__)
|
||||
# include <android/api-level.h>
|
||||
#endif // defined(__ANDROID__)
|
||||
|
||||
// Support move construction and assignment on compilers known to allow it.
|
||||
#if !defined(BOOST_ASIO_HAS_MOVE)
|
||||
# if !defined(BOOST_ASIO_DISABLE_MOVE)
|
||||
@@ -102,14 +108,26 @@
|
||||
# define BOOST_ASIO_HAS_MOVE 1
|
||||
# endif // (_MSC_VER >= 1700)
|
||||
# endif // defined(BOOST_ASIO_MSVC)
|
||||
# if defined(__INTEL_CXX11_MODE__)
|
||||
# if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500)
|
||||
# define BOOST_ASIO_HAS_MOVE 1
|
||||
# endif // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500)
|
||||
# if defined(__ICL) && (__ICL >= 1500)
|
||||
# define BOOST_ASIO_HAS_MOVE 1
|
||||
# endif // defined(__ICL) && (__ICL >= 1500)
|
||||
# endif // defined(__INTEL_CXX11_MODE__)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_MOVE)
|
||||
#endif // !defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
// If BOOST_ASIO_MOVE_CAST isn't defined, and move support is available, define
|
||||
// BOOST_ASIO_MOVE_ARG and BOOST_ASIO_MOVE_CAST to take advantage of rvalue
|
||||
// references and perfect forwarding.
|
||||
// * BOOST_ASIO_MOVE_ARG,
|
||||
// * BOOST_ASIO_NONDEDUCED_MOVE_ARG, and
|
||||
// * BOOST_ASIO_MOVE_CAST
|
||||
// to take advantage of rvalue references and perfect forwarding.
|
||||
#if defined(BOOST_ASIO_HAS_MOVE) && !defined(BOOST_ASIO_MOVE_CAST)
|
||||
# define BOOST_ASIO_MOVE_ARG(type) type&&
|
||||
# define BOOST_ASIO_MOVE_ARG2(type1, type2) type1, type2&&
|
||||
# define BOOST_ASIO_NONDEDUCED_MOVE_ARG(type) type&
|
||||
# define BOOST_ASIO_MOVE_CAST(type) static_cast<type&&>
|
||||
# define BOOST_ASIO_MOVE_CAST2(type1, type2) static_cast<type1, type2&&>
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE) && !defined(BOOST_ASIO_MOVE_CAST)
|
||||
@@ -135,6 +153,7 @@
|
||||
# else
|
||||
# define BOOST_ASIO_MOVE_ARG(type) type
|
||||
# endif
|
||||
# define BOOST_ASIO_NONDEDUCED_MOVE_ARG(type) const type&
|
||||
# define BOOST_ASIO_MOVE_CAST(type) static_cast<const type&>
|
||||
# define BOOST_ASIO_MOVE_CAST2(type1, type2) static_cast<const type1, type2&>
|
||||
#endif // !defined(BOOST_ASIO_MOVE_CAST)
|
||||
@@ -154,9 +173,38 @@
|
||||
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4)
|
||||
# endif // defined(__GNUC__)
|
||||
# if defined(BOOST_ASIO_MSVC)
|
||||
# if (_MSC_VER >= 1900)
|
||||
# define BOOST_ASIO_HAS_VARIADIC_TEMPLATES 1
|
||||
# endif // (_MSC_VER >= 1900)
|
||||
# endif // defined(BOOST_ASIO_MSVC)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_VARIADIC_TEMPLATES)
|
||||
#endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||
|
||||
// Support deleted functions on compilers known to allow it.
|
||||
#if !defined(BOOST_ASIO_DELETED)
|
||||
# if defined(__GNUC__)
|
||||
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define BOOST_ASIO_DELETED = delete
|
||||
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
|
||||
# endif // defined(__GNUC__)
|
||||
# if defined(__clang__)
|
||||
# if __has_feature(__cxx_deleted_functions__)
|
||||
# define BOOST_ASIO_DELETED = delete
|
||||
# endif // __has_feature(__cxx_deleted_functions__)
|
||||
# endif // defined(__clang__)
|
||||
# if defined(BOOST_ASIO_MSVC)
|
||||
# if (_MSC_VER >= 1900)
|
||||
# define BOOST_ASIO_DELETED = delete
|
||||
# endif // (_MSC_VER >= 1900)
|
||||
# endif // defined(BOOST_ASIO_MSVC)
|
||||
# if !defined(BOOST_ASIO_DELETED)
|
||||
# define BOOST_ASIO_DELETED
|
||||
# endif // !defined(BOOST_ASIO_DELETED)
|
||||
#endif // !defined(BOOST_ASIO_DELETED)
|
||||
|
||||
// Support constexpr on compilers known to allow it.
|
||||
#if !defined(BOOST_ASIO_HAS_CONSTEXPR)
|
||||
# if !defined(BOOST_ASIO_DISABLE_CONSTEXPR)
|
||||
@@ -172,6 +220,11 @@
|
||||
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
|
||||
# endif // defined(__GNUC__)
|
||||
# if defined(BOOST_ASIO_MSVC)
|
||||
# if (_MSC_VER >= 1900)
|
||||
# define BOOST_ASIO_HAS_CONSTEXPR 1
|
||||
# endif // (_MSC_VER >= 1900)
|
||||
# endif // defined(BOOST_ASIO_MSVC)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_CONSTEXPR)
|
||||
#endif // !defined(BOOST_ASIO_HAS_CONSTEXPR)
|
||||
#if !defined(BOOST_ASIO_CONSTEXPR)
|
||||
@@ -182,6 +235,85 @@
|
||||
# endif // defined(BOOST_ASIO_HAS_CONSTEXPR)
|
||||
#endif // !defined(BOOST_ASIO_CONSTEXPR)
|
||||
|
||||
// Support noexcept on compilers known to allow it.
|
||||
#if !defined(BOOST_ASIO_NOEXCEPT)
|
||||
# if !defined(BOOST_ASIO_DISABLE_NOEXCEPT)
|
||||
# if defined(BOOST_ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 105300)
|
||||
# define BOOST_ASIO_NOEXCEPT BOOST_NOEXCEPT
|
||||
# define BOOST_ASIO_NOEXCEPT_OR_NOTHROW BOOST_NOEXCEPT_OR_NOTHROW
|
||||
# elif defined(__clang__)
|
||||
# if __has_feature(__cxx_noexcept__)
|
||||
# define BOOST_ASIO_NOEXCEPT noexcept(true)
|
||||
# define BOOST_ASIO_NOEXCEPT_OR_NOTHROW noexcept(true)
|
||||
# endif // __has_feature(__cxx_noexcept__)
|
||||
# elif defined(__GNUC__)
|
||||
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define BOOST_ASIO_NOEXCEPT noexcept(true)
|
||||
# define BOOST_ASIO_NOEXCEPT_OR_NOTHROW noexcept(true)
|
||||
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
|
||||
# elif defined(BOOST_ASIO_MSVC)
|
||||
# if (_MSC_VER >= 1900)
|
||||
# define BOOST_ASIO_NOEXCEPT noexcept(true)
|
||||
# define BOOST_ASIO_NOEXCEPT_OR_NOTHROW noexcept(true)
|
||||
# endif // (_MSC_VER >= 1900)
|
||||
# endif // defined(BOOST_ASIO_MSVC)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_NOEXCEPT)
|
||||
# if !defined(BOOST_ASIO_NOEXCEPT)
|
||||
# define BOOST_ASIO_NOEXCEPT
|
||||
# endif // !defined(BOOST_ASIO_NOEXCEPT)
|
||||
# if !defined(BOOST_ASIO_NOEXCEPT_OR_NOTHROW)
|
||||
# define BOOST_ASIO_NOEXCEPT_OR_NOTHROW throw()
|
||||
# endif // !defined(BOOST_ASIO_NOEXCEPT_OR_NOTHROW)
|
||||
#endif // !defined(BOOST_ASIO_NOEXCEPT)
|
||||
|
||||
// Support automatic type deduction on compilers known to support it.
|
||||
#if !defined(BOOST_ASIO_HAS_DECLTYPE)
|
||||
# if !defined(BOOST_ASIO_DISABLE_DECLTYPE)
|
||||
# if defined(__clang__)
|
||||
# if __has_feature(__cxx_decltype__)
|
||||
# define BOOST_ASIO_HAS_DECLTYPE 1
|
||||
# endif // __has_feature(__cxx_decltype__)
|
||||
# endif // defined(__clang__)
|
||||
# if defined(__GNUC__)
|
||||
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define BOOST_ASIO_HAS_DECLTYPE 1
|
||||
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
|
||||
# endif // defined(__GNUC__)
|
||||
# if defined(BOOST_ASIO_MSVC)
|
||||
# if (_MSC_VER >= 1800)
|
||||
# define BOOST_ASIO_HAS_DECLTYPE 1
|
||||
# endif // (_MSC_VER >= 1800)
|
||||
# endif // defined(BOOST_ASIO_MSVC)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_DECLTYPE)
|
||||
#endif // !defined(BOOST_ASIO_HAS_DECLTYPE)
|
||||
|
||||
// Support alias templates on compilers known to allow it.
|
||||
#if !defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
|
||||
# if !defined(BOOST_ASIO_DISABLE_ALIAS_TEMPLATES)
|
||||
# if defined(__clang__)
|
||||
# if __has_feature(__cxx_alias_templates__)
|
||||
# define BOOST_ASIO_HAS_ALIAS_TEMPLATES 1
|
||||
# endif // __has_feature(__cxx_alias_templates__)
|
||||
# endif // defined(__clang__)
|
||||
# if defined(__GNUC__)
|
||||
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define BOOST_ASIO_HAS_ALIAS_TEMPLATES 1
|
||||
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
|
||||
# endif // defined(__GNUC__)
|
||||
# if defined(BOOST_ASIO_MSVC)
|
||||
# if (_MSC_VER >= 1900)
|
||||
# define BOOST_ASIO_HAS_ALIAS_TEMPLATES 1
|
||||
# endif // (_MSC_VER >= 1900)
|
||||
# endif // defined(BOOST_ASIO_MSVC)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_ALIAS_TEMPLATES)
|
||||
#endif // !defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
|
||||
|
||||
// Standard library support for system errors.
|
||||
# if !defined(BOOST_ASIO_DISABLE_STD_SYSTEM_ERROR)
|
||||
# if defined(__clang__)
|
||||
@@ -283,6 +415,31 @@
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_STD_SHARED_PTR)
|
||||
#endif // !defined(BOOST_ASIO_HAS_STD_SHARED_PTR)
|
||||
|
||||
// Standard library support for allocator_arg_t.
|
||||
#if !defined(BOOST_ASIO_HAS_STD_ALLOCATOR_ARG)
|
||||
# if !defined(BOOST_ASIO_DISABLE_STD_ALLOCATOR_ARG)
|
||||
# if defined(__clang__)
|
||||
# if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
|
||||
# define BOOST_ASIO_HAS_STD_ALLOCATOR_ARG 1
|
||||
# elif (__cplusplus >= 201103)
|
||||
# define BOOST_ASIO_HAS_STD_ALLOCATOR_ARG 1
|
||||
# endif // (__cplusplus >= 201103)
|
||||
# endif // defined(__clang__)
|
||||
# if defined(__GNUC__)
|
||||
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define BOOST_ASIO_HAS_STD_ALLOCATOR_ARG 1
|
||||
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
|
||||
# endif // defined(__GNUC__)
|
||||
# if defined(BOOST_ASIO_MSVC)
|
||||
# if (_MSC_VER >= 1600)
|
||||
# define BOOST_ASIO_HAS_STD_ALLOCATOR_ARG 1
|
||||
# endif // (_MSC_VER >= 1600)
|
||||
# endif // defined(BOOST_ASIO_MSVC)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_STD_ALLOCATOR_ARG)
|
||||
#endif // !defined(BOOST_ASIO_HAS_STD_ALLOCATOR_ARG)
|
||||
|
||||
// Standard library support for atomic operations.
|
||||
#if !defined(BOOST_ASIO_HAS_STD_ATOMIC)
|
||||
# if !defined(BOOST_ASIO_DISABLE_STD_ATOMIC)
|
||||
@@ -293,14 +450,20 @@
|
||||
# if __has_include(<atomic>)
|
||||
# define BOOST_ASIO_HAS_STD_ATOMIC 1
|
||||
# endif // __has_include(<atomic>)
|
||||
# endif // (__cplusplus >= 201103)
|
||||
# elif defined(__apple_build_version__) && defined(_LIBCPP_VERSION)
|
||||
# if (__clang_major__ >= 10)
|
||||
# if __has_include(<atomic>)
|
||||
# define BOOST_ASIO_HAS_STD_ATOMIC 1
|
||||
# endif // __has_include(<atomic>)
|
||||
# endif // (__clang_major__ >= 10)
|
||||
# endif /// defined(__apple_build_version__) && defined(_LIBCPP_VERSION)
|
||||
# endif // defined(__clang__)
|
||||
# if defined(__GNUC__)
|
||||
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
|
||||
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define BOOST_ASIO_HAS_STD_ATOMIC 1
|
||||
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
|
||||
# endif // defined(__GNUC__)
|
||||
# if defined(BOOST_ASIO_MSVC)
|
||||
# if (_MSC_VER >= 1700)
|
||||
@@ -351,6 +514,15 @@
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_BOOST_CHRONO)
|
||||
#endif // !defined(BOOST_ASIO_HAS_BOOST_CHRONO)
|
||||
|
||||
// Some form of chrono library is available.
|
||||
#if !defined(BOOST_ASIO_HAS_CHRONO)
|
||||
# if defined(BOOST_ASIO_HAS_STD_CHRONO) \
|
||||
|| defined(BOOST_ASIO_HAS_BOOST_CHRONO)
|
||||
# define BOOST_ASIO_HAS_CHRONO 1
|
||||
# endif // defined(BOOST_ASIO_HAS_STD_CHRONO)
|
||||
// || defined(BOOST_ASIO_HAS_BOOST_CHRONO)
|
||||
#endif // !defined(BOOST_ASIO_HAS_CHRONO)
|
||||
|
||||
// Boost support for the DateTime library.
|
||||
#if !defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
# if !defined(BOOST_ASIO_DISABLE_BOOST_DATE_TIME)
|
||||
@@ -435,6 +607,28 @@
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_STD_TYPE_TRAITS)
|
||||
#endif // !defined(BOOST_ASIO_HAS_STD_TYPE_TRAITS)
|
||||
|
||||
// Standard library support for the nullptr_t type.
|
||||
#if !defined(BOOST_ASIO_HAS_NULLPTR)
|
||||
# if !defined(BOOST_ASIO_DISABLE_NULLPTR)
|
||||
# if defined(__clang__)
|
||||
# if __has_feature(__cxx_nullptr__)
|
||||
# define BOOST_ASIO_HAS_NULLPTR 1
|
||||
# endif // __has_feature(__cxx_rvalue_references__)
|
||||
# elif defined(__GNUC__)
|
||||
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define BOOST_ASIO_HAS_NULLPTR 1
|
||||
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
|
||||
# endif // defined(__GNUC__)
|
||||
# if defined(BOOST_ASIO_MSVC)
|
||||
# if (_MSC_VER >= 1700)
|
||||
# define BOOST_ASIO_HAS_NULLPTR 1
|
||||
# endif // (_MSC_VER >= 1700)
|
||||
# endif // defined(BOOST_ASIO_MSVC)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_NULLPTR)
|
||||
#endif // !defined(BOOST_ASIO_HAS_NULLPTR)
|
||||
|
||||
// Standard library support for the C++11 allocator additions.
|
||||
#if !defined(BOOST_ASIO_HAS_CXX11_ALLOCATORS)
|
||||
# if !defined(BOOST_ASIO_DISABLE_CXX11_ALLOCATORS)
|
||||
@@ -445,16 +639,16 @@
|
||||
# define BOOST_ASIO_HAS_CXX11_ALLOCATORS 1
|
||||
# endif // (__cplusplus >= 201103)
|
||||
# elif defined(__GNUC__)
|
||||
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
|
||||
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define BOOST_ASIO_HAS_CXX11_ALLOCATORS 1
|
||||
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
|
||||
# endif // defined(__GNUC__)
|
||||
# if defined(BOOST_ASIO_MSVC)
|
||||
# if (_MSC_VER >= 1700)
|
||||
# if (_MSC_VER >= 1800)
|
||||
# define BOOST_ASIO_HAS_CXX11_ALLOCATORS 1
|
||||
# endif // (_MSC_VER >= 1700)
|
||||
# endif // (_MSC_VER >= 1800)
|
||||
# endif // defined(BOOST_ASIO_MSVC)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_CXX11_ALLOCATORS)
|
||||
#endif // !defined(BOOST_ASIO_HAS_CXX11_ALLOCATORS)
|
||||
@@ -538,6 +732,161 @@
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_STD_MUTEX_AND_CONDVAR)
|
||||
#endif // !defined(BOOST_ASIO_HAS_STD_MUTEX_AND_CONDVAR)
|
||||
|
||||
// Standard library support for the call_once function.
|
||||
#if !defined(BOOST_ASIO_HAS_STD_CALL_ONCE)
|
||||
# if !defined(BOOST_ASIO_DISABLE_STD_CALL_ONCE)
|
||||
# if defined(__clang__)
|
||||
# if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
|
||||
# define BOOST_ASIO_HAS_STD_CALL_ONCE 1
|
||||
# elif (__cplusplus >= 201103)
|
||||
# if __has_include(<mutex>)
|
||||
# define BOOST_ASIO_HAS_STD_CALL_ONCE 1
|
||||
# endif // __has_include(<mutex>)
|
||||
# endif // (__cplusplus >= 201103)
|
||||
# endif // defined(__clang__)
|
||||
# if defined(__GNUC__)
|
||||
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define BOOST_ASIO_HAS_STD_CALL_ONCE 1
|
||||
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
|
||||
# endif // defined(__GNUC__)
|
||||
# if defined(BOOST_ASIO_MSVC)
|
||||
# if (_MSC_VER >= 1700)
|
||||
# define BOOST_ASIO_HAS_STD_CALL_ONCE 1
|
||||
# endif // (_MSC_VER >= 1700)
|
||||
# endif // defined(BOOST_ASIO_MSVC)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_STD_CALL_ONCE)
|
||||
#endif // !defined(BOOST_ASIO_HAS_STD_CALL_ONCE)
|
||||
|
||||
// Standard library support for futures.
|
||||
#if !defined(BOOST_ASIO_HAS_STD_FUTURE)
|
||||
# if !defined(BOOST_ASIO_DISABLE_STD_FUTURE)
|
||||
# if defined(__clang__)
|
||||
# if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
|
||||
# define BOOST_ASIO_HAS_STD_FUTURE 1
|
||||
# elif (__cplusplus >= 201103)
|
||||
# if __has_include(<future>)
|
||||
# define BOOST_ASIO_HAS_STD_FUTURE 1
|
||||
# endif // __has_include(<mutex>)
|
||||
# endif // (__cplusplus >= 201103)
|
||||
# endif // defined(__clang__)
|
||||
# if defined(__GNUC__)
|
||||
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define BOOST_ASIO_HAS_STD_FUTURE 1
|
||||
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
|
||||
# endif // defined(__GNUC__)
|
||||
# if defined(BOOST_ASIO_MSVC)
|
||||
# if (_MSC_VER >= 1700)
|
||||
# define BOOST_ASIO_HAS_STD_FUTURE 1
|
||||
# endif // (_MSC_VER >= 1700)
|
||||
# endif // defined(BOOST_ASIO_MSVC)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_STD_FUTURE)
|
||||
#endif // !defined(BOOST_ASIO_HAS_STD_FUTURE)
|
||||
|
||||
// Standard library support for std::string_view.
|
||||
#if !defined(BOOST_ASIO_HAS_STD_STRING_VIEW)
|
||||
# if !defined(BOOST_ASIO_DISABLE_STD_STRING_VIEW)
|
||||
# if defined(__clang__)
|
||||
# if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
|
||||
# if (__cplusplus >= 201402)
|
||||
# if __has_include(<string_view>)
|
||||
# define BOOST_ASIO_HAS_STD_STRING_VIEW 1
|
||||
# endif // __has_include(<string_view>)
|
||||
# endif // (__cplusplus >= 201402)
|
||||
# else // defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
|
||||
# if (__cplusplus >= 201703)
|
||||
# if __has_include(<string_view>)
|
||||
# define BOOST_ASIO_HAS_STD_STRING_VIEW 1
|
||||
# endif // __has_include(<string_view>)
|
||||
# endif // (__cplusplus >= 201703)
|
||||
# endif // defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
|
||||
# elif defined(__GNUC__)
|
||||
# if (__GNUC__ >= 7)
|
||||
# if (__cplusplus >= 201703)
|
||||
# define BOOST_ASIO_HAS_STD_STRING_VIEW 1
|
||||
# endif // (__cplusplus >= 201703)
|
||||
# endif // (__GNUC__ >= 7)
|
||||
# elif defined(BOOST_ASIO_MSVC)
|
||||
# if (_MSC_VER >= 1910 && _MSVC_LANG >= 201703)
|
||||
# define BOOST_ASIO_HAS_STD_STRING_VIEW 1
|
||||
# endif // (_MSC_VER >= 1910 && _MSVC_LANG >= 201703)
|
||||
# endif // defined(BOOST_ASIO_MSVC)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_STD_STRING_VIEW)
|
||||
#endif // !defined(BOOST_ASIO_HAS_STD_STRING_VIEW)
|
||||
|
||||
// Standard library support for std::experimental::string_view.
|
||||
#if !defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
|
||||
# if !defined(BOOST_ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW)
|
||||
# if defined(__clang__)
|
||||
# if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
|
||||
# if (_LIBCPP_VERSION < 7000)
|
||||
# if (__cplusplus >= 201402)
|
||||
# if __has_include(<experimental/string_view>)
|
||||
# define BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
|
||||
# endif // __has_include(<experimental/string_view>)
|
||||
# endif // (__cplusplus >= 201402)
|
||||
# endif // (_LIBCPP_VERSION < 7000)
|
||||
# else // defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
|
||||
# if (__cplusplus >= 201402)
|
||||
# if __has_include(<experimental/string_view>)
|
||||
# define BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
|
||||
# endif // __has_include(<experimental/string_view>)
|
||||
# endif // (__cplusplus >= 201402)
|
||||
# endif // // defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
|
||||
# endif // defined(__clang__)
|
||||
# if defined(__GNUC__)
|
||||
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)
|
||||
# if (__cplusplus >= 201402)
|
||||
# define BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
|
||||
# endif // (__cplusplus >= 201402)
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)
|
||||
# endif // defined(__GNUC__)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW)
|
||||
#endif // !defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
|
||||
|
||||
// Standard library has a string_view that we can use.
|
||||
#if !defined(BOOST_ASIO_HAS_STRING_VIEW)
|
||||
# if !defined(BOOST_ASIO_DISABLE_STRING_VIEW)
|
||||
# if defined(BOOST_ASIO_HAS_STD_STRING_VIEW)
|
||||
# define BOOST_ASIO_HAS_STRING_VIEW 1
|
||||
# elif defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
|
||||
# define BOOST_ASIO_HAS_STRING_VIEW 1
|
||||
# endif // defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_STRING_VIEW)
|
||||
#endif // !defined(BOOST_ASIO_HAS_STRING_VIEW)
|
||||
|
||||
// Standard library support for iostream move construction and assignment.
|
||||
#if !defined(BOOST_ASIO_HAS_STD_IOSTREAM_MOVE)
|
||||
# if !defined(BOOST_ASIO_DISABLE_STD_IOSTREAM_MOVE)
|
||||
# if defined(__GNUC__)
|
||||
# if (__GNUC__ > 4)
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define BOOST_ASIO_HAS_STD_IOSTREAM_MOVE 1
|
||||
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# endif // (__GNUC__ > 4)
|
||||
# endif // defined(__GNUC__)
|
||||
# if defined(BOOST_ASIO_MSVC)
|
||||
# if (_MSC_VER >= 1700)
|
||||
# define BOOST_ASIO_HAS_STD_IOSTREAM_MOVE 1
|
||||
# endif // (_MSC_VER >= 1700)
|
||||
# endif // defined(BOOST_ASIO_MSVC)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_STD_IOSTREAM_MOVE)
|
||||
#endif // !defined(BOOST_ASIO_HAS_STD_IOSTREAM_MOVE)
|
||||
|
||||
// Standard library has invoke_result (which supersedes result_of).
|
||||
#if !defined(BOOST_ASIO_HAS_STD_INVOKE_RESULT)
|
||||
# if !defined(BOOST_ASIO_DISABLE_STD_INVOKE_RESULT)
|
||||
# if defined(BOOST_ASIO_MSVC)
|
||||
# if (_MSC_VER >= 1911 && _MSVC_LANG >= 201703)
|
||||
# define BOOST_ASIO_HAS_STD_INVOKE_RESULT 1
|
||||
# endif // (_MSC_VER >= 1911 && _MSVC_LANG >= 201703)
|
||||
# endif // defined(BOOST_ASIO_MSVC)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_STD_INVOKE_RESULT)
|
||||
#endif // !defined(BOOST_ASIO_HAS_STD_INVOKE_RESULT)
|
||||
|
||||
// Windows App target. Windows but with a limited API.
|
||||
#if !defined(BOOST_ASIO_WINDOWS_APP)
|
||||
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0603)
|
||||
@@ -583,15 +932,15 @@
|
||||
# if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
# pragma message( \
|
||||
"Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n"\
|
||||
"- add -D_WIN32_WINNT=0x0501 to the compiler command line; or\n"\
|
||||
"- add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.\n"\
|
||||
"Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).")
|
||||
"- add -D_WIN32_WINNT=0x0601 to the compiler command line; or\n"\
|
||||
"- add _WIN32_WINNT=0x0601 to your project's Preprocessor Definitions.\n"\
|
||||
"Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target).")
|
||||
# else // defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
# warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately.
|
||||
# warning For example, add -D_WIN32_WINNT=0x0501 to the compiler command line.
|
||||
# warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).
|
||||
# warning For example, add -D_WIN32_WINNT=0x0601 to the compiler command line.
|
||||
# warning Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target).
|
||||
# endif // defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
# define _WIN32_WINNT 0x0501
|
||||
# define _WIN32_WINNT 0x0601
|
||||
# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)
|
||||
# if defined(_MSC_VER)
|
||||
# if defined(_WIN32) && !defined(WIN32)
|
||||
@@ -662,7 +1011,8 @@
|
||||
|| defined(__FreeBSD__) \
|
||||
|| defined(__NetBSD__) \
|
||||
|| defined(__OpenBSD__) \
|
||||
|| defined(__linux__)
|
||||
|| defined(__linux__) \
|
||||
|| defined(__HAIKU__)
|
||||
# define BOOST_ASIO_HAS_UNISTD_H 1
|
||||
# endif
|
||||
# endif // !defined(BOOST_ASIO_HAS_BOOST_CONFIG)
|
||||
@@ -873,11 +1223,18 @@
|
||||
# if !defined(BOOST_ASIO_DISABLE_THREADS)
|
||||
# if defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_THREADS)
|
||||
# define BOOST_ASIO_HAS_THREADS 1
|
||||
# elif defined(_MSC_VER) && defined(_MT)
|
||||
# elif defined(__GNUC__) && !defined(__MINGW32__) \
|
||||
&& !defined(linux) && !defined(__linux) && !defined(__linux__)
|
||||
# define BOOST_ASIO_HAS_THREADS 1
|
||||
# elif defined(__BORLANDC__) && defined(__MT__)
|
||||
# elif defined(_MT) || defined(__MT__)
|
||||
# define BOOST_ASIO_HAS_THREADS 1
|
||||
# elif defined(_POSIX_THREADS)
|
||||
# elif defined(_REENTRANT)
|
||||
# define BOOST_ASIO_HAS_THREADS 1
|
||||
# elif defined(__APPLE__)
|
||||
# define BOOST_ASIO_HAS_THREADS 1
|
||||
# elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0)
|
||||
# define BOOST_ASIO_HAS_THREADS 1
|
||||
# elif defined(_PTHREADS)
|
||||
# define BOOST_ASIO_HAS_THREADS 1
|
||||
# endif // defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_THREADS)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_THREADS)
|
||||
@@ -888,7 +1245,7 @@
|
||||
# if defined(BOOST_ASIO_HAS_THREADS)
|
||||
# if defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS)
|
||||
# define BOOST_ASIO_HAS_PTHREADS 1
|
||||
# elif defined(_POSIX_THREADS)
|
||||
# elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0)
|
||||
# define BOOST_ASIO_HAS_PTHREADS 1
|
||||
# endif // defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS)
|
||||
# endif // defined(BOOST_ASIO_HAS_THREADS)
|
||||
@@ -988,12 +1345,14 @@
|
||||
# if defined(__linux__)
|
||||
# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
# if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)
|
||||
# if !defined(__INTEL_COMPILER) && !defined(__ICL)
|
||||
# if !defined(__INTEL_COMPILER) && !defined(__ICL) \
|
||||
&& !(defined(__clang__) && defined(__ANDROID__))
|
||||
# define BOOST_ASIO_HAS_THREAD_KEYWORD_EXTENSION 1
|
||||
# define BOOST_ASIO_THREAD_KEYWORD __thread
|
||||
# elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100)
|
||||
# define BOOST_ASIO_HAS_THREAD_KEYWORD_EXTENSION 1
|
||||
# endif // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100)
|
||||
// && !(defined(__clang__) && defined(__ANDROID__))
|
||||
# endif // ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)
|
||||
# endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
# endif // defined(__linux__)
|
||||
@@ -1017,6 +1376,15 @@
|
||||
// || (defined(__MACH__) && defined(__APPLE__))
|
||||
#endif // !defined(BOOST_ASIO_DISABLE_SSIZE_T)
|
||||
|
||||
// Helper macros to manage transition away from error_code return values.
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
# define BOOST_ASIO_SYNC_OP_VOID void
|
||||
# define BOOST_ASIO_SYNC_OP_VOID_RETURN(e) return
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
# define BOOST_ASIO_SYNC_OP_VOID boost::system::error_code
|
||||
# define BOOST_ASIO_SYNC_OP_VOID_RETURN(e) return e
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
// Newer gcc, clang need special treatment to suppress unused typedef warnings.
|
||||
#if defined(__clang__)
|
||||
# if defined(__apple_build_version__)
|
||||
@@ -1047,4 +1415,24 @@
|
||||
# define BOOST_ASIO_UNUSED_VARIABLE
|
||||
#endif // !defined(BOOST_ASIO_UNUSED_VARIABLE)
|
||||
|
||||
// Support co_await on compilers known to allow it.
|
||||
#if !defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||
# if !defined(BOOST_ASIO_DISABLE_CO_AWAIT)
|
||||
# if defined(BOOST_ASIO_MSVC)
|
||||
# if (_MSC_FULL_VER >= 190023506)
|
||||
# if defined(_RESUMABLE_FUNCTIONS_SUPPORTED)
|
||||
# define BOOST_ASIO_HAS_CO_AWAIT 1
|
||||
# endif // defined(_RESUMABLE_FUNCTIONS_SUPPORTED)
|
||||
# endif // (_MSC_FULL_VER >= 190023506)
|
||||
# endif // defined(BOOST_ASIO_MSVC)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_CO_AWAIT)
|
||||
# if defined(__clang__)
|
||||
# if (__cpp_coroutines >= 201703)
|
||||
# if __has_include(<experimental/coroutine>)
|
||||
# define BOOST_ASIO_HAS_CO_AWAIT 1
|
||||
# endif // __has_include(<experimental/coroutine>)
|
||||
# endif // (__cpp_coroutines >= 201703)
|
||||
# endif // defined(__clang__)
|
||||
#endif // !defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_CONFIG_HPP
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/consuming_buffers.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/detail/buffer_sequence_adapter.hpp>
|
||||
#include <boost/asio/detail/limits.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
@@ -27,262 +27,384 @@ namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
// A proxy iterator for a sub-range in a list of buffers.
|
||||
template <typename Buffer, typename Buffer_Iterator>
|
||||
class consuming_buffers_iterator
|
||||
// Helper template to determine the maximum number of prepared buffers.
|
||||
template <typename Buffers>
|
||||
struct prepared_buffers_max
|
||||
{
|
||||
public:
|
||||
/// The type used for the distance between two iterators.
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
enum { value = buffer_sequence_adapter_base::max_buffers };
|
||||
};
|
||||
|
||||
/// The type of the value pointed to by the iterator.
|
||||
template <typename Elem, std::size_t N>
|
||||
struct prepared_buffers_max<boost::array<Elem, N> >
|
||||
{
|
||||
enum { value = N };
|
||||
};
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_STD_ARRAY)
|
||||
|
||||
template <typename Elem, std::size_t N>
|
||||
struct prepared_buffers_max<std::array<Elem, N> >
|
||||
{
|
||||
enum { value = N };
|
||||
};
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
|
||||
|
||||
// A buffer sequence used to represent a subsequence of the buffers.
|
||||
template <typename Buffer, std::size_t MaxBuffers>
|
||||
struct prepared_buffers
|
||||
{
|
||||
typedef Buffer value_type;
|
||||
typedef const Buffer* const_iterator;
|
||||
|
||||
/// The type of the result of applying operator->() to the iterator.
|
||||
typedef const Buffer* pointer;
|
||||
enum { max_buffers = MaxBuffers < 16 ? MaxBuffers : 16 };
|
||||
|
||||
/// The type of the result of applying operator*() to the iterator.
|
||||
typedef const Buffer& reference;
|
||||
prepared_buffers() : count(0) {}
|
||||
const_iterator begin() const { return elems; }
|
||||
const_iterator end() const { return elems + count; }
|
||||
|
||||
/// The iterator category.
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
|
||||
// Default constructor creates an end iterator.
|
||||
consuming_buffers_iterator()
|
||||
: at_end_(true)
|
||||
{
|
||||
}
|
||||
|
||||
// Construct with a buffer for the first entry and an iterator
|
||||
// range for the remaining entries.
|
||||
consuming_buffers_iterator(bool at_end, const Buffer& first,
|
||||
Buffer_Iterator begin_remainder, Buffer_Iterator end_remainder,
|
||||
std::size_t max_size)
|
||||
: at_end_(max_size > 0 ? at_end : true),
|
||||
first_(buffer(first, max_size)),
|
||||
begin_remainder_(begin_remainder),
|
||||
end_remainder_(end_remainder),
|
||||
offset_(0),
|
||||
max_size_(max_size)
|
||||
{
|
||||
}
|
||||
|
||||
// Dereference an iterator.
|
||||
const Buffer& operator*() const
|
||||
{
|
||||
return dereference();
|
||||
}
|
||||
|
||||
// Dereference an iterator.
|
||||
const Buffer* operator->() const
|
||||
{
|
||||
return &dereference();
|
||||
}
|
||||
|
||||
// Increment operator (prefix).
|
||||
consuming_buffers_iterator& operator++()
|
||||
{
|
||||
increment();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Increment operator (postfix).
|
||||
consuming_buffers_iterator operator++(int)
|
||||
{
|
||||
consuming_buffers_iterator tmp(*this);
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Test two iterators for equality.
|
||||
friend bool operator==(const consuming_buffers_iterator& a,
|
||||
const consuming_buffers_iterator& b)
|
||||
{
|
||||
return a.equal(b);
|
||||
}
|
||||
|
||||
// Test two iterators for inequality.
|
||||
friend bool operator!=(const consuming_buffers_iterator& a,
|
||||
const consuming_buffers_iterator& b)
|
||||
{
|
||||
return !a.equal(b);
|
||||
}
|
||||
|
||||
private:
|
||||
void increment()
|
||||
{
|
||||
if (!at_end_)
|
||||
{
|
||||
if (begin_remainder_ == end_remainder_
|
||||
|| offset_ + buffer_size(first_) >= max_size_)
|
||||
{
|
||||
at_end_ = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset_ += buffer_size(first_);
|
||||
first_ = buffer(*begin_remainder_++, max_size_ - offset_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool equal(const consuming_buffers_iterator& other) const
|
||||
{
|
||||
if (at_end_ && other.at_end_)
|
||||
return true;
|
||||
return !at_end_ && !other.at_end_
|
||||
&& buffer_cast<const void*>(first_)
|
||||
== buffer_cast<const void*>(other.first_)
|
||||
&& buffer_size(first_) == buffer_size(other.first_)
|
||||
&& begin_remainder_ == other.begin_remainder_
|
||||
&& end_remainder_ == other.end_remainder_;
|
||||
}
|
||||
|
||||
const Buffer& dereference() const
|
||||
{
|
||||
return first_;
|
||||
}
|
||||
|
||||
bool at_end_;
|
||||
Buffer first_;
|
||||
Buffer_Iterator begin_remainder_;
|
||||
Buffer_Iterator end_remainder_;
|
||||
std::size_t offset_;
|
||||
std::size_t max_size_;
|
||||
Buffer elems[max_buffers];
|
||||
std::size_t count;
|
||||
};
|
||||
|
||||
// A proxy for a sub-range in a list of buffers.
|
||||
template <typename Buffer, typename Buffers>
|
||||
template <typename Buffer, typename Buffers, typename Buffer_Iterator>
|
||||
class consuming_buffers
|
||||
{
|
||||
public:
|
||||
// The type for each element in the list of buffers.
|
||||
typedef Buffer value_type;
|
||||
|
||||
// A forward-only iterator type that may be used to read elements.
|
||||
typedef consuming_buffers_iterator<Buffer, typename Buffers::const_iterator>
|
||||
const_iterator;
|
||||
typedef prepared_buffers<Buffer, prepared_buffers_max<Buffers>::value>
|
||||
prepared_buffers_type;
|
||||
|
||||
// Construct to represent the entire list of buffers.
|
||||
consuming_buffers(const Buffers& buffers)
|
||||
explicit consuming_buffers(const Buffers& buffers)
|
||||
: buffers_(buffers),
|
||||
at_end_(buffers_.begin() == buffers_.end()),
|
||||
begin_remainder_(buffers_.begin()),
|
||||
max_size_((std::numeric_limits<std::size_t>::max)())
|
||||
total_consumed_(0),
|
||||
next_elem_(0),
|
||||
next_elem_offset_(0)
|
||||
{
|
||||
if (!at_end_)
|
||||
using boost::asio::buffer_size;
|
||||
total_size_ = buffer_size(buffers);
|
||||
}
|
||||
|
||||
// Determine if we are at the end of the buffers.
|
||||
bool empty() const
|
||||
{
|
||||
return total_consumed_ >= total_size_;
|
||||
}
|
||||
|
||||
// Get the buffer for a single transfer, with a size.
|
||||
prepared_buffers_type prepare(std::size_t max_size)
|
||||
{
|
||||
prepared_buffers_type result;
|
||||
|
||||
Buffer_Iterator next = boost::asio::buffer_sequence_begin(buffers_);
|
||||
Buffer_Iterator end = boost::asio::buffer_sequence_end(buffers_);
|
||||
|
||||
std::advance(next, next_elem_);
|
||||
std::size_t elem_offset = next_elem_offset_;
|
||||
while (next != end && max_size > 0 && (result.count) < result.max_buffers)
|
||||
{
|
||||
first_ = *buffers_.begin();
|
||||
++begin_remainder_;
|
||||
Buffer next_buf = Buffer(*next) + elem_offset;
|
||||
result.elems[result.count] = boost::asio::buffer(next_buf, max_size);
|
||||
max_size -= result.elems[result.count].size();
|
||||
elem_offset = 0;
|
||||
if (result.elems[result.count].size() > 0)
|
||||
++result.count;
|
||||
++next;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy constructor.
|
||||
consuming_buffers(const consuming_buffers& other)
|
||||
: buffers_(other.buffers_),
|
||||
at_end_(other.at_end_),
|
||||
first_(other.first_),
|
||||
begin_remainder_(buffers_.begin()),
|
||||
max_size_(other.max_size_)
|
||||
{
|
||||
typename Buffers::const_iterator first = other.buffers_.begin();
|
||||
typename Buffers::const_iterator second = other.begin_remainder_;
|
||||
std::advance(begin_remainder_, std::distance(first, second));
|
||||
}
|
||||
|
||||
// Assignment operator.
|
||||
consuming_buffers& operator=(const consuming_buffers& other)
|
||||
{
|
||||
buffers_ = other.buffers_;
|
||||
at_end_ = other.at_end_;
|
||||
first_ = other.first_;
|
||||
begin_remainder_ = buffers_.begin();
|
||||
typename Buffers::const_iterator first = other.buffers_.begin();
|
||||
typename Buffers::const_iterator second = other.begin_remainder_;
|
||||
std::advance(begin_remainder_, std::distance(first, second));
|
||||
max_size_ = other.max_size_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Get a forward-only iterator to the first element.
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(at_end_, first_,
|
||||
begin_remainder_, buffers_.end(), max_size_);
|
||||
}
|
||||
|
||||
// Get a forward-only iterator for one past the last element.
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator();
|
||||
}
|
||||
|
||||
// Set the maximum size for a single transfer.
|
||||
void prepare(std::size_t max_size)
|
||||
{
|
||||
max_size_ = max_size;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Consume the specified number of bytes from the buffers.
|
||||
void consume(std::size_t size)
|
||||
{
|
||||
// Remove buffers from the start until the specified size is reached.
|
||||
while (size > 0 && !at_end_)
|
||||
total_consumed_ += size;
|
||||
|
||||
Buffer_Iterator next = boost::asio::buffer_sequence_begin(buffers_);
|
||||
Buffer_Iterator end = boost::asio::buffer_sequence_end(buffers_);
|
||||
|
||||
std::advance(next, next_elem_);
|
||||
while (next != end && size > 0)
|
||||
{
|
||||
if (buffer_size(first_) <= size)
|
||||
Buffer next_buf = Buffer(*next) + next_elem_offset_;
|
||||
if (size < next_buf.size())
|
||||
{
|
||||
size -= buffer_size(first_);
|
||||
if (begin_remainder_ == buffers_.end())
|
||||
at_end_ = true;
|
||||
else
|
||||
first_ = *begin_remainder_++;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_ = first_ + size;
|
||||
next_elem_offset_ += size;
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any more empty buffers at the start.
|
||||
while (!at_end_ && buffer_size(first_) == 0)
|
||||
{
|
||||
if (begin_remainder_ == buffers_.end())
|
||||
at_end_ = true;
|
||||
else
|
||||
first_ = *begin_remainder_++;
|
||||
{
|
||||
size -= next_buf.size();
|
||||
next_elem_offset_ = 0;
|
||||
++next_elem_;
|
||||
++next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the total number of bytes consumed from the buffers.
|
||||
std::size_t total_consumed() const
|
||||
{
|
||||
return total_consumed_;
|
||||
}
|
||||
|
||||
private:
|
||||
Buffers buffers_;
|
||||
bool at_end_;
|
||||
Buffer first_;
|
||||
typename Buffers::const_iterator begin_remainder_;
|
||||
std::size_t max_size_;
|
||||
std::size_t total_size_;
|
||||
std::size_t total_consumed_;
|
||||
std::size_t next_elem_;
|
||||
std::size_t next_elem_offset_;
|
||||
};
|
||||
|
||||
// Base class of all consuming_buffers specialisations for single buffers.
|
||||
template <typename Buffer>
|
||||
class consuming_single_buffer
|
||||
{
|
||||
public:
|
||||
// Construct to represent the entire list of buffers.
|
||||
template <typename Buffer1>
|
||||
explicit consuming_single_buffer(const Buffer1& buffer)
|
||||
: buffer_(buffer),
|
||||
total_consumed_(0)
|
||||
{
|
||||
}
|
||||
|
||||
// Determine if we are at the end of the buffers.
|
||||
bool empty() const
|
||||
{
|
||||
return total_consumed_ >= buffer_.size();
|
||||
}
|
||||
|
||||
// Get the buffer for a single transfer, with a size.
|
||||
Buffer prepare(std::size_t max_size)
|
||||
{
|
||||
return boost::asio::buffer(buffer_ + total_consumed_, max_size);
|
||||
}
|
||||
|
||||
// Consume the specified number of bytes from the buffers.
|
||||
void consume(std::size_t size)
|
||||
{
|
||||
total_consumed_ += size;
|
||||
}
|
||||
|
||||
// Get the total number of bytes consumed from the buffers.
|
||||
std::size_t total_consumed() const
|
||||
{
|
||||
return total_consumed_;
|
||||
}
|
||||
|
||||
private:
|
||||
Buffer buffer_;
|
||||
std::size_t total_consumed_;
|
||||
};
|
||||
|
||||
template <>
|
||||
class consuming_buffers<mutable_buffer, mutable_buffer, const mutable_buffer*>
|
||||
: public consuming_single_buffer<BOOST_ASIO_MUTABLE_BUFFER>
|
||||
{
|
||||
public:
|
||||
explicit consuming_buffers(const mutable_buffer& buffer)
|
||||
: consuming_single_buffer<BOOST_ASIO_MUTABLE_BUFFER>(buffer)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class consuming_buffers<const_buffer, mutable_buffer, const mutable_buffer*>
|
||||
: public consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>
|
||||
{
|
||||
public:
|
||||
explicit consuming_buffers(const mutable_buffer& buffer)
|
||||
: consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>(buffer)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class consuming_buffers<const_buffer, const_buffer, const const_buffer*>
|
||||
: public consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>
|
||||
{
|
||||
public:
|
||||
explicit consuming_buffers(const const_buffer& buffer)
|
||||
: consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>(buffer)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
template <>
|
||||
class consuming_buffers<mutable_buffer,
|
||||
mutable_buffers_1, const mutable_buffer*>
|
||||
: public consuming_single_buffer<BOOST_ASIO_MUTABLE_BUFFER>
|
||||
{
|
||||
public:
|
||||
explicit consuming_buffers(const mutable_buffers_1& buffer)
|
||||
: consuming_single_buffer<BOOST_ASIO_MUTABLE_BUFFER>(buffer)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class consuming_buffers<const_buffer, mutable_buffers_1, const mutable_buffer*>
|
||||
: public consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>
|
||||
{
|
||||
public:
|
||||
explicit consuming_buffers(const mutable_buffers_1& buffer)
|
||||
: consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>(buffer)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class consuming_buffers<const_buffer, const_buffers_1, const const_buffer*>
|
||||
: public consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>
|
||||
{
|
||||
public:
|
||||
explicit consuming_buffers(const const_buffers_1& buffer)
|
||||
: consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>(buffer)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
template <typename Buffer, typename Elem>
|
||||
class consuming_buffers<Buffer, boost::array<Elem, 2>,
|
||||
typename boost::array<Elem, 2>::const_iterator>
|
||||
{
|
||||
public:
|
||||
// Construct to represent the entire list of buffers.
|
||||
explicit consuming_buffers(const boost::array<Elem, 2>& buffers)
|
||||
: buffers_(buffers),
|
||||
total_consumed_(0)
|
||||
{
|
||||
}
|
||||
|
||||
// Determine if we are at the end of the buffers.
|
||||
bool empty() const
|
||||
{
|
||||
return total_consumed_ >=
|
||||
Buffer(buffers_[0]).size() + Buffer(buffers_[1]).size();
|
||||
}
|
||||
|
||||
// Get the buffer for a single transfer, with a size.
|
||||
boost::array<Buffer, 2> prepare(std::size_t max_size)
|
||||
{
|
||||
boost::array<Buffer, 2> result = {{
|
||||
Buffer(buffers_[0]), Buffer(buffers_[1]) }};
|
||||
std::size_t buffer0_size = result[0].size();
|
||||
result[0] = boost::asio::buffer(result[0] + total_consumed_, max_size);
|
||||
result[1] = boost::asio::buffer(
|
||||
result[1] + (total_consumed_ < buffer0_size
|
||||
? 0 : total_consumed_ - buffer0_size),
|
||||
max_size - result[0].size());
|
||||
return result;
|
||||
}
|
||||
|
||||
// Consume the specified number of bytes from the buffers.
|
||||
void consume(std::size_t size)
|
||||
{
|
||||
total_consumed_ += size;
|
||||
}
|
||||
|
||||
// Get the total number of bytes consumed from the buffers.
|
||||
std::size_t total_consumed() const
|
||||
{
|
||||
return total_consumed_;
|
||||
}
|
||||
|
||||
private:
|
||||
boost::array<Elem, 2> buffers_;
|
||||
std::size_t total_consumed_;
|
||||
};
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_STD_ARRAY)
|
||||
|
||||
template <typename Buffer, typename Elem>
|
||||
class consuming_buffers<Buffer, std::array<Elem, 2>,
|
||||
typename std::array<Elem, 2>::const_iterator>
|
||||
{
|
||||
public:
|
||||
// Construct to represent the entire list of buffers.
|
||||
explicit consuming_buffers(const std::array<Elem, 2>& buffers)
|
||||
: buffers_(buffers),
|
||||
total_consumed_(0)
|
||||
{
|
||||
}
|
||||
|
||||
// Determine if we are at the end of the buffers.
|
||||
bool empty() const
|
||||
{
|
||||
return total_consumed_ >=
|
||||
Buffer(buffers_[0]).size() + Buffer(buffers_[1]).size();
|
||||
}
|
||||
|
||||
// Get the buffer for a single transfer, with a size.
|
||||
std::array<Buffer, 2> prepare(std::size_t max_size)
|
||||
{
|
||||
std::array<Buffer, 2> result = {{
|
||||
Buffer(buffers_[0]), Buffer(buffers_[1]) }};
|
||||
std::size_t buffer0_size = result[0].size();
|
||||
result[0] = boost::asio::buffer(result[0] + total_consumed_, max_size);
|
||||
result[1] = boost::asio::buffer(
|
||||
result[1] + (total_consumed_ < buffer0_size
|
||||
? 0 : total_consumed_ - buffer0_size),
|
||||
max_size - result[0].size());
|
||||
return result;
|
||||
}
|
||||
|
||||
// Consume the specified number of bytes from the buffers.
|
||||
void consume(std::size_t size)
|
||||
{
|
||||
total_consumed_ += size;
|
||||
}
|
||||
|
||||
// Get the total number of bytes consumed from the buffers.
|
||||
std::size_t total_consumed() const
|
||||
{
|
||||
return total_consumed_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<Elem, 2> buffers_;
|
||||
std::size_t total_consumed_;
|
||||
};
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
|
||||
|
||||
// Specialisation for null_buffers to ensure that the null_buffers type is
|
||||
// always passed through to the underlying read or write operation.
|
||||
template <typename Buffer>
|
||||
class consuming_buffers<Buffer, boost::asio::null_buffers>
|
||||
class consuming_buffers<Buffer, null_buffers, const mutable_buffer*>
|
||||
: public boost::asio::null_buffers
|
||||
{
|
||||
public:
|
||||
consuming_buffers(const boost::asio::null_buffers&)
|
||||
consuming_buffers(const null_buffers&)
|
||||
{
|
||||
// No-op.
|
||||
}
|
||||
|
||||
void prepare(std::size_t)
|
||||
bool empty()
|
||||
{
|
||||
// No-op.
|
||||
return false;
|
||||
}
|
||||
|
||||
null_buffers prepare(std::size_t)
|
||||
{
|
||||
return null_buffers();
|
||||
}
|
||||
|
||||
void consume(std::size_t)
|
||||
{
|
||||
// No-op.
|
||||
}
|
||||
|
||||
std::size_t total_consumed() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
33
winx64/include/boost/asio/detail/cstddef.hpp
Normal file
33
winx64/include/boost/asio/detail/cstddef.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// detail/cstddef.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_DETAIL_CSTDDEF_HPP
|
||||
#define BOOST_ASIO_DETAIL_CSTDDEF_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_NULLPTR)
|
||||
using std::nullptr_t;
|
||||
#else // defined(BOOST_ASIO_HAS_NULLPTR)
|
||||
struct nullptr_t {};
|
||||
#endif // defined(BOOST_ASIO_HAS_NULLPTR)
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_CSTDDEF_HPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/cstdint.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -28,18 +28,32 @@ namespace asio {
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_CSTDINT)
|
||||
using std::int16_t;
|
||||
using std::int_least16_t;
|
||||
using std::uint16_t;
|
||||
using std::uint_least16_t;
|
||||
using std::int32_t;
|
||||
using std::int_least32_t;
|
||||
using std::uint32_t;
|
||||
using std::uint_least32_t;
|
||||
using std::int64_t;
|
||||
using std::int_least64_t;
|
||||
using std::uint64_t;
|
||||
using std::uint_least64_t;
|
||||
using std::uintmax_t;
|
||||
#else // defined(BOOST_ASIO_HAS_CSTDINT)
|
||||
using boost::int16_t;
|
||||
using boost::int_least16_t;
|
||||
using boost::uint16_t;
|
||||
using boost::uint_least16_t;
|
||||
using boost::int32_t;
|
||||
using boost::int_least32_t;
|
||||
using boost::uint32_t;
|
||||
using boost::uint_least32_t;
|
||||
using boost::int64_t;
|
||||
using boost::int_least64_t;
|
||||
using boost::uint64_t;
|
||||
using boost::uint_least64_t;
|
||||
using boost::uintmax_t;
|
||||
#endif // defined(BOOST_ASIO_HAS_CSTDINT)
|
||||
|
||||
} // namespace asio
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/date_time_fwd.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/deadline_timer_service.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -18,14 +18,15 @@
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <cstddef>
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/detail/addressof.hpp>
|
||||
#include <boost/asio/execution_context.hpp>
|
||||
#include <boost/asio/detail/bind_handler.hpp>
|
||||
#include <boost/asio/detail/fenced_block.hpp>
|
||||
#include <boost/asio/detail/memory.hpp>
|
||||
#include <boost/asio/detail/noncopyable.hpp>
|
||||
#include <boost/asio/detail/socket_ops.hpp>
|
||||
#include <boost/asio/detail/socket_types.hpp>
|
||||
#include <boost/asio/detail/timer_queue.hpp>
|
||||
#include <boost/asio/detail/timer_queue_ptime.hpp>
|
||||
#include <boost/asio/detail/timer_scheduler.hpp>
|
||||
#include <boost/asio/detail/wait_handler.hpp>
|
||||
#include <boost/asio/detail/wait_op.hpp>
|
||||
@@ -43,6 +44,7 @@ namespace detail {
|
||||
|
||||
template <typename Time_Traits>
|
||||
class deadline_timer_service
|
||||
: public execution_context_service_base<deadline_timer_service<Time_Traits> >
|
||||
{
|
||||
public:
|
||||
// The time type.
|
||||
@@ -62,8 +64,10 @@ public:
|
||||
};
|
||||
|
||||
// Constructor.
|
||||
deadline_timer_service(boost::asio::io_service& io_service)
|
||||
: scheduler_(boost::asio::use_service<timer_scheduler>(io_service))
|
||||
deadline_timer_service(execution_context& context)
|
||||
: execution_context_service_base<
|
||||
deadline_timer_service<Time_Traits> >(context),
|
||||
scheduler_(boost::asio::use_service<timer_scheduler>(context))
|
||||
{
|
||||
scheduler_.init_task();
|
||||
scheduler_.add_timer_queue(timer_queue_);
|
||||
@@ -76,7 +80,7 @@ public:
|
||||
}
|
||||
|
||||
// Destroy all user-defined handler objects owned by the service.
|
||||
void shutdown_service()
|
||||
void shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -94,6 +98,38 @@ public:
|
||||
cancel(impl, ec);
|
||||
}
|
||||
|
||||
// Move-construct a new serial port implementation.
|
||||
void move_construct(implementation_type& impl,
|
||||
implementation_type& other_impl)
|
||||
{
|
||||
scheduler_.move_timer(timer_queue_, impl.timer_data, other_impl.timer_data);
|
||||
|
||||
impl.expiry = other_impl.expiry;
|
||||
other_impl.expiry = time_type();
|
||||
|
||||
impl.might_have_pending_waits = other_impl.might_have_pending_waits;
|
||||
other_impl.might_have_pending_waits = false;
|
||||
}
|
||||
|
||||
// Move-assign from another serial port implementation.
|
||||
void move_assign(implementation_type& impl,
|
||||
deadline_timer_service& other_service,
|
||||
implementation_type& other_impl)
|
||||
{
|
||||
if (this != &other_service)
|
||||
if (impl.might_have_pending_waits)
|
||||
scheduler_.cancel_timer(timer_queue_, impl.timer_data);
|
||||
|
||||
other_service.scheduler_.move_timer(other_service.timer_queue_,
|
||||
impl.timer_data, other_impl.timer_data);
|
||||
|
||||
impl.expiry = other_impl.expiry;
|
||||
other_impl.expiry = time_type();
|
||||
|
||||
impl.might_have_pending_waits = other_impl.might_have_pending_waits;
|
||||
other_impl.might_have_pending_waits = false;
|
||||
}
|
||||
|
||||
// Cancel any asynchronous wait operations associated with the timer.
|
||||
std::size_t cancel(implementation_type& impl, boost::system::error_code& ec)
|
||||
{
|
||||
@@ -103,7 +139,8 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOST_ASIO_HANDLER_OPERATION(("deadline_timer", &impl, "cancel"));
|
||||
BOOST_ASIO_HANDLER_OPERATION((scheduler_.context(),
|
||||
"deadline_timer", &impl, 0, "cancel"));
|
||||
|
||||
std::size_t count = scheduler_.cancel_timer(timer_queue_, impl.timer_data);
|
||||
impl.might_have_pending_waits = false;
|
||||
@@ -121,7 +158,8 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOST_ASIO_HANDLER_OPERATION(("deadline_timer", &impl, "cancel_one"));
|
||||
BOOST_ASIO_HANDLER_OPERATION((scheduler_.context(),
|
||||
"deadline_timer", &impl, 0, "cancel_one"));
|
||||
|
||||
std::size_t count = scheduler_.cancel_timer(
|
||||
timer_queue_, impl.timer_data, 1);
|
||||
@@ -131,12 +169,24 @@ public:
|
||||
return count;
|
||||
}
|
||||
|
||||
// Get the expiry time for the timer as an absolute time.
|
||||
time_type expiry(const implementation_type& impl) const
|
||||
{
|
||||
return impl.expiry;
|
||||
}
|
||||
|
||||
// Get the expiry time for the timer as an absolute time.
|
||||
time_type expires_at(const implementation_type& impl) const
|
||||
{
|
||||
return impl.expiry;
|
||||
}
|
||||
|
||||
// Get the expiry time for the timer relative to now.
|
||||
duration_type expires_from_now(const implementation_type& impl) const
|
||||
{
|
||||
return Time_Traits::subtract(this->expiry(impl), Time_Traits::now());
|
||||
}
|
||||
|
||||
// Set the expiry time for the timer as an absolute time.
|
||||
std::size_t expires_at(implementation_type& impl,
|
||||
const time_type& expiry_time, boost::system::error_code& ec)
|
||||
@@ -147,10 +197,12 @@ public:
|
||||
return count;
|
||||
}
|
||||
|
||||
// Get the expiry time for the timer relative to now.
|
||||
duration_type expires_from_now(const implementation_type& impl) const
|
||||
// Set the expiry time for the timer relative to now.
|
||||
std::size_t expires_after(implementation_type& impl,
|
||||
const duration_type& expiry_time, boost::system::error_code& ec)
|
||||
{
|
||||
return Time_Traits::subtract(expires_at(impl), Time_Traits::now());
|
||||
return expires_at(impl,
|
||||
Time_Traits::add(Time_Traits::now(), expiry_time), ec);
|
||||
}
|
||||
|
||||
// Set the expiry time for the timer relative to now.
|
||||
@@ -175,19 +227,20 @@ public:
|
||||
}
|
||||
|
||||
// Start an asynchronous wait on the timer.
|
||||
template <typename Handler>
|
||||
void async_wait(implementation_type& impl, Handler& handler)
|
||||
template <typename Handler, typename IoExecutor>
|
||||
void async_wait(implementation_type& impl,
|
||||
Handler& handler, const IoExecutor& io_ex)
|
||||
{
|
||||
// Allocate and construct an operation to wrap the handler.
|
||||
typedef wait_handler<Handler> op;
|
||||
typedef wait_handler<Handler, IoExecutor> op;
|
||||
typename op::ptr p = { boost::asio::detail::addressof(handler),
|
||||
boost_asio_handler_alloc_helpers::allocate(
|
||||
sizeof(op), handler), 0 };
|
||||
p.p = new (p.v) op(handler);
|
||||
op::ptr::allocate(handler), 0 };
|
||||
p.p = new (p.v) op(handler, io_ex);
|
||||
|
||||
impl.might_have_pending_waits = true;
|
||||
|
||||
BOOST_ASIO_HANDLER_CREATION((p.p, "deadline_timer", &impl, "async_wait"));
|
||||
BOOST_ASIO_HANDLER_CREATION((scheduler_.context(),
|
||||
*p.p, "deadline_timer", &impl, 0, "async_wait"));
|
||||
|
||||
scheduler_.schedule_timer(timer_queue_, impl.expiry, impl.timer_data, p.p);
|
||||
p.v = p.p = 0;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/dependent_type.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/descriptor_ops.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -22,6 +22,7 @@
|
||||
&& !defined(__CYGWIN__)
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/asio/detail/socket_types.hpp>
|
||||
|
||||
@@ -101,6 +102,9 @@ BOOST_ASIO_DECL int poll_read(int d,
|
||||
BOOST_ASIO_DECL int poll_write(int d,
|
||||
state_type state, boost::system::error_code& ec);
|
||||
|
||||
BOOST_ASIO_DECL int poll_error(int d,
|
||||
state_type state, boost::system::error_code& ec);
|
||||
|
||||
} // namespace descriptor_ops
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/descriptor_read_op.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -19,11 +19,12 @@
|
||||
|
||||
#if !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
|
||||
|
||||
#include <boost/asio/detail/addressof.hpp>
|
||||
#include <boost/asio/detail/bind_handler.hpp>
|
||||
#include <boost/asio/detail/buffer_sequence_adapter.hpp>
|
||||
#include <boost/asio/detail/descriptor_ops.hpp>
|
||||
#include <boost/asio/detail/fenced_block.hpp>
|
||||
#include <boost/asio/detail/handler_work.hpp>
|
||||
#include <boost/asio/detail/memory.hpp>
|
||||
#include <boost/asio/detail/reactor_op.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
@@ -44,15 +45,21 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
static bool do_perform(reactor_op* base)
|
||||
static status do_perform(reactor_op* base)
|
||||
{
|
||||
descriptor_read_op_base* o(static_cast<descriptor_read_op_base*>(base));
|
||||
|
||||
buffer_sequence_adapter<boost::asio::mutable_buffer,
|
||||
MutableBufferSequence> bufs(o->buffers_);
|
||||
|
||||
return descriptor_ops::non_blocking_read(o->descriptor_,
|
||||
bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_);
|
||||
status result = descriptor_ops::non_blocking_read(o->descriptor_,
|
||||
bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_)
|
||||
? done : not_done;
|
||||
|
||||
BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_read",
|
||||
o->ec_, o->bytes_transferred_));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -60,30 +67,33 @@ private:
|
||||
MutableBufferSequence buffers_;
|
||||
};
|
||||
|
||||
template <typename MutableBufferSequence, typename Handler>
|
||||
template <typename MutableBufferSequence, typename Handler, typename IoExecutor>
|
||||
class descriptor_read_op
|
||||
: public descriptor_read_op_base<MutableBufferSequence>
|
||||
{
|
||||
public:
|
||||
BOOST_ASIO_DEFINE_HANDLER_PTR(descriptor_read_op);
|
||||
|
||||
descriptor_read_op(int descriptor,
|
||||
const MutableBufferSequence& buffers, Handler& handler)
|
||||
descriptor_read_op(int descriptor, const MutableBufferSequence& buffers,
|
||||
Handler& handler, const IoExecutor& io_ex)
|
||||
: descriptor_read_op_base<MutableBufferSequence>(
|
||||
descriptor, buffers, &descriptor_read_op::do_complete),
|
||||
handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
|
||||
handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
|
||||
io_executor_(io_ex)
|
||||
{
|
||||
handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
|
||||
}
|
||||
|
||||
static void do_complete(io_service_impl* owner, operation* base,
|
||||
static void do_complete(void* owner, operation* base,
|
||||
const boost::system::error_code& /*ec*/,
|
||||
std::size_t /*bytes_transferred*/)
|
||||
{
|
||||
// Take ownership of the handler object.
|
||||
descriptor_read_op* o(static_cast<descriptor_read_op*>(base));
|
||||
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
|
||||
handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
|
||||
|
||||
BOOST_ASIO_HANDLER_COMPLETION((o));
|
||||
BOOST_ASIO_HANDLER_COMPLETION((*o));
|
||||
|
||||
// Make a copy of the handler so that the memory can be deallocated before
|
||||
// the upcall is made. Even if we're not about to make an upcall, a
|
||||
@@ -101,13 +111,14 @@ public:
|
||||
{
|
||||
fenced_block b(fenced_block::half);
|
||||
BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_));
|
||||
boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
|
||||
w.complete(handler, handler.handler_);
|
||||
BOOST_ASIO_HANDLER_INVOCATION_END;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
IoExecutor io_executor_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/descriptor_write_op.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -19,11 +19,12 @@
|
||||
|
||||
#if !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
|
||||
|
||||
#include <boost/asio/detail/addressof.hpp>
|
||||
#include <boost/asio/detail/bind_handler.hpp>
|
||||
#include <boost/asio/detail/buffer_sequence_adapter.hpp>
|
||||
#include <boost/asio/detail/descriptor_ops.hpp>
|
||||
#include <boost/asio/detail/fenced_block.hpp>
|
||||
#include <boost/asio/detail/handler_work.hpp>
|
||||
#include <boost/asio/detail/memory.hpp>
|
||||
#include <boost/asio/detail/reactor_op.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
@@ -44,15 +45,21 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
static bool do_perform(reactor_op* base)
|
||||
static status do_perform(reactor_op* base)
|
||||
{
|
||||
descriptor_write_op_base* o(static_cast<descriptor_write_op_base*>(base));
|
||||
|
||||
buffer_sequence_adapter<boost::asio::const_buffer,
|
||||
ConstBufferSequence> bufs(o->buffers_);
|
||||
|
||||
return descriptor_ops::non_blocking_write(o->descriptor_,
|
||||
bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_);
|
||||
status result = descriptor_ops::non_blocking_write(o->descriptor_,
|
||||
bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_)
|
||||
? done : not_done;
|
||||
|
||||
BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_write",
|
||||
o->ec_, o->bytes_transferred_));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -60,30 +67,33 @@ private:
|
||||
ConstBufferSequence buffers_;
|
||||
};
|
||||
|
||||
template <typename ConstBufferSequence, typename Handler>
|
||||
template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
|
||||
class descriptor_write_op
|
||||
: public descriptor_write_op_base<ConstBufferSequence>
|
||||
{
|
||||
public:
|
||||
BOOST_ASIO_DEFINE_HANDLER_PTR(descriptor_write_op);
|
||||
|
||||
descriptor_write_op(int descriptor,
|
||||
const ConstBufferSequence& buffers, Handler& handler)
|
||||
descriptor_write_op(int descriptor, const ConstBufferSequence& buffers,
|
||||
Handler& handler, const IoExecutor& io_ex)
|
||||
: descriptor_write_op_base<ConstBufferSequence>(
|
||||
descriptor, buffers, &descriptor_write_op::do_complete),
|
||||
handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
|
||||
handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
|
||||
io_executor_(io_ex)
|
||||
{
|
||||
handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
|
||||
}
|
||||
|
||||
static void do_complete(io_service_impl* owner, operation* base,
|
||||
static void do_complete(void* owner, operation* base,
|
||||
const boost::system::error_code& /*ec*/,
|
||||
std::size_t /*bytes_transferred*/)
|
||||
{
|
||||
// Take ownership of the handler object.
|
||||
descriptor_write_op* o(static_cast<descriptor_write_op*>(base));
|
||||
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
|
||||
handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
|
||||
|
||||
BOOST_ASIO_HANDLER_COMPLETION((o));
|
||||
BOOST_ASIO_HANDLER_COMPLETION((*o));
|
||||
|
||||
// Make a copy of the handler so that the memory can be deallocated before
|
||||
// the upcall is made. Even if we're not about to make an upcall, a
|
||||
@@ -101,13 +111,14 @@ public:
|
||||
{
|
||||
fenced_block b(fenced_block::half);
|
||||
BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_));
|
||||
boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
|
||||
w.complete(handler, handler.handler_);
|
||||
BOOST_ASIO_HANDLER_INVOCATION_END;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
IoExecutor io_executor_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/dev_poll_reactor.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <boost/asio/detail/timer_queue_base.hpp>
|
||||
#include <boost/asio/detail/timer_queue_set.hpp>
|
||||
#include <boost/asio/detail/wait_op.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/execution_context.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace asio {
|
||||
namespace detail {
|
||||
|
||||
class dev_poll_reactor
|
||||
: public boost::asio::detail::service_base<dev_poll_reactor>
|
||||
: public execution_context_service_base<dev_poll_reactor>
|
||||
{
|
||||
public:
|
||||
enum op_types { read_op = 0, write_op = 1,
|
||||
@@ -54,17 +54,17 @@ public:
|
||||
};
|
||||
|
||||
// Constructor.
|
||||
BOOST_ASIO_DECL dev_poll_reactor(boost::asio::io_service& io_service);
|
||||
BOOST_ASIO_DECL dev_poll_reactor(boost::asio::execution_context& ctx);
|
||||
|
||||
// Destructor.
|
||||
BOOST_ASIO_DECL ~dev_poll_reactor();
|
||||
|
||||
// Destroy all user-defined handler objects owned by the service.
|
||||
BOOST_ASIO_DECL void shutdown_service();
|
||||
BOOST_ASIO_DECL void shutdown();
|
||||
|
||||
// Recreate internal descriptors following a fork.
|
||||
BOOST_ASIO_DECL void fork_service(
|
||||
boost::asio::io_service::fork_event fork_ev);
|
||||
BOOST_ASIO_DECL void notify_fork(
|
||||
boost::asio::execution_context::fork_event fork_ev);
|
||||
|
||||
// Initialise the task.
|
||||
BOOST_ASIO_DECL void init_task();
|
||||
@@ -87,7 +87,7 @@ public:
|
||||
// Post a reactor operation for immediate completion.
|
||||
void post_immediate_completion(reactor_op* op, bool is_continuation)
|
||||
{
|
||||
io_service_.post_immediate_completion(op, is_continuation);
|
||||
scheduler_.post_immediate_completion(op, is_continuation);
|
||||
}
|
||||
|
||||
// Start a new operation. The reactor operation will be performed when the
|
||||
@@ -102,15 +102,21 @@ public:
|
||||
BOOST_ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data&);
|
||||
|
||||
// Cancel any operations that are running against the descriptor and remove
|
||||
// its registration from the reactor.
|
||||
// its registration from the reactor. The reactor resources associated with
|
||||
// the descriptor must be released by calling cleanup_descriptor_data.
|
||||
BOOST_ASIO_DECL void deregister_descriptor(socket_type descriptor,
|
||||
per_descriptor_data&, bool closing);
|
||||
|
||||
// Cancel any operations that are running against the descriptor and remove
|
||||
// its registration from the reactor.
|
||||
// Remove the descriptor's registration from the reactor. The reactor
|
||||
// resources associated with the descriptor must be released by calling
|
||||
// cleanup_descriptor_data.
|
||||
BOOST_ASIO_DECL void deregister_internal_descriptor(
|
||||
socket_type descriptor, per_descriptor_data&);
|
||||
|
||||
// Perform any post-deregistration cleanup tasks associated with the
|
||||
// descriptor data.
|
||||
BOOST_ASIO_DECL void cleanup_descriptor_data(per_descriptor_data&);
|
||||
|
||||
// Add a new timer queue to the reactor.
|
||||
template <typename Time_Traits>
|
||||
void add_timer_queue(timer_queue<Time_Traits>& queue);
|
||||
@@ -133,8 +139,14 @@ public:
|
||||
typename timer_queue<Time_Traits>::per_timer_data& timer,
|
||||
std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());
|
||||
|
||||
// Move the timer operations associated with the given timer.
|
||||
template <typename Time_Traits>
|
||||
void move_timer(timer_queue<Time_Traits>& queue,
|
||||
typename timer_queue<Time_Traits>::per_timer_data& target,
|
||||
typename timer_queue<Time_Traits>::per_timer_data& source);
|
||||
|
||||
// Run /dev/poll once until interrupted or events are ready to be dispatched.
|
||||
BOOST_ASIO_DECL void run(bool block, op_queue<operation>& ops);
|
||||
BOOST_ASIO_DECL void run(long usec, op_queue<operation>& ops);
|
||||
|
||||
// Interrupt the select loop.
|
||||
BOOST_ASIO_DECL void interrupt();
|
||||
@@ -153,7 +165,7 @@ private:
|
||||
// Get the timeout value for the /dev/poll DP_POLL operation. The timeout
|
||||
// value is returned as a number of milliseconds. A return value of -1
|
||||
// indicates that the poll should block indefinitely.
|
||||
BOOST_ASIO_DECL int get_timeout();
|
||||
BOOST_ASIO_DECL int get_timeout(int msec);
|
||||
|
||||
// Cancel all operations associated with the given descriptor. The do_cancel
|
||||
// function of the handler objects will be invoked. This function does not
|
||||
@@ -164,8 +176,8 @@ private:
|
||||
// Add a pending event entry for the given descriptor.
|
||||
BOOST_ASIO_DECL ::pollfd& add_pending_event_change(int descriptor);
|
||||
|
||||
// The io_service implementation used to post completions.
|
||||
io_service_impl& io_service_;
|
||||
// The scheduler implementation used to post completions.
|
||||
scheduler& scheduler_;
|
||||
|
||||
// Mutex to protect access to internal data.
|
||||
boost::asio::detail::mutex mutex_;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/epoll_reactor.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -19,10 +19,9 @@
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_EPOLL)
|
||||
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/detail/atomic_count.hpp>
|
||||
#include <boost/asio/detail/conditionally_enabled_mutex.hpp>
|
||||
#include <boost/asio/detail/limits.hpp>
|
||||
#include <boost/asio/detail/mutex.hpp>
|
||||
#include <boost/asio/detail/object_pool.hpp>
|
||||
#include <boost/asio/detail/op_queue.hpp>
|
||||
#include <boost/asio/detail/reactor_op.hpp>
|
||||
@@ -31,6 +30,11 @@
|
||||
#include <boost/asio/detail/timer_queue_base.hpp>
|
||||
#include <boost/asio/detail/timer_queue_set.hpp>
|
||||
#include <boost/asio/detail/wait_op.hpp>
|
||||
#include <boost/asio/execution_context.hpp>
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_TIMERFD)
|
||||
# include <sys/timerfd.h>
|
||||
#endif // defined(BOOST_ASIO_HAS_TIMERFD)
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
@@ -39,8 +43,12 @@ namespace asio {
|
||||
namespace detail {
|
||||
|
||||
class epoll_reactor
|
||||
: public boost::asio::detail::service_base<epoll_reactor>
|
||||
: public execution_context_service_base<epoll_reactor>
|
||||
{
|
||||
private:
|
||||
// The mutex type used by this reactor.
|
||||
typedef conditionally_enabled_mutex mutex;
|
||||
|
||||
public:
|
||||
enum op_types { read_op = 0, write_op = 1,
|
||||
connect_op = 1, except_op = 2, max_ops = 3 };
|
||||
@@ -59,13 +67,15 @@ public:
|
||||
int descriptor_;
|
||||
uint32_t registered_events_;
|
||||
op_queue<reactor_op> op_queue_[max_ops];
|
||||
bool try_speculative_[max_ops];
|
||||
bool shutdown_;
|
||||
|
||||
BOOST_ASIO_DECL descriptor_state();
|
||||
BOOST_ASIO_DECL descriptor_state(bool locking);
|
||||
void set_ready_events(uint32_t events) { task_result_ = events; }
|
||||
void add_ready_events(uint32_t events) { task_result_ |= events; }
|
||||
BOOST_ASIO_DECL operation* perform_io(uint32_t events);
|
||||
BOOST_ASIO_DECL static void do_complete(
|
||||
io_service_impl* owner, operation* base,
|
||||
void* owner, operation* base,
|
||||
const boost::system::error_code& ec, std::size_t bytes_transferred);
|
||||
};
|
||||
|
||||
@@ -73,17 +83,17 @@ public:
|
||||
typedef descriptor_state* per_descriptor_data;
|
||||
|
||||
// Constructor.
|
||||
BOOST_ASIO_DECL epoll_reactor(boost::asio::io_service& io_service);
|
||||
BOOST_ASIO_DECL epoll_reactor(boost::asio::execution_context& ctx);
|
||||
|
||||
// Destructor.
|
||||
BOOST_ASIO_DECL ~epoll_reactor();
|
||||
|
||||
// Destroy all user-defined handler objects owned by the service.
|
||||
BOOST_ASIO_DECL void shutdown_service();
|
||||
BOOST_ASIO_DECL void shutdown();
|
||||
|
||||
// Recreate internal descriptors following a fork.
|
||||
BOOST_ASIO_DECL void fork_service(
|
||||
boost::asio::io_service::fork_event fork_ev);
|
||||
BOOST_ASIO_DECL void notify_fork(
|
||||
boost::asio::execution_context::fork_event fork_ev);
|
||||
|
||||
// Initialise the task.
|
||||
BOOST_ASIO_DECL void init_task();
|
||||
@@ -107,7 +117,7 @@ public:
|
||||
// Post a reactor operation for immediate completion.
|
||||
void post_immediate_completion(reactor_op* op, bool is_continuation)
|
||||
{
|
||||
io_service_.post_immediate_completion(op, is_continuation);
|
||||
scheduler_.post_immediate_completion(op, is_continuation);
|
||||
}
|
||||
|
||||
// Start a new operation. The reactor operation will be performed when the
|
||||
@@ -123,14 +133,22 @@ public:
|
||||
per_descriptor_data& descriptor_data);
|
||||
|
||||
// Cancel any operations that are running against the descriptor and remove
|
||||
// its registration from the reactor.
|
||||
// its registration from the reactor. The reactor resources associated with
|
||||
// the descriptor must be released by calling cleanup_descriptor_data.
|
||||
BOOST_ASIO_DECL void deregister_descriptor(socket_type descriptor,
|
||||
per_descriptor_data& descriptor_data, bool closing);
|
||||
|
||||
// Remote the descriptor's registration from the reactor.
|
||||
// Remove the descriptor's registration from the reactor. The reactor
|
||||
// resources associated with the descriptor must be released by calling
|
||||
// cleanup_descriptor_data.
|
||||
BOOST_ASIO_DECL void deregister_internal_descriptor(
|
||||
socket_type descriptor, per_descriptor_data& descriptor_data);
|
||||
|
||||
// Perform any post-deregistration cleanup tasks associated with the
|
||||
// descriptor data.
|
||||
BOOST_ASIO_DECL void cleanup_descriptor_data(
|
||||
per_descriptor_data& descriptor_data);
|
||||
|
||||
// Add a new timer queue to the reactor.
|
||||
template <typename Time_Traits>
|
||||
void add_timer_queue(timer_queue<Time_Traits>& timer_queue);
|
||||
@@ -153,8 +171,14 @@ public:
|
||||
typename timer_queue<Time_Traits>::per_timer_data& timer,
|
||||
std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());
|
||||
|
||||
// Move the timer operations associated with the given timer.
|
||||
template <typename Time_Traits>
|
||||
void move_timer(timer_queue<Time_Traits>& queue,
|
||||
typename timer_queue<Time_Traits>::per_timer_data& target,
|
||||
typename timer_queue<Time_Traits>::per_timer_data& source);
|
||||
|
||||
// Run epoll once until interrupted or events are ready to be dispatched.
|
||||
BOOST_ASIO_DECL void run(bool block, op_queue<operation>& ops);
|
||||
BOOST_ASIO_DECL void run(long usec, op_queue<operation>& ops);
|
||||
|
||||
// Interrupt the select loop.
|
||||
BOOST_ASIO_DECL void interrupt();
|
||||
@@ -188,7 +212,7 @@ private:
|
||||
// Get the timeout value for the epoll_wait call. The timeout value is
|
||||
// returned as a number of milliseconds. A return value of -1 indicates
|
||||
// that epoll_wait should block indefinitely.
|
||||
BOOST_ASIO_DECL int get_timeout();
|
||||
BOOST_ASIO_DECL int get_timeout(int msec);
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_TIMERFD)
|
||||
// Get the timeout value for the timer descriptor. The return value is the
|
||||
@@ -196,8 +220,8 @@ private:
|
||||
BOOST_ASIO_DECL int get_timeout(itimerspec& ts);
|
||||
#endif // defined(BOOST_ASIO_HAS_TIMERFD)
|
||||
|
||||
// The io_service implementation used to post completions.
|
||||
io_service_impl& io_service_;
|
||||
// The scheduler implementation used to post completions.
|
||||
scheduler& scheduler_;
|
||||
|
||||
// Mutex to protect access to internal data.
|
||||
mutex mutex_;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/event.hpp
|
||||
// ~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/eventfd_select_interrupter.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
|
||||
106
winx64/include/boost/asio/detail/executor_function.hpp
Normal file
106
winx64/include/boost/asio/detail/executor_function.hpp
Normal file
@@ -0,0 +1,106 @@
|
||||
//
|
||||
// detail/executor_function.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_DETAIL_EXECUTOR_FUNCTION_HPP
|
||||
#define BOOST_ASIO_DETAIL_EXECUTOR_FUNCTION_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/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
class executor_function_base
|
||||
{
|
||||
public:
|
||||
void complete()
|
||||
{
|
||||
func_(this, true);
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
func_(this, false);
|
||||
}
|
||||
|
||||
protected:
|
||||
typedef void (*func_type)(executor_function_base*, bool);
|
||||
|
||||
executor_function_base(func_type func)
|
||||
: func_(func)
|
||||
{
|
||||
}
|
||||
|
||||
// Prevents deletion through this type.
|
||||
~executor_function_base()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
func_type func_;
|
||||
};
|
||||
|
||||
template <typename Function, typename Alloc>
|
||||
class executor_function : public executor_function_base
|
||||
{
|
||||
public:
|
||||
BOOST_ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR(
|
||||
thread_info_base::executor_function_tag, executor_function);
|
||||
|
||||
template <typename F>
|
||||
executor_function(BOOST_ASIO_MOVE_ARG(F) f, const Alloc& allocator)
|
||||
: executor_function_base(&executor_function::do_complete),
|
||||
function_(BOOST_ASIO_MOVE_CAST(F)(f)),
|
||||
allocator_(allocator)
|
||||
{
|
||||
}
|
||||
|
||||
static void do_complete(executor_function_base* base, bool call)
|
||||
{
|
||||
// Take ownership of the function object.
|
||||
executor_function* o(static_cast<executor_function*>(base));
|
||||
Alloc allocator(o->allocator_);
|
||||
ptr p = { detail::addressof(allocator), o, o };
|
||||
|
||||
// Make a copy of the function so that the memory can be deallocated before
|
||||
// the upcall is made. Even if we're not about to make an upcall, a
|
||||
// sub-object of the function may be the true owner of the memory
|
||||
// associated with the function. Consequently, a local copy of the function
|
||||
// is required to ensure that any owning sub-object remains valid until
|
||||
// after we have deallocated the memory here.
|
||||
Function function(BOOST_ASIO_MOVE_CAST(Function)(o->function_));
|
||||
p.reset();
|
||||
|
||||
// Make the upcall if required.
|
||||
if (call)
|
||||
{
|
||||
function();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Function function_;
|
||||
Alloc allocator_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_EXECUTOR_FUNCTION_HPP
|
||||
86
winx64/include/boost/asio/detail/executor_op.hpp
Normal file
86
winx64/include/boost/asio/detail/executor_op.hpp
Normal file
@@ -0,0 +1,86 @@
|
||||
//
|
||||
// detail/executor_op.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_DETAIL_EXECUTOR_OP_HPP
|
||||
#define BOOST_ASIO_DETAIL_EXECUTOR_OP_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/fenced_block.hpp>
|
||||
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||
#include <boost/asio/detail/scheduler_operation.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
template <typename Handler, typename Alloc,
|
||||
typename Operation = scheduler_operation>
|
||||
class executor_op : public Operation
|
||||
{
|
||||
public:
|
||||
BOOST_ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(executor_op);
|
||||
|
||||
template <typename H>
|
||||
executor_op(BOOST_ASIO_MOVE_ARG(H) h, const Alloc& allocator)
|
||||
: Operation(&executor_op::do_complete),
|
||||
handler_(BOOST_ASIO_MOVE_CAST(H)(h)),
|
||||
allocator_(allocator)
|
||||
{
|
||||
}
|
||||
|
||||
static void do_complete(void* owner, Operation* base,
|
||||
const boost::system::error_code& /*ec*/,
|
||||
std::size_t /*bytes_transferred*/)
|
||||
{
|
||||
// Take ownership of the handler object.
|
||||
executor_op* o(static_cast<executor_op*>(base));
|
||||
Alloc allocator(o->allocator_);
|
||||
ptr p = { detail::addressof(allocator), o, o };
|
||||
|
||||
BOOST_ASIO_HANDLER_COMPLETION((*o));
|
||||
|
||||
// Make a copy of the handler so that the memory can be deallocated before
|
||||
// the upcall is made. Even if we're not about to make an upcall, a
|
||||
// sub-object of the handler may be the true owner of the memory associated
|
||||
// with the handler. Consequently, a local copy of the handler is required
|
||||
// to ensure that any owning sub-object remains valid until after we have
|
||||
// deallocated the memory here.
|
||||
Handler handler(BOOST_ASIO_MOVE_CAST(Handler)(o->handler_));
|
||||
p.reset();
|
||||
|
||||
// Make the upcall if required.
|
||||
if (owner)
|
||||
{
|
||||
fenced_block b(fenced_block::half);
|
||||
BOOST_ASIO_HANDLER_INVOCATION_BEGIN(());
|
||||
boost_asio_handler_invoke_helpers::invoke(handler, handler);
|
||||
BOOST_ASIO_HANDLER_INVOCATION_END;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
Alloc allocator_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_EXECUTOR_OP_HPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/fd_set_adapter.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/fenced_block.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
//
|
||||
// detail/function.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
// detail/functional.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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_DETAIL_FUNCTION_HPP
|
||||
#define BOOST_ASIO_DETAIL_FUNCTION_HPP
|
||||
#ifndef BOOST_ASIO_DETAIL_FUNCTIONAL_HPP
|
||||
#define BOOST_ASIO_DETAIL_FUNCTIONAL_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
@@ -17,11 +17,11 @@
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_STD_FUNCTION)
|
||||
# include <functional>
|
||||
#else // defined(BOOST_ASIO_HAS_STD_FUNCTION)
|
||||
#include <functional>
|
||||
|
||||
#if !defined(BOOST_ASIO_HAS_STD_FUNCTION)
|
||||
# include <boost/function.hpp>
|
||||
#endif // defined(BOOST_ASIO_HAS_STD_FUNCTION)
|
||||
#endif // !defined(BOOST_ASIO_HAS_STD_FUNCTION)
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
@@ -37,4 +37,4 @@ using boost::function;
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_FUNCTION_HPP
|
||||
#endif // BOOST_ASIO_DETAIL_FUNCTIONAL_HPP
|
||||
33
winx64/include/boost/asio/detail/future.hpp
Normal file
33
winx64/include/boost/asio/detail/future.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// detail/future.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_DETAIL_FUTURE_HPP
|
||||
#define BOOST_ASIO_DETAIL_FUTURE_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_STD_FUTURE)
|
||||
# include <future>
|
||||
// Even though the future header is available, libstdc++ may not implement the
|
||||
// std::future class itself. However, we need to have already included the
|
||||
// future header to reliably test for _GLIBCXX_HAS_GTHREADS.
|
||||
# if defined(__GNUC__) && !defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
|
||||
# if defined(_GLIBCXX_HAS_GTHREADS)
|
||||
# define BOOST_ASIO_HAS_STD_FUTURE_CLASS 1
|
||||
# endif // defined(_GLIBCXX_HAS_GTHREADS)
|
||||
# else // defined(__GNUC__) && !defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
|
||||
# define BOOST_ASIO_HAS_STD_FUTURE_CLASS 1
|
||||
# endif // defined(__GNUC__) && !defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
|
||||
#endif // defined(BOOST_ASIO_HAS_STD_FUTURE)
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_FUTURE_HPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/gcc_arm_fenced_block.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#if defined(__GNUC__) && defined(__arm__)
|
||||
|
||||
#include <boost/asio/detail/noncopyable.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/gcc_hppa_fenced_block.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#if defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))
|
||||
|
||||
#include <boost/asio/detail/noncopyable.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/gcc_sync_fenced_block.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -22,6 +22,8 @@
|
||||
&& !defined(__INTEL_COMPILER) && !defined(__ICL) \
|
||||
&& !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)
|
||||
|
||||
#include <boost/asio/detail/noncopyable.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/gcc_x86_fenced_block.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
|
||||
#include <boost/asio/detail/noncopyable.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
54
winx64/include/boost/asio/detail/global.hpp
Normal file
54
winx64/include/boost/asio/detail/global.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// detail/global.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_DETAIL_GLOBAL_HPP
|
||||
#define BOOST_ASIO_DETAIL_GLOBAL_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_THREADS)
|
||||
# include <boost/asio/detail/null_global.hpp>
|
||||
#elif defined(BOOST_ASIO_WINDOWS)
|
||||
# include <boost/asio/detail/win_global.hpp>
|
||||
#elif defined(BOOST_ASIO_HAS_PTHREADS)
|
||||
# include <boost/asio/detail/posix_global.hpp>
|
||||
#elif defined(BOOST_ASIO_HAS_STD_CALL_ONCE)
|
||||
# include <boost/asio/detail/std_global.hpp>
|
||||
#else
|
||||
# error Only Windows, POSIX and std::call_once are supported!
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
inline T& global()
|
||||
{
|
||||
#if !defined(BOOST_ASIO_HAS_THREADS)
|
||||
return null_global<T>();
|
||||
#elif defined(BOOST_ASIO_WINDOWS)
|
||||
return win_global<T>();
|
||||
#elif defined(BOOST_ASIO_HAS_PTHREADS)
|
||||
return posix_global<T>();
|
||||
#elif defined(BOOST_ASIO_HAS_STD_CALL_ONCE)
|
||||
return std_global<T>();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_GLOBAL_HPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/handler_alloc_helpers.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -16,8 +16,10 @@
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <boost/asio/detail/addressof.hpp>
|
||||
#include <boost/asio/detail/memory.hpp>
|
||||
#include <boost/asio/detail/noncopyable.hpp>
|
||||
#include <boost/asio/detail/recycling_allocator.hpp>
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/handler_alloc_hook.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
@@ -51,16 +53,123 @@ inline void deallocate(void* p, std::size_t s, Handler& h)
|
||||
|
||||
} // namespace boost_asio_handler_alloc_helpers
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
template <typename Handler, typename T>
|
||||
class hook_allocator
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
template <typename U>
|
||||
struct rebind
|
||||
{
|
||||
typedef hook_allocator<Handler, U> other;
|
||||
};
|
||||
|
||||
explicit hook_allocator(Handler& h)
|
||||
: handler_(h)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
hook_allocator(const hook_allocator<Handler, U>& a)
|
||||
: handler_(a.handler_)
|
||||
{
|
||||
}
|
||||
|
||||
T* allocate(std::size_t n)
|
||||
{
|
||||
return static_cast<T*>(
|
||||
boost_asio_handler_alloc_helpers::allocate(sizeof(T) * n, handler_));
|
||||
}
|
||||
|
||||
void deallocate(T* p, std::size_t n)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(p, sizeof(T) * n, handler_);
|
||||
}
|
||||
|
||||
//private:
|
||||
Handler& handler_;
|
||||
};
|
||||
|
||||
template <typename Handler>
|
||||
class hook_allocator<Handler, void>
|
||||
{
|
||||
public:
|
||||
typedef void value_type;
|
||||
|
||||
template <typename U>
|
||||
struct rebind
|
||||
{
|
||||
typedef hook_allocator<Handler, U> other;
|
||||
};
|
||||
|
||||
explicit hook_allocator(Handler& h)
|
||||
: handler_(h)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
hook_allocator(const hook_allocator<Handler, U>& a)
|
||||
: handler_(a.handler_)
|
||||
{
|
||||
}
|
||||
|
||||
//private:
|
||||
Handler& handler_;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Allocator>
|
||||
struct get_hook_allocator
|
||||
{
|
||||
typedef Allocator type;
|
||||
|
||||
static type get(Handler&, const Allocator& a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Handler, typename T>
|
||||
struct get_hook_allocator<Handler, std::allocator<T> >
|
||||
{
|
||||
typedef hook_allocator<Handler, T> type;
|
||||
|
||||
static type get(Handler& handler, const std::allocator<T>&)
|
||||
{
|
||||
return type(handler);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_ASIO_DEFINE_HANDLER_PTR(op) \
|
||||
struct ptr \
|
||||
{ \
|
||||
Handler* h; \
|
||||
void* v; \
|
||||
op* v; \
|
||||
op* p; \
|
||||
~ptr() \
|
||||
{ \
|
||||
reset(); \
|
||||
} \
|
||||
static op* allocate(Handler& handler) \
|
||||
{ \
|
||||
typedef typename ::boost::asio::associated_allocator< \
|
||||
Handler>::type associated_allocator_type; \
|
||||
typedef typename ::boost::asio::detail::get_hook_allocator< \
|
||||
Handler, associated_allocator_type>::type hook_allocator_type; \
|
||||
BOOST_ASIO_REBIND_ALLOC(hook_allocator_type, op) a( \
|
||||
::boost::asio::detail::get_hook_allocator< \
|
||||
Handler, associated_allocator_type>::get( \
|
||||
handler, ::boost::asio::get_associated_allocator(handler))); \
|
||||
return a.allocate(1); \
|
||||
} \
|
||||
void reset() \
|
||||
{ \
|
||||
if (p) \
|
||||
@@ -70,13 +179,66 @@ inline void deallocate(void* p, std::size_t s, Handler& h)
|
||||
} \
|
||||
if (v) \
|
||||
{ \
|
||||
boost_asio_handler_alloc_helpers::deallocate(v, sizeof(op), *h); \
|
||||
typedef typename ::boost::asio::associated_allocator< \
|
||||
Handler>::type associated_allocator_type; \
|
||||
typedef typename ::boost::asio::detail::get_hook_allocator< \
|
||||
Handler, associated_allocator_type>::type hook_allocator_type; \
|
||||
BOOST_ASIO_REBIND_ALLOC(hook_allocator_type, op) a( \
|
||||
::boost::asio::detail::get_hook_allocator< \
|
||||
Handler, associated_allocator_type>::get( \
|
||||
*h, ::boost::asio::get_associated_allocator(*h))); \
|
||||
a.deallocate(static_cast<op*>(v), 1); \
|
||||
v = 0; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
/**/
|
||||
|
||||
#define BOOST_ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR(purpose, op) \
|
||||
struct ptr \
|
||||
{ \
|
||||
const Alloc* a; \
|
||||
void* v; \
|
||||
op* p; \
|
||||
~ptr() \
|
||||
{ \
|
||||
reset(); \
|
||||
} \
|
||||
static op* allocate(const Alloc& a) \
|
||||
{ \
|
||||
typedef typename ::boost::asio::detail::get_recycling_allocator< \
|
||||
Alloc, purpose>::type recycling_allocator_type; \
|
||||
BOOST_ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \
|
||||
::boost::asio::detail::get_recycling_allocator< \
|
||||
Alloc, purpose>::get(a)); \
|
||||
return a1.allocate(1); \
|
||||
} \
|
||||
void reset() \
|
||||
{ \
|
||||
if (p) \
|
||||
{ \
|
||||
p->~op(); \
|
||||
p = 0; \
|
||||
} \
|
||||
if (v) \
|
||||
{ \
|
||||
typedef typename ::boost::asio::detail::get_recycling_allocator< \
|
||||
Alloc, purpose>::type recycling_allocator_type; \
|
||||
BOOST_ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \
|
||||
::boost::asio::detail::get_recycling_allocator< \
|
||||
Alloc, purpose>::get(*a)); \
|
||||
a1.deallocate(static_cast<op*>(v), 1); \
|
||||
v = 0; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
/**/
|
||||
|
||||
#define BOOST_ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(op) \
|
||||
BOOST_ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR( \
|
||||
::boost::asio::detail::thread_info_base::default_tag, op ) \
|
||||
/**/
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/handler_cont_helpers.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -16,7 +16,7 @@
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <boost/asio/detail/addressof.hpp>
|
||||
#include <boost/asio/detail/memory.hpp>
|
||||
#include <boost/asio/handler_continuation_hook.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/handler_invoke_helpers.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -16,7 +16,7 @@
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <boost/asio/detail/addressof.hpp>
|
||||
#include <boost/asio/detail/memory.hpp>
|
||||
#include <boost/asio/handler_invoke_hook.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/handler_tracking.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -17,7 +17,17 @@
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
class execution_context;
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#if defined(BOOST_ASIO_CUSTOM_HANDLER_TRACKING)
|
||||
# include BOOST_ASIO_CUSTOM_HANDLER_TRACKING
|
||||
#elif defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
# include <boost/system/error_code.hpp>
|
||||
# include <boost/asio/detail/cstdint.hpp>
|
||||
# include <boost/asio/detail/static_mutex.hpp>
|
||||
@@ -30,7 +40,30 @@ namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
#if defined(BOOST_ASIO_CUSTOM_HANDLER_TRACKING)
|
||||
|
||||
// The user-specified header must define the following macros:
|
||||
// - BOOST_ASIO_INHERIT_TRACKED_HANDLER
|
||||
// - BOOST_ASIO_ALSO_INHERIT_TRACKED_HANDLER
|
||||
// - BOOST_ASIO_HANDLER_TRACKING_INIT
|
||||
// - BOOST_ASIO_HANDLER_CREATION(args)
|
||||
// - BOOST_ASIO_HANDLER_COMPLETION(args)
|
||||
// - BOOST_ASIO_HANDLER_INVOCATION_BEGIN(args)
|
||||
// - BOOST_ASIO_HANDLER_INVOCATION_END
|
||||
// - BOOST_ASIO_HANDLER_OPERATION(args)
|
||||
// - BOOST_ASIO_HANDLER_REACTOR_REGISTRATION(args)
|
||||
// - BOOST_ASIO_HANDLER_REACTOR_DEREGISTRATION(args)
|
||||
// - BOOST_ASIO_HANDLER_REACTOR_READ_EVENT
|
||||
// - BOOST_ASIO_HANDLER_REACTOR_WRITE_EVENT
|
||||
// - BOOST_ASIO_HANDLER_REACTOR_ERROR_EVENT
|
||||
// - BOOST_ASIO_HANDLER_REACTOR_EVENTS(args)
|
||||
// - BOOST_ASIO_HANDLER_REACTOR_OPERATION(args)
|
||||
|
||||
# if !defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
# define BOOST_ASIO_ENABLE_HANDLER_TRACKING 1
|
||||
# endif /// !defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
|
||||
#elif defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
|
||||
class handler_tracking
|
||||
{
|
||||
@@ -58,14 +91,16 @@ public:
|
||||
BOOST_ASIO_DECL static void init();
|
||||
|
||||
// Record the creation of a tracked handler.
|
||||
BOOST_ASIO_DECL static void creation(tracked_handler* h,
|
||||
const char* object_type, void* object, const char* op_name);
|
||||
BOOST_ASIO_DECL static void creation(
|
||||
execution_context& context, tracked_handler& h,
|
||||
const char* object_type, void* object,
|
||||
uintmax_t native_handle, const char* op_name);
|
||||
|
||||
class completion
|
||||
{
|
||||
public:
|
||||
// Constructor records that handler is to be invoked with no arguments.
|
||||
BOOST_ASIO_DECL explicit completion(tracked_handler* h);
|
||||
BOOST_ASIO_DECL explicit completion(const tracked_handler& h);
|
||||
|
||||
// Destructor records only when an exception is thrown from the handler, or
|
||||
// if the memory is being freed without the handler having been invoked.
|
||||
@@ -99,9 +134,32 @@ public:
|
||||
completion* next_;
|
||||
};
|
||||
|
||||
// Record an operation that affects pending handlers.
|
||||
BOOST_ASIO_DECL static void operation(const char* object_type,
|
||||
void* object, const char* op_name);
|
||||
// Record an operation that is not directly associated with a handler.
|
||||
BOOST_ASIO_DECL static void operation(execution_context& context,
|
||||
const char* object_type, void* object,
|
||||
uintmax_t native_handle, const char* op_name);
|
||||
|
||||
// Record that a descriptor has been registered with the reactor.
|
||||
BOOST_ASIO_DECL static void reactor_registration(execution_context& context,
|
||||
uintmax_t native_handle, uintmax_t registration);
|
||||
|
||||
// Record that a descriptor has been deregistered from the reactor.
|
||||
BOOST_ASIO_DECL static void reactor_deregistration(execution_context& context,
|
||||
uintmax_t native_handle, uintmax_t registration);
|
||||
|
||||
// Record a reactor-based operation that is associated with a handler.
|
||||
BOOST_ASIO_DECL static void reactor_events(execution_context& context,
|
||||
uintmax_t registration, unsigned events);
|
||||
|
||||
// Record a reactor-based operation that is associated with a handler.
|
||||
BOOST_ASIO_DECL static void reactor_operation(
|
||||
const tracked_handler& h, const char* op_name,
|
||||
const boost::system::error_code& ec);
|
||||
|
||||
// Record a reactor-based operation that is associated with a handler.
|
||||
BOOST_ASIO_DECL static void reactor_operation(
|
||||
const tracked_handler& h, const char* op_name,
|
||||
const boost::system::error_code& ec, std::size_t bytes_transferred);
|
||||
|
||||
// Write a line of output.
|
||||
BOOST_ASIO_DECL static void write_line(const char* format, ...);
|
||||
@@ -135,6 +193,22 @@ private:
|
||||
# define BOOST_ASIO_HANDLER_OPERATION(args) \
|
||||
boost::asio::detail::handler_tracking::operation args
|
||||
|
||||
# define BOOST_ASIO_HANDLER_REACTOR_REGISTRATION(args) \
|
||||
boost::asio::detail::handler_tracking::reactor_registration args
|
||||
|
||||
# define BOOST_ASIO_HANDLER_REACTOR_DEREGISTRATION(args) \
|
||||
boost::asio::detail::handler_tracking::reactor_deregistration args
|
||||
|
||||
# define BOOST_ASIO_HANDLER_REACTOR_READ_EVENT 1
|
||||
# define BOOST_ASIO_HANDLER_REACTOR_WRITE_EVENT 2
|
||||
# define BOOST_ASIO_HANDLER_REACTOR_ERROR_EVENT 4
|
||||
|
||||
# define BOOST_ASIO_HANDLER_REACTOR_EVENTS(args) \
|
||||
boost::asio::detail::handler_tracking::reactor_events args
|
||||
|
||||
# define BOOST_ASIO_HANDLER_REACTOR_OPERATION(args) \
|
||||
boost::asio::detail::handler_tracking::reactor_operation args
|
||||
|
||||
#else // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
|
||||
# define BOOST_ASIO_INHERIT_TRACKED_HANDLER
|
||||
@@ -145,6 +219,13 @@ private:
|
||||
# define BOOST_ASIO_HANDLER_INVOCATION_BEGIN(args) (void)0
|
||||
# define BOOST_ASIO_HANDLER_INVOCATION_END (void)0
|
||||
# define BOOST_ASIO_HANDLER_OPERATION(args) (void)0
|
||||
# define BOOST_ASIO_HANDLER_REACTOR_REGISTRATION(args) (void)0
|
||||
# define BOOST_ASIO_HANDLER_REACTOR_DEREGISTRATION(args) (void)0
|
||||
# define BOOST_ASIO_HANDLER_REACTOR_READ_EVENT 0
|
||||
# define BOOST_ASIO_HANDLER_REACTOR_WRITE_EVENT 0
|
||||
# define BOOST_ASIO_HANDLER_REACTOR_ERROR_EVENT 0
|
||||
# define BOOST_ASIO_HANDLER_REACTOR_EVENTS(args) (void)0
|
||||
# define BOOST_ASIO_HANDLER_REACTOR_OPERATION(args) (void)0
|
||||
|
||||
#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/handler_type_requirements.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -50,7 +50,7 @@
|
||||
#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS)
|
||||
|
||||
#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
|
||||
# include <boost/asio/handler_type.hpp>
|
||||
# include <boost/asio/async_result.hpp>
|
||||
#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
|
||||
|
||||
namespace boost {
|
||||
@@ -62,19 +62,19 @@ namespace detail {
|
||||
# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT)
|
||||
|
||||
template <typename Handler>
|
||||
auto zero_arg_handler_test(Handler h, void*)
|
||||
auto zero_arg_copyable_handler_test(Handler h, void*)
|
||||
-> decltype(
|
||||
sizeof(Handler(static_cast<const Handler&>(h))),
|
||||
((h)()),
|
||||
char(0));
|
||||
|
||||
template <typename Handler>
|
||||
char (&zero_arg_handler_test(Handler, ...))[2];
|
||||
char (&zero_arg_copyable_handler_test(Handler, ...))[2];
|
||||
|
||||
template <typename Handler, typename Arg1>
|
||||
auto one_arg_handler_test(Handler h, Arg1* a1)
|
||||
-> decltype(
|
||||
sizeof(Handler(static_cast<const Handler&>(h))),
|
||||
sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
|
||||
((h)(*a1)),
|
||||
char(0));
|
||||
|
||||
@@ -84,13 +84,23 @@ char (&one_arg_handler_test(Handler h, ...))[2];
|
||||
template <typename Handler, typename Arg1, typename Arg2>
|
||||
auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2)
|
||||
-> decltype(
|
||||
sizeof(Handler(static_cast<const Handler&>(h))),
|
||||
sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
|
||||
((h)(*a1, *a2)),
|
||||
char(0));
|
||||
|
||||
template <typename Handler>
|
||||
char (&two_arg_handler_test(Handler, ...))[2];
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2>
|
||||
auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2)
|
||||
-> decltype(
|
||||
sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
|
||||
((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))),
|
||||
char(0));
|
||||
|
||||
template <typename Handler>
|
||||
char (&two_arg_move_handler_test(Handler, ...))[2];
|
||||
|
||||
# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \
|
||||
static_assert(expr, msg);
|
||||
|
||||
@@ -104,21 +114,28 @@ template <typename T> T& lvref();
|
||||
template <typename T> T& lvref(T);
|
||||
template <typename T> const T& clvref();
|
||||
template <typename T> const T& clvref(T);
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
template <typename T> T rvref();
|
||||
template <typename T> T rvref(T);
|
||||
#else // defined(BOOST_ASIO_HAS_MOVE)
|
||||
template <typename T> const T& rvref();
|
||||
template <typename T> const T& rvref(T);
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
template <typename T> char argbyv(T);
|
||||
|
||||
template <size_t>
|
||||
template <int>
|
||||
struct handler_type_requirements
|
||||
{
|
||||
};
|
||||
|
||||
#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \
|
||||
#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \
|
||||
handler_type, handler) \
|
||||
\
|
||||
typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
|
||||
void()) asio_true_handler_type; \
|
||||
\
|
||||
BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
|
||||
sizeof(boost::asio::detail::zero_arg_handler_test( \
|
||||
sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \
|
||||
boost::asio::detail::clvref< \
|
||||
asio_true_handler_type>(), 0)) == 1, \
|
||||
"CompletionHandler type requirements not met") \
|
||||
@@ -142,7 +159,7 @@ struct handler_type_requirements
|
||||
\
|
||||
BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
|
||||
sizeof(boost::asio::detail::two_arg_handler_test( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>(), \
|
||||
static_cast<const boost::system::error_code*>(0), \
|
||||
static_cast<const std::size_t*>(0))) == 1, \
|
||||
@@ -151,7 +168,7 @@ struct handler_type_requirements
|
||||
typedef boost::asio::detail::handler_type_requirements< \
|
||||
sizeof( \
|
||||
boost::asio::detail::argbyv( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>())) + \
|
||||
sizeof( \
|
||||
boost::asio::detail::lvref< \
|
||||
@@ -160,7 +177,6 @@ struct handler_type_requirements
|
||||
boost::asio::detail::lvref<const std::size_t>()), \
|
||||
char(0))> BOOST_ASIO_UNUSED_TYPEDEF
|
||||
|
||||
|
||||
#define BOOST_ASIO_WRITE_HANDLER_CHECK( \
|
||||
handler_type, handler) \
|
||||
\
|
||||
@@ -170,7 +186,7 @@ struct handler_type_requirements
|
||||
\
|
||||
BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
|
||||
sizeof(boost::asio::detail::two_arg_handler_test( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>(), \
|
||||
static_cast<const boost::system::error_code*>(0), \
|
||||
static_cast<const std::size_t*>(0))) == 1, \
|
||||
@@ -179,7 +195,7 @@ struct handler_type_requirements
|
||||
typedef boost::asio::detail::handler_type_requirements< \
|
||||
sizeof( \
|
||||
boost::asio::detail::argbyv( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>())) + \
|
||||
sizeof( \
|
||||
boost::asio::detail::lvref< \
|
||||
@@ -197,7 +213,7 @@ struct handler_type_requirements
|
||||
\
|
||||
BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
|
||||
sizeof(boost::asio::detail::one_arg_handler_test( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>(), \
|
||||
static_cast<const boost::system::error_code*>(0))) == 1, \
|
||||
"AcceptHandler type requirements not met") \
|
||||
@@ -205,7 +221,7 @@ struct handler_type_requirements
|
||||
typedef boost::asio::detail::handler_type_requirements< \
|
||||
sizeof( \
|
||||
boost::asio::detail::argbyv( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>())) + \
|
||||
sizeof( \
|
||||
boost::asio::detail::lvref< \
|
||||
@@ -213,6 +229,33 @@ struct handler_type_requirements
|
||||
boost::asio::detail::lvref<const boost::system::error_code>()), \
|
||||
char(0))> BOOST_ASIO_UNUSED_TYPEDEF
|
||||
|
||||
#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \
|
||||
handler_type, handler, socket_type) \
|
||||
\
|
||||
typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
|
||||
void(boost::system::error_code, socket_type)) \
|
||||
asio_true_handler_type; \
|
||||
\
|
||||
BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
|
||||
sizeof(boost::asio::detail::two_arg_move_handler_test( \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>(), \
|
||||
static_cast<const boost::system::error_code*>(0), \
|
||||
static_cast<socket_type*>(0))) == 1, \
|
||||
"MoveAcceptHandler type requirements not met") \
|
||||
\
|
||||
typedef boost::asio::detail::handler_type_requirements< \
|
||||
sizeof( \
|
||||
boost::asio::detail::argbyv( \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>())) + \
|
||||
sizeof( \
|
||||
boost::asio::detail::lvref< \
|
||||
asio_true_handler_type>()( \
|
||||
boost::asio::detail::lvref<const boost::system::error_code>(), \
|
||||
boost::asio::detail::rvref<socket_type>()), \
|
||||
char(0))> BOOST_ASIO_UNUSED_TYPEDEF
|
||||
|
||||
#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \
|
||||
handler_type, handler) \
|
||||
\
|
||||
@@ -222,7 +265,7 @@ struct handler_type_requirements
|
||||
\
|
||||
BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
|
||||
sizeof(boost::asio::detail::one_arg_handler_test( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>(), \
|
||||
static_cast<const boost::system::error_code*>(0))) == 1, \
|
||||
"ConnectHandler type requirements not met") \
|
||||
@@ -230,7 +273,7 @@ struct handler_type_requirements
|
||||
typedef boost::asio::detail::handler_type_requirements< \
|
||||
sizeof( \
|
||||
boost::asio::detail::argbyv( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>())) + \
|
||||
sizeof( \
|
||||
boost::asio::detail::lvref< \
|
||||
@@ -238,7 +281,34 @@ struct handler_type_requirements
|
||||
boost::asio::detail::lvref<const boost::system::error_code>()), \
|
||||
char(0))> BOOST_ASIO_UNUSED_TYPEDEF
|
||||
|
||||
#define BOOST_ASIO_COMPOSED_CONNECT_HANDLER_CHECK( \
|
||||
#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \
|
||||
handler_type, handler, endpoint_type) \
|
||||
\
|
||||
typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
|
||||
void(boost::system::error_code, endpoint_type)) \
|
||||
asio_true_handler_type; \
|
||||
\
|
||||
BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
|
||||
sizeof(boost::asio::detail::two_arg_handler_test( \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>(), \
|
||||
static_cast<const boost::system::error_code*>(0), \
|
||||
static_cast<const endpoint_type*>(0))) == 1, \
|
||||
"RangeConnectHandler type requirements not met") \
|
||||
\
|
||||
typedef boost::asio::detail::handler_type_requirements< \
|
||||
sizeof( \
|
||||
boost::asio::detail::argbyv( \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>())) + \
|
||||
sizeof( \
|
||||
boost::asio::detail::lvref< \
|
||||
asio_true_handler_type>()( \
|
||||
boost::asio::detail::lvref<const boost::system::error_code>(), \
|
||||
boost::asio::detail::lvref<const endpoint_type>()), \
|
||||
char(0))> BOOST_ASIO_UNUSED_TYPEDEF
|
||||
|
||||
#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \
|
||||
handler_type, handler, iter_type) \
|
||||
\
|
||||
typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
|
||||
@@ -247,16 +317,16 @@ struct handler_type_requirements
|
||||
\
|
||||
BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
|
||||
sizeof(boost::asio::detail::two_arg_handler_test( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>(), \
|
||||
static_cast<const boost::system::error_code*>(0), \
|
||||
static_cast<const iter_type*>(0))) == 1, \
|
||||
"ComposedConnectHandler type requirements not met") \
|
||||
"IteratorConnectHandler type requirements not met") \
|
||||
\
|
||||
typedef boost::asio::detail::handler_type_requirements< \
|
||||
sizeof( \
|
||||
boost::asio::detail::argbyv( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>())) + \
|
||||
sizeof( \
|
||||
boost::asio::detail::lvref< \
|
||||
@@ -266,30 +336,30 @@ struct handler_type_requirements
|
||||
char(0))> BOOST_ASIO_UNUSED_TYPEDEF
|
||||
|
||||
#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \
|
||||
handler_type, handler, iter_type) \
|
||||
handler_type, handler, range_type) \
|
||||
\
|
||||
typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
|
||||
void(boost::system::error_code, iter_type)) \
|
||||
void(boost::system::error_code, range_type)) \
|
||||
asio_true_handler_type; \
|
||||
\
|
||||
BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
|
||||
sizeof(boost::asio::detail::two_arg_handler_test( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>(), \
|
||||
static_cast<const boost::system::error_code*>(0), \
|
||||
static_cast<const iter_type*>(0))) == 1, \
|
||||
static_cast<const range_type*>(0))) == 1, \
|
||||
"ResolveHandler type requirements not met") \
|
||||
\
|
||||
typedef boost::asio::detail::handler_type_requirements< \
|
||||
sizeof( \
|
||||
boost::asio::detail::argbyv( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>())) + \
|
||||
sizeof( \
|
||||
boost::asio::detail::lvref< \
|
||||
asio_true_handler_type>()( \
|
||||
boost::asio::detail::lvref<const boost::system::error_code>(), \
|
||||
boost::asio::detail::lvref<const iter_type>()), \
|
||||
boost::asio::detail::lvref<const range_type>()), \
|
||||
char(0))> BOOST_ASIO_UNUSED_TYPEDEF
|
||||
|
||||
#define BOOST_ASIO_WAIT_HANDLER_CHECK( \
|
||||
@@ -301,7 +371,7 @@ struct handler_type_requirements
|
||||
\
|
||||
BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
|
||||
sizeof(boost::asio::detail::one_arg_handler_test( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>(), \
|
||||
static_cast<const boost::system::error_code*>(0))) == 1, \
|
||||
"WaitHandler type requirements not met") \
|
||||
@@ -309,7 +379,7 @@ struct handler_type_requirements
|
||||
typedef boost::asio::detail::handler_type_requirements< \
|
||||
sizeof( \
|
||||
boost::asio::detail::argbyv( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>())) + \
|
||||
sizeof( \
|
||||
boost::asio::detail::lvref< \
|
||||
@@ -326,7 +396,7 @@ struct handler_type_requirements
|
||||
\
|
||||
BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
|
||||
sizeof(boost::asio::detail::two_arg_handler_test( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>(), \
|
||||
static_cast<const boost::system::error_code*>(0), \
|
||||
static_cast<const int*>(0))) == 1, \
|
||||
@@ -335,7 +405,7 @@ struct handler_type_requirements
|
||||
typedef boost::asio::detail::handler_type_requirements< \
|
||||
sizeof( \
|
||||
boost::asio::detail::argbyv( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>())) + \
|
||||
sizeof( \
|
||||
boost::asio::detail::lvref< \
|
||||
@@ -353,7 +423,7 @@ struct handler_type_requirements
|
||||
\
|
||||
BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
|
||||
sizeof(boost::asio::detail::one_arg_handler_test( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>(), \
|
||||
static_cast<const boost::system::error_code*>(0))) == 1, \
|
||||
"HandshakeHandler type requirements not met") \
|
||||
@@ -361,7 +431,7 @@ struct handler_type_requirements
|
||||
typedef boost::asio::detail::handler_type_requirements< \
|
||||
sizeof( \
|
||||
boost::asio::detail::argbyv( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>())) + \
|
||||
sizeof( \
|
||||
boost::asio::detail::lvref< \
|
||||
@@ -378,7 +448,7 @@ struct handler_type_requirements
|
||||
\
|
||||
BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
|
||||
sizeof(boost::asio::detail::two_arg_handler_test( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>(), \
|
||||
static_cast<const boost::system::error_code*>(0), \
|
||||
static_cast<const std::size_t*>(0))) == 1, \
|
||||
@@ -387,7 +457,7 @@ struct handler_type_requirements
|
||||
typedef boost::asio::detail::handler_type_requirements< \
|
||||
sizeof( \
|
||||
boost::asio::detail::argbyv( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>())) + \
|
||||
sizeof( \
|
||||
boost::asio::detail::lvref< \
|
||||
@@ -405,7 +475,7 @@ struct handler_type_requirements
|
||||
\
|
||||
BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
|
||||
sizeof(boost::asio::detail::one_arg_handler_test( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>(), \
|
||||
static_cast<const boost::system::error_code*>(0))) == 1, \
|
||||
"ShutdownHandler type requirements not met") \
|
||||
@@ -413,7 +483,7 @@ struct handler_type_requirements
|
||||
typedef boost::asio::detail::handler_type_requirements< \
|
||||
sizeof( \
|
||||
boost::asio::detail::argbyv( \
|
||||
boost::asio::detail::clvref< \
|
||||
boost::asio::detail::rvref< \
|
||||
asio_true_handler_type>())) + \
|
||||
sizeof( \
|
||||
boost::asio::detail::lvref< \
|
||||
@@ -423,7 +493,7 @@ struct handler_type_requirements
|
||||
|
||||
#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
|
||||
|
||||
#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \
|
||||
#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \
|
||||
handler_type, handler) \
|
||||
typedef int BOOST_ASIO_UNUSED_TYPEDEF
|
||||
|
||||
@@ -439,11 +509,19 @@ struct handler_type_requirements
|
||||
handler_type, handler) \
|
||||
typedef int BOOST_ASIO_UNUSED_TYPEDEF
|
||||
|
||||
#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \
|
||||
handler_type, handler, socket_type) \
|
||||
typedef int BOOST_ASIO_UNUSED_TYPEDEF
|
||||
|
||||
#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \
|
||||
handler_type, handler) \
|
||||
typedef int BOOST_ASIO_UNUSED_TYPEDEF
|
||||
|
||||
#define BOOST_ASIO_COMPOSED_CONNECT_HANDLER_CHECK( \
|
||||
#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \
|
||||
handler_type, handler, iter_type) \
|
||||
typedef int BOOST_ASIO_UNUSED_TYPEDEF
|
||||
|
||||
#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \
|
||||
handler_type, handler, iter_type) \
|
||||
typedef int BOOST_ASIO_UNUSED_TYPEDEF
|
||||
|
||||
|
||||
115
winx64/include/boost/asio/detail/handler_work.hpp
Normal file
115
winx64/include/boost/asio/detail/handler_work.hpp
Normal file
@@ -0,0 +1,115 @@
|
||||
//
|
||||
// detail/handler_work.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_DETAIL_HANDLER_WORK_HPP
|
||||
#define BOOST_ASIO_DETAIL_HANDLER_WORK_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_executor.hpp>
|
||||
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
// A helper class template to allow completion handlers to be dispatched
|
||||
// through either the new executors framework or the old invocaton hook. The
|
||||
// primary template uses the new executors framework.
|
||||
template <typename Handler,
|
||||
typename IoExecutor = system_executor, typename HandlerExecutor
|
||||
= typename associated_executor<Handler, IoExecutor>::type>
|
||||
class handler_work
|
||||
{
|
||||
public:
|
||||
explicit handler_work(Handler& handler) BOOST_ASIO_NOEXCEPT
|
||||
: io_executor_(),
|
||||
executor_(boost::asio::get_associated_executor(handler, io_executor_))
|
||||
{
|
||||
}
|
||||
|
||||
handler_work(Handler& handler, const IoExecutor& io_ex) BOOST_ASIO_NOEXCEPT
|
||||
: io_executor_(io_ex),
|
||||
executor_(boost::asio::get_associated_executor(handler, io_executor_))
|
||||
{
|
||||
}
|
||||
|
||||
static void start(Handler& handler) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
HandlerExecutor ex(boost::asio::get_associated_executor(handler));
|
||||
ex.on_work_started();
|
||||
}
|
||||
|
||||
static void start(Handler& handler,
|
||||
const IoExecutor& io_ex) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
HandlerExecutor ex(boost::asio::get_associated_executor(handler, io_ex));
|
||||
ex.on_work_started();
|
||||
io_ex.on_work_started();
|
||||
}
|
||||
|
||||
~handler_work()
|
||||
{
|
||||
io_executor_.on_work_finished();
|
||||
executor_.on_work_finished();
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
void complete(Function& function, Handler& handler)
|
||||
{
|
||||
executor_.dispatch(BOOST_ASIO_MOVE_CAST(Function)(function),
|
||||
boost::asio::get_associated_allocator(handler));
|
||||
}
|
||||
|
||||
private:
|
||||
// Disallow copying and assignment.
|
||||
handler_work(const handler_work&);
|
||||
handler_work& operator=(const handler_work&);
|
||||
|
||||
IoExecutor io_executor_;
|
||||
HandlerExecutor executor_;
|
||||
};
|
||||
|
||||
// This specialisation dispatches a handler through the old invocation hook.
|
||||
// The specialisation is not strictly required for correctness, as the
|
||||
// system_executor will dispatch through the hook anyway. However, by doing
|
||||
// this we avoid an extra copy of the handler.
|
||||
template <typename Handler>
|
||||
class handler_work<Handler, system_executor, system_executor>
|
||||
{
|
||||
public:
|
||||
explicit handler_work(Handler&) BOOST_ASIO_NOEXCEPT {}
|
||||
static void start(Handler&) BOOST_ASIO_NOEXCEPT {}
|
||||
~handler_work() {}
|
||||
|
||||
template <typename Function>
|
||||
void complete(Function& function, Handler& handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(function, handler);
|
||||
}
|
||||
|
||||
private:
|
||||
// Disallow copying and assignment.
|
||||
handler_work(const handler_work&);
|
||||
handler_work& operator=(const handler_work&);
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_HANDLER_WORK_HPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/hash_map.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/impl/buffer_sequence_adapter.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -40,16 +40,16 @@ class winrt_buffer_impl :
|
||||
public:
|
||||
explicit winrt_buffer_impl(const boost::asio::const_buffer& b)
|
||||
{
|
||||
bytes_ = const_cast<byte*>(boost::asio::buffer_cast<const byte*>(b));
|
||||
length_ = boost::asio::buffer_size(b);
|
||||
capacity_ = boost::asio::buffer_size(b);
|
||||
bytes_ = const_cast<byte*>(static_cast<const byte*>(b.data()));
|
||||
length_ = b.size();
|
||||
capacity_ = b.size();
|
||||
}
|
||||
|
||||
explicit winrt_buffer_impl(const boost::asio::mutable_buffer& b)
|
||||
{
|
||||
bytes_ = const_cast<byte*>(boost::asio::buffer_cast<const byte*>(b));
|
||||
bytes_ = static_cast<byte*>(b.data());
|
||||
length_ = 0;
|
||||
capacity_ = boost::asio::buffer_size(b);
|
||||
capacity_ = b.size();
|
||||
}
|
||||
|
||||
~winrt_buffer_impl()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/impl/descriptor_ops.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -439,6 +439,29 @@ int poll_write(int d, state_type state, boost::system::error_code& ec)
|
||||
return result;
|
||||
}
|
||||
|
||||
int poll_error(int d, state_type state, boost::system::error_code& ec)
|
||||
{
|
||||
if (d == -1)
|
||||
{
|
||||
ec = boost::asio::error::bad_descriptor;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pollfd fds;
|
||||
fds.fd = d;
|
||||
fds.events = POLLPRI | POLLERR | POLLHUP;
|
||||
fds.revents = 0;
|
||||
int timeout = (state & user_set_non_blocking) ? 0 : -1;
|
||||
errno = 0;
|
||||
int result = error_wrapper(::poll(&fds, 1, timeout), ec);
|
||||
if (result == 0)
|
||||
ec = (state & user_set_non_blocking)
|
||||
? boost::asio::error::would_block : boost::system::error_code();
|
||||
else if (result > 0)
|
||||
ec = boost::system::error_code();
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace descriptor_ops
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/impl/dev_poll_reactor.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -46,12 +46,12 @@ void dev_poll_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
|
||||
|
||||
if (shutdown_)
|
||||
{
|
||||
io_service_.post_immediate_completion(op, false);
|
||||
scheduler_.post_immediate_completion(op, false);
|
||||
return;
|
||||
}
|
||||
|
||||
bool earliest = queue.enqueue_timer(time, timer, op);
|
||||
io_service_.work_started();
|
||||
scheduler_.work_started();
|
||||
if (earliest)
|
||||
interrupter_.interrupt();
|
||||
}
|
||||
@@ -65,10 +65,23 @@ std::size_t dev_poll_reactor::cancel_timer(timer_queue<Time_Traits>& queue,
|
||||
op_queue<operation> ops;
|
||||
std::size_t n = queue.cancel_timer(timer, ops, max_cancelled);
|
||||
lock.unlock();
|
||||
io_service_.post_deferred_completions(ops);
|
||||
scheduler_.post_deferred_completions(ops);
|
||||
return n;
|
||||
}
|
||||
|
||||
template <typename Time_Traits>
|
||||
void dev_poll_reactor::move_timer(timer_queue<Time_Traits>& queue,
|
||||
typename timer_queue<Time_Traits>::per_timer_data& target,
|
||||
typename timer_queue<Time_Traits>::per_timer_data& source)
|
||||
{
|
||||
boost::asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
op_queue<operation> ops;
|
||||
queue.cancel_timer(target, ops);
|
||||
queue.move_timer(target, source);
|
||||
lock.unlock();
|
||||
scheduler_.post_deferred_completions(ops);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/impl/dev_poll_reactor.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -30,9 +30,9 @@ namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
dev_poll_reactor::dev_poll_reactor(boost::asio::io_service& io_service)
|
||||
: boost::asio::detail::service_base<dev_poll_reactor>(io_service),
|
||||
io_service_(use_service<io_service_impl>(io_service)),
|
||||
dev_poll_reactor::dev_poll_reactor(boost::asio::execution_context& ctx)
|
||||
: boost::asio::detail::execution_context_service_base<dev_poll_reactor>(ctx),
|
||||
scheduler_(use_service<scheduler>(ctx)),
|
||||
mutex_(),
|
||||
dev_poll_fd_(do_dev_poll_create()),
|
||||
interrupter_(),
|
||||
@@ -48,11 +48,11 @@ dev_poll_reactor::dev_poll_reactor(boost::asio::io_service& io_service)
|
||||
|
||||
dev_poll_reactor::~dev_poll_reactor()
|
||||
{
|
||||
shutdown_service();
|
||||
shutdown();
|
||||
::close(dev_poll_fd_);
|
||||
}
|
||||
|
||||
void dev_poll_reactor::shutdown_service()
|
||||
void dev_poll_reactor::shutdown()
|
||||
{
|
||||
boost::asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
shutdown_ = true;
|
||||
@@ -65,12 +65,13 @@ void dev_poll_reactor::shutdown_service()
|
||||
|
||||
timer_queues_.get_all_timers(ops);
|
||||
|
||||
io_service_.abandon_operations(ops);
|
||||
scheduler_.abandon_operations(ops);
|
||||
}
|
||||
|
||||
void dev_poll_reactor::fork_service(boost::asio::io_service::fork_event fork_ev)
|
||||
void dev_poll_reactor::notify_fork(
|
||||
boost::asio::execution_context::fork_event fork_ev)
|
||||
{
|
||||
if (fork_ev == boost::asio::io_service::fork_child)
|
||||
if (fork_ev == boost::asio::execution_context::fork_child)
|
||||
{
|
||||
detail::mutex::scoped_lock lock(mutex_);
|
||||
|
||||
@@ -113,7 +114,7 @@ void dev_poll_reactor::fork_service(boost::asio::io_service::fork_event fork_ev)
|
||||
|
||||
void dev_poll_reactor::init_task()
|
||||
{
|
||||
io_service_.init_task();
|
||||
scheduler_.init_task();
|
||||
}
|
||||
|
||||
int dev_poll_reactor::register_descriptor(socket_type, per_descriptor_data&)
|
||||
@@ -168,7 +169,7 @@ void dev_poll_reactor::start_op(int op_type, socket_type descriptor,
|
||||
if (op->perform())
|
||||
{
|
||||
lock.unlock();
|
||||
io_service_.post_immediate_completion(op, is_continuation);
|
||||
scheduler_.post_immediate_completion(op, is_continuation);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -176,7 +177,7 @@ void dev_poll_reactor::start_op(int op_type, socket_type descriptor,
|
||||
}
|
||||
|
||||
bool first = op_queue_[op_type].enqueue_operation(descriptor, op);
|
||||
io_service_.work_started();
|
||||
scheduler_.work_started();
|
||||
if (first)
|
||||
{
|
||||
::pollfd& ev = add_pending_event_change(descriptor);
|
||||
@@ -235,13 +236,18 @@ void dev_poll_reactor::deregister_internal_descriptor(
|
||||
op_queue_[i].cancel_operations(descriptor, ops, ec);
|
||||
}
|
||||
|
||||
void dev_poll_reactor::run(bool block, op_queue<operation>& ops)
|
||||
void dev_poll_reactor::cleanup_descriptor_data(
|
||||
dev_poll_reactor::per_descriptor_data&)
|
||||
{
|
||||
}
|
||||
|
||||
void dev_poll_reactor::run(long usec, op_queue<operation>& ops)
|
||||
{
|
||||
boost::asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
|
||||
// We can return immediately if there's no work to do and the reactor is
|
||||
// not supposed to block.
|
||||
if (!block && op_queue_[read_op].empty() && op_queue_[write_op].empty()
|
||||
if (usec == 0 && op_queue_[read_op].empty() && op_queue_[write_op].empty()
|
||||
&& op_queue_[except_op].empty() && timer_queues_.all_empty())
|
||||
return;
|
||||
|
||||
@@ -267,7 +273,15 @@ void dev_poll_reactor::run(bool block, op_queue<operation>& ops)
|
||||
pending_event_change_index_.clear();
|
||||
}
|
||||
|
||||
int timeout = block ? get_timeout() : 0;
|
||||
// Calculate timeout.
|
||||
int timeout;
|
||||
if (usec == 0)
|
||||
timeout = 0;
|
||||
else
|
||||
{
|
||||
timeout = (usec < 0) ? -1 : ((usec - 1) / 1000 + 1);
|
||||
timeout = get_timeout(timeout);
|
||||
}
|
||||
lock.unlock();
|
||||
|
||||
// Block on the /dev/poll descriptor.
|
||||
@@ -381,11 +395,13 @@ void dev_poll_reactor::do_remove_timer_queue(timer_queue_base& queue)
|
||||
timer_queues_.erase(&queue);
|
||||
}
|
||||
|
||||
int dev_poll_reactor::get_timeout()
|
||||
int dev_poll_reactor::get_timeout(int msec)
|
||||
{
|
||||
// By default we will wait no longer than 5 minutes. This will ensure that
|
||||
// any changes to the system clock are detected after no longer than this.
|
||||
return timer_queues_.wait_duration_msec(5 * 60 * 1000);
|
||||
const int max_msec = 5 * 60 * 1000;
|
||||
return timer_queues_.wait_duration_msec(
|
||||
(msec < 0 || max_msec < msec) ? max_msec : msec);
|
||||
}
|
||||
|
||||
void dev_poll_reactor::cancel_ops_unlocked(socket_type descriptor,
|
||||
@@ -396,7 +412,7 @@ void dev_poll_reactor::cancel_ops_unlocked(socket_type descriptor,
|
||||
for (int i = 0; i < max_ops; ++i)
|
||||
need_interrupt = op_queue_[i].cancel_operations(
|
||||
descriptor, ops, ec) || need_interrupt;
|
||||
io_service_.post_deferred_completions(ops);
|
||||
scheduler_.post_deferred_completions(ops);
|
||||
if (need_interrupt)
|
||||
interrupter_.interrupt();
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/impl/epoll_reactor.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -44,12 +44,12 @@ void epoll_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
|
||||
|
||||
if (shutdown_)
|
||||
{
|
||||
io_service_.post_immediate_completion(op, false);
|
||||
scheduler_.post_immediate_completion(op, false);
|
||||
return;
|
||||
}
|
||||
|
||||
bool earliest = queue.enqueue_timer(time, timer, op);
|
||||
io_service_.work_started();
|
||||
scheduler_.work_started();
|
||||
if (earliest)
|
||||
update_timeout();
|
||||
}
|
||||
@@ -63,10 +63,23 @@ std::size_t epoll_reactor::cancel_timer(timer_queue<Time_Traits>& queue,
|
||||
op_queue<operation> ops;
|
||||
std::size_t n = queue.cancel_timer(timer, ops, max_cancelled);
|
||||
lock.unlock();
|
||||
io_service_.post_deferred_completions(ops);
|
||||
scheduler_.post_deferred_completions(ops);
|
||||
return n;
|
||||
}
|
||||
|
||||
template <typename Time_Traits>
|
||||
void epoll_reactor::move_timer(timer_queue<Time_Traits>& queue,
|
||||
typename timer_queue<Time_Traits>::per_timer_data& target,
|
||||
typename timer_queue<Time_Traits>::per_timer_data& source)
|
||||
{
|
||||
mutex::scoped_lock lock(mutex_);
|
||||
op_queue<operation> ops;
|
||||
queue.cancel_timer(target, ops);
|
||||
queue.move_timer(target, source);
|
||||
lock.unlock();
|
||||
scheduler_.post_deferred_completions(ops);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/impl/epoll_reactor.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -35,14 +35,16 @@ namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
epoll_reactor::epoll_reactor(boost::asio::io_service& io_service)
|
||||
: boost::asio::detail::service_base<epoll_reactor>(io_service),
|
||||
io_service_(use_service<io_service_impl>(io_service)),
|
||||
mutex_(),
|
||||
epoll_reactor::epoll_reactor(boost::asio::execution_context& ctx)
|
||||
: execution_context_service_base<epoll_reactor>(ctx),
|
||||
scheduler_(use_service<scheduler>(ctx)),
|
||||
mutex_(BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(
|
||||
REACTOR_REGISTRATION, scheduler_.concurrency_hint())),
|
||||
interrupter_(),
|
||||
epoll_fd_(do_epoll_create()),
|
||||
timer_fd_(do_timerfd_create()),
|
||||
shutdown_(false)
|
||||
shutdown_(false),
|
||||
registered_descriptors_mutex_(mutex_.enabled())
|
||||
{
|
||||
// Add the interrupter's descriptor to epoll.
|
||||
epoll_event ev = { 0, { 0 } };
|
||||
@@ -68,7 +70,7 @@ epoll_reactor::~epoll_reactor()
|
||||
close(timer_fd_);
|
||||
}
|
||||
|
||||
void epoll_reactor::shutdown_service()
|
||||
void epoll_reactor::shutdown()
|
||||
{
|
||||
mutex::scoped_lock lock(mutex_);
|
||||
shutdown_ = true;
|
||||
@@ -86,12 +88,13 @@ void epoll_reactor::shutdown_service()
|
||||
|
||||
timer_queues_.get_all_timers(ops);
|
||||
|
||||
io_service_.abandon_operations(ops);
|
||||
scheduler_.abandon_operations(ops);
|
||||
}
|
||||
|
||||
void epoll_reactor::fork_service(boost::asio::io_service::fork_event fork_ev)
|
||||
void epoll_reactor::notify_fork(
|
||||
boost::asio::execution_context::fork_event fork_ev)
|
||||
{
|
||||
if (fork_ev == boost::asio::io_service::fork_child)
|
||||
if (fork_ev == boost::asio::execution_context::fork_child)
|
||||
{
|
||||
if (epoll_fd_ != -1)
|
||||
::close(epoll_fd_);
|
||||
@@ -142,7 +145,7 @@ void epoll_reactor::fork_service(boost::asio::io_service::fork_event fork_ev)
|
||||
|
||||
void epoll_reactor::init_task()
|
||||
{
|
||||
io_service_.init_task();
|
||||
scheduler_.init_task();
|
||||
}
|
||||
|
||||
int epoll_reactor::register_descriptor(socket_type descriptor,
|
||||
@@ -150,12 +153,18 @@ int epoll_reactor::register_descriptor(socket_type descriptor,
|
||||
{
|
||||
descriptor_data = allocate_descriptor_state();
|
||||
|
||||
BOOST_ASIO_HANDLER_REACTOR_REGISTRATION((
|
||||
context(), static_cast<uintmax_t>(descriptor),
|
||||
reinterpret_cast<uintmax_t>(descriptor_data)));
|
||||
|
||||
{
|
||||
mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
|
||||
|
||||
descriptor_data->reactor_ = this;
|
||||
descriptor_data->descriptor_ = descriptor;
|
||||
descriptor_data->shutdown_ = false;
|
||||
for (int i = 0; i < max_ops; ++i)
|
||||
descriptor_data->try_speculative_[i] = true;
|
||||
}
|
||||
|
||||
epoll_event ev = { 0, { 0 } };
|
||||
@@ -186,6 +195,10 @@ int epoll_reactor::register_internal_descriptor(
|
||||
{
|
||||
descriptor_data = allocate_descriptor_state();
|
||||
|
||||
BOOST_ASIO_HANDLER_REACTOR_REGISTRATION((
|
||||
context(), static_cast<uintmax_t>(descriptor),
|
||||
reinterpret_cast<uintmax_t>(descriptor_data)));
|
||||
|
||||
{
|
||||
mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
|
||||
|
||||
@@ -193,6 +206,8 @@ int epoll_reactor::register_internal_descriptor(
|
||||
descriptor_data->descriptor_ = descriptor;
|
||||
descriptor_data->shutdown_ = false;
|
||||
descriptor_data->op_queue_[op_type].push(op);
|
||||
for (int i = 0; i < max_ops; ++i)
|
||||
descriptor_data->try_speculative_[i] = true;
|
||||
}
|
||||
|
||||
epoll_event ev = { 0, { 0 } };
|
||||
@@ -239,17 +254,23 @@ void epoll_reactor::start_op(int op_type, socket_type descriptor,
|
||||
&& (op_type != read_op
|
||||
|| descriptor_data->op_queue_[except_op].empty()))
|
||||
{
|
||||
if (op->perform())
|
||||
if (descriptor_data->try_speculative_[op_type])
|
||||
{
|
||||
descriptor_lock.unlock();
|
||||
io_service_.post_immediate_completion(op, is_continuation);
|
||||
return;
|
||||
if (reactor_op::status status = op->perform())
|
||||
{
|
||||
if (status == reactor_op::done_and_exhausted)
|
||||
if (descriptor_data->registered_events_ != 0)
|
||||
descriptor_data->try_speculative_[op_type] = false;
|
||||
descriptor_lock.unlock();
|
||||
scheduler_.post_immediate_completion(op, is_continuation);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (descriptor_data->registered_events_ == 0)
|
||||
{
|
||||
op->ec_ = boost::asio::error::operation_not_supported;
|
||||
io_service_.post_immediate_completion(op, is_continuation);
|
||||
scheduler_.post_immediate_completion(op, is_continuation);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -268,7 +289,7 @@ void epoll_reactor::start_op(int op_type, socket_type descriptor,
|
||||
{
|
||||
op->ec_ = boost::system::error_code(errno,
|
||||
boost::asio::error::get_system_category());
|
||||
io_service_.post_immediate_completion(op, is_continuation);
|
||||
scheduler_.post_immediate_completion(op, is_continuation);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -277,7 +298,7 @@ void epoll_reactor::start_op(int op_type, socket_type descriptor,
|
||||
else if (descriptor_data->registered_events_ == 0)
|
||||
{
|
||||
op->ec_ = boost::asio::error::operation_not_supported;
|
||||
io_service_.post_immediate_completion(op, is_continuation);
|
||||
scheduler_.post_immediate_completion(op, is_continuation);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -295,7 +316,7 @@ void epoll_reactor::start_op(int op_type, socket_type descriptor,
|
||||
}
|
||||
|
||||
descriptor_data->op_queue_[op_type].push(op);
|
||||
io_service_.work_started();
|
||||
scheduler_.work_started();
|
||||
}
|
||||
|
||||
void epoll_reactor::cancel_ops(socket_type,
|
||||
@@ -319,7 +340,7 @@ void epoll_reactor::cancel_ops(socket_type,
|
||||
|
||||
descriptor_lock.unlock();
|
||||
|
||||
io_service_.post_deferred_completions(ops);
|
||||
scheduler_.post_deferred_completions(ops);
|
||||
}
|
||||
|
||||
void epoll_reactor::deregister_descriptor(socket_type descriptor,
|
||||
@@ -359,10 +380,20 @@ void epoll_reactor::deregister_descriptor(socket_type descriptor,
|
||||
|
||||
descriptor_lock.unlock();
|
||||
|
||||
free_descriptor_state(descriptor_data);
|
||||
descriptor_data = 0;
|
||||
BOOST_ASIO_HANDLER_REACTOR_DEREGISTRATION((
|
||||
context(), static_cast<uintmax_t>(descriptor),
|
||||
reinterpret_cast<uintmax_t>(descriptor_data)));
|
||||
|
||||
io_service_.post_deferred_completions(ops);
|
||||
scheduler_.post_deferred_completions(ops);
|
||||
|
||||
// Leave descriptor_data set so that it will be freed by the subsequent
|
||||
// call to cleanup_descriptor_data.
|
||||
}
|
||||
else
|
||||
{
|
||||
// We are shutting down, so prevent cleanup_descriptor_data from freeing
|
||||
// the descriptor_data object and let the destructor free it instead.
|
||||
descriptor_data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,33 +419,87 @@ void epoll_reactor::deregister_internal_descriptor(socket_type descriptor,
|
||||
|
||||
descriptor_lock.unlock();
|
||||
|
||||
BOOST_ASIO_HANDLER_REACTOR_DEREGISTRATION((
|
||||
context(), static_cast<uintmax_t>(descriptor),
|
||||
reinterpret_cast<uintmax_t>(descriptor_data)));
|
||||
|
||||
// Leave descriptor_data set so that it will be freed by the subsequent
|
||||
// call to cleanup_descriptor_data.
|
||||
}
|
||||
else
|
||||
{
|
||||
// We are shutting down, so prevent cleanup_descriptor_data from freeing
|
||||
// the descriptor_data object and let the destructor free it instead.
|
||||
descriptor_data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void epoll_reactor::cleanup_descriptor_data(
|
||||
per_descriptor_data& descriptor_data)
|
||||
{
|
||||
if (descriptor_data)
|
||||
{
|
||||
free_descriptor_state(descriptor_data);
|
||||
descriptor_data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void epoll_reactor::run(bool block, op_queue<operation>& ops)
|
||||
void epoll_reactor::run(long usec, op_queue<operation>& ops)
|
||||
{
|
||||
// This code relies on the fact that the task_io_service queues the reactor
|
||||
// task behind all descriptor operations generated by this function. This
|
||||
// means, that by the time we reach this point, any previously returned
|
||||
// descriptor operations have already been dequeued. Therefore it is now safe
|
||||
// for us to reuse and return them for the task_io_service to queue again.
|
||||
// This code relies on the fact that the scheduler queues the reactor task
|
||||
// behind all descriptor operations generated by this function. This means,
|
||||
// that by the time we reach this point, any previously returned descriptor
|
||||
// operations have already been dequeued. Therefore it is now safe for us to
|
||||
// reuse and return them for the scheduler to queue again.
|
||||
|
||||
// Calculate a timeout only if timerfd is not used.
|
||||
// Calculate timeout. Check the timer queues only if timerfd is not in use.
|
||||
int timeout;
|
||||
if (timer_fd_ != -1)
|
||||
timeout = block ? -1 : 0;
|
||||
if (usec == 0)
|
||||
timeout = 0;
|
||||
else
|
||||
{
|
||||
mutex::scoped_lock lock(mutex_);
|
||||
timeout = block ? get_timeout() : 0;
|
||||
timeout = (usec < 0) ? -1 : ((usec - 1) / 1000 + 1);
|
||||
if (timer_fd_ == -1)
|
||||
{
|
||||
mutex::scoped_lock lock(mutex_);
|
||||
timeout = get_timeout(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
// Block on the epoll descriptor.
|
||||
epoll_event events[128];
|
||||
int num_events = epoll_wait(epoll_fd_, events, 128, timeout);
|
||||
|
||||
#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
// Trace the waiting events.
|
||||
for (int i = 0; i < num_events; ++i)
|
||||
{
|
||||
void* ptr = events[i].data.ptr;
|
||||
if (ptr == &interrupter_)
|
||||
{
|
||||
// Ignore.
|
||||
}
|
||||
# if defined(BOOST_ASIO_HAS_TIMERFD)
|
||||
else if (ptr == &timer_fd_)
|
||||
{
|
||||
// Ignore.
|
||||
}
|
||||
# endif // defined(BOOST_ASIO_HAS_TIMERFD)
|
||||
else
|
||||
{
|
||||
unsigned event_mask = 0;
|
||||
if ((events[i].events & EPOLLIN) != 0)
|
||||
event_mask |= BOOST_ASIO_HANDLER_REACTOR_READ_EVENT;
|
||||
if ((events[i].events & EPOLLOUT))
|
||||
event_mask |= BOOST_ASIO_HANDLER_REACTOR_WRITE_EVENT;
|
||||
if ((events[i].events & (EPOLLERR | EPOLLHUP)) != 0)
|
||||
event_mask |= BOOST_ASIO_HANDLER_REACTOR_ERROR_EVENT;
|
||||
BOOST_ASIO_HANDLER_REACTOR_EVENTS((context(),
|
||||
reinterpret_cast<uintmax_t>(ptr), event_mask));
|
||||
}
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_TIMERFD)
|
||||
bool check_timers = (timer_fd_ == -1);
|
||||
#else // defined(BOOST_ASIO_HAS_TIMERFD)
|
||||
@@ -448,11 +533,18 @@ void epoll_reactor::run(bool block, op_queue<operation>& ops)
|
||||
else
|
||||
{
|
||||
// The descriptor operation doesn't count as work in and of itself, so we
|
||||
// don't call work_started() here. This still allows the io_service to
|
||||
// don't call work_started() here. This still allows the scheduler to
|
||||
// stop if the only remaining operations are descriptor operations.
|
||||
descriptor_state* descriptor_data = static_cast<descriptor_state*>(ptr);
|
||||
descriptor_data->set_ready_events(events[i].events);
|
||||
ops.push(descriptor_data);
|
||||
if (!ops.is_enqueued(descriptor_data))
|
||||
{
|
||||
descriptor_data->set_ready_events(events[i].events);
|
||||
ops.push(descriptor_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
descriptor_data->add_ready_events(events[i].events);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -533,7 +625,8 @@ int epoll_reactor::do_timerfd_create()
|
||||
epoll_reactor::descriptor_state* epoll_reactor::allocate_descriptor_state()
|
||||
{
|
||||
mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
|
||||
return registered_descriptors_.alloc();
|
||||
return registered_descriptors_.alloc(BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(
|
||||
REACTOR_IO, scheduler_.concurrency_hint()));
|
||||
}
|
||||
|
||||
void epoll_reactor::free_descriptor_state(epoll_reactor::descriptor_state* s)
|
||||
@@ -569,11 +662,13 @@ void epoll_reactor::update_timeout()
|
||||
interrupt();
|
||||
}
|
||||
|
||||
int epoll_reactor::get_timeout()
|
||||
int epoll_reactor::get_timeout(int msec)
|
||||
{
|
||||
// By default we will wait no longer than 5 minutes. This will ensure that
|
||||
// any changes to the system clock are detected after no longer than this.
|
||||
return timer_queues_.wait_duration_msec(5 * 60 * 1000);
|
||||
const int max_msec = 5 * 60 * 1000;
|
||||
return timer_queues_.wait_duration_msec(
|
||||
(msec < 0 || max_msec < msec) ? max_msec : msec);
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_TIMERFD)
|
||||
@@ -603,19 +698,18 @@ struct epoll_reactor::perform_io_cleanup_on_block_exit
|
||||
{
|
||||
// Post the remaining completed operations for invocation.
|
||||
if (!ops_.empty())
|
||||
reactor_->io_service_.post_deferred_completions(ops_);
|
||||
reactor_->scheduler_.post_deferred_completions(ops_);
|
||||
|
||||
// A user-initiated operation has completed, but there's no need to
|
||||
// explicitly call work_finished() here. Instead, we'll take advantage of
|
||||
// the fact that the task_io_service will call work_finished() once we
|
||||
// return.
|
||||
// the fact that the scheduler will call work_finished() once we return.
|
||||
}
|
||||
else
|
||||
{
|
||||
// No user-initiated operations have completed, so we need to compensate
|
||||
// for the work_finished() call that the task_io_service will make once
|
||||
// this operation returns.
|
||||
reactor_->io_service_.work_started();
|
||||
// for the work_finished() call that the scheduler will make once this
|
||||
// operation returns.
|
||||
reactor_->scheduler_.compensating_work_started();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -624,8 +718,9 @@ struct epoll_reactor::perform_io_cleanup_on_block_exit
|
||||
operation* first_op_;
|
||||
};
|
||||
|
||||
epoll_reactor::descriptor_state::descriptor_state()
|
||||
: operation(&epoll_reactor::descriptor_state::do_complete)
|
||||
epoll_reactor::descriptor_state::descriptor_state(bool locking)
|
||||
: operation(&epoll_reactor::descriptor_state::do_complete),
|
||||
mutex_(locking)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -642,12 +737,18 @@ operation* epoll_reactor::descriptor_state::perform_io(uint32_t events)
|
||||
{
|
||||
if (events & (flag[j] | EPOLLERR | EPOLLHUP))
|
||||
{
|
||||
try_speculative_[j] = true;
|
||||
while (reactor_op* op = op_queue_[j].front())
|
||||
{
|
||||
if (op->perform())
|
||||
if (reactor_op::status status = op->perform())
|
||||
{
|
||||
op_queue_[j].pop();
|
||||
io_cleanup.ops_.push(op);
|
||||
if (status == reactor_op::done_and_exhausted)
|
||||
{
|
||||
try_speculative_[j] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
@@ -663,7 +764,7 @@ operation* epoll_reactor::descriptor_state::perform_io(uint32_t events)
|
||||
}
|
||||
|
||||
void epoll_reactor::descriptor_state::do_complete(
|
||||
io_service_impl* owner, operation* base,
|
||||
void* owner, operation* base,
|
||||
const boost::system::error_code& ec, std::size_t bytes_transferred)
|
||||
{
|
||||
if (owner)
|
||||
@@ -672,7 +773,7 @@ void epoll_reactor::descriptor_state::do_complete(
|
||||
uint32_t events = static_cast<uint32_t>(bytes_transferred);
|
||||
if (operation* op = descriptor_data->perform_io(events))
|
||||
{
|
||||
op->complete(*owner, ec, 0);
|
||||
op->complete(owner, ec, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/impl/eventfd_select_interrupter.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/impl/handler_tracking.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -17,7 +17,11 @@
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
#if defined(BOOST_ASIO_CUSTOM_HANDLER_TRACKING)
|
||||
|
||||
// The handler tracking implementation is provided by the user-specified header.
|
||||
|
||||
#elif defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
@@ -25,17 +29,15 @@
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
# include <boost/asio/time_traits.hpp>
|
||||
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
# if defined(BOOST_ASIO_HAS_STD_CHRONO)
|
||||
# include <chrono>
|
||||
# elif defined(BOOST_ASIO_HAS_BOOST_CHRONO)
|
||||
# include <boost/chrono/system_clocks.hpp>
|
||||
# endif
|
||||
#elif defined(BOOST_ASIO_HAS_CHRONO)
|
||||
# include <boost/asio/detail/chrono.hpp>
|
||||
# include <boost/asio/detail/chrono_time_traits.hpp>
|
||||
# include <boost/asio/wait_traits.hpp>
|
||||
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
|
||||
#if !defined(BOOST_ASIO_WINDOWS)
|
||||
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
||||
# include <boost/asio/detail/socket_types.hpp>
|
||||
#elif !defined(BOOST_ASIO_WINDOWS)
|
||||
# include <unistd.h>
|
||||
#endif // !defined(BOOST_ASIO_WINDOWS)
|
||||
|
||||
@@ -56,16 +58,11 @@ struct handler_tracking_timestamp
|
||||
boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1));
|
||||
boost::posix_time::time_duration now =
|
||||
boost::posix_time::microsec_clock::universal_time() - epoch;
|
||||
#elif defined(BOOST_ASIO_HAS_STD_CHRONO)
|
||||
typedef chrono_time_traits<std::chrono::system_clock,
|
||||
boost::asio::wait_traits<std::chrono::system_clock> > traits_helper;
|
||||
#elif defined(BOOST_ASIO_HAS_CHRONO)
|
||||
typedef chrono_time_traits<chrono::system_clock,
|
||||
boost::asio::wait_traits<chrono::system_clock> > traits_helper;
|
||||
traits_helper::posix_time_duration now(
|
||||
std::chrono::system_clock::now().time_since_epoch());
|
||||
#elif defined(BOOST_ASIO_HAS_BOOST_CHRONO)
|
||||
typedef chrono_time_traits<boost::chrono::system_clock,
|
||||
boost::asio::wait_traits<boost::chrono::system_clock> > traits_helper;
|
||||
traits_helper::posix_time_duration now(
|
||||
boost::chrono::system_clock::now().time_since_epoch());
|
||||
chrono::system_clock::now().time_since_epoch());
|
||||
#endif
|
||||
seconds = static_cast<uint64_t>(now.total_seconds());
|
||||
microseconds = static_cast<uint64_t>(now.total_microseconds() % 1000000);
|
||||
@@ -96,13 +93,15 @@ void handler_tracking::init()
|
||||
state->current_completion_ = new tss_ptr<completion>;
|
||||
}
|
||||
|
||||
void handler_tracking::creation(handler_tracking::tracked_handler* h,
|
||||
const char* object_type, void* object, const char* op_name)
|
||||
void handler_tracking::creation(execution_context&,
|
||||
handler_tracking::tracked_handler& h,
|
||||
const char* object_type, void* object,
|
||||
uintmax_t /*native_handle*/, const char* op_name)
|
||||
{
|
||||
static tracking_state* state = get_state();
|
||||
|
||||
static_mutex::scoped_lock lock(state->mutex_);
|
||||
h->id_ = state->next_id_++;
|
||||
h.id_ = state->next_id_++;
|
||||
lock.unlock();
|
||||
|
||||
handler_tracking_timestamp timestamp;
|
||||
@@ -118,11 +117,12 @@ void handler_tracking::creation(handler_tracking::tracked_handler* h,
|
||||
"@asio|%llu.%06llu|%llu*%llu|%.20s@%p.%.50s\n",
|
||||
#endif // defined(BOOST_ASIO_WINDOWS)
|
||||
timestamp.seconds, timestamp.microseconds,
|
||||
current_id, h->id_, object_type, object, op_name);
|
||||
current_id, h.id_, object_type, object, op_name);
|
||||
}
|
||||
|
||||
handler_tracking::completion::completion(handler_tracking::tracked_handler* h)
|
||||
: id_(h->id_),
|
||||
handler_tracking::completion::completion(
|
||||
const handler_tracking::tracked_handler& h)
|
||||
: id_(h.id_),
|
||||
invoked_(false),
|
||||
next_(*get_state()->current_completion_)
|
||||
{
|
||||
@@ -250,8 +250,9 @@ void handler_tracking::completion::invocation_end()
|
||||
}
|
||||
}
|
||||
|
||||
void handler_tracking::operation(const char* object_type,
|
||||
void* object, const char* op_name)
|
||||
void handler_tracking::operation(execution_context&,
|
||||
const char* object_type, void* object,
|
||||
uintmax_t /*native_handle*/, const char* op_name)
|
||||
{
|
||||
static tracking_state* state = get_state();
|
||||
|
||||
@@ -271,6 +272,54 @@ void handler_tracking::operation(const char* object_type,
|
||||
current_id, object_type, object, op_name);
|
||||
}
|
||||
|
||||
void handler_tracking::reactor_registration(execution_context& /*context*/,
|
||||
uintmax_t /*native_handle*/, uintmax_t /*registration*/)
|
||||
{
|
||||
}
|
||||
|
||||
void handler_tracking::reactor_deregistration(execution_context& /*context*/,
|
||||
uintmax_t /*native_handle*/, uintmax_t /*registration*/)
|
||||
{
|
||||
}
|
||||
|
||||
void handler_tracking::reactor_events(execution_context& /*context*/,
|
||||
uintmax_t /*native_handle*/, unsigned /*events*/)
|
||||
{
|
||||
}
|
||||
|
||||
void handler_tracking::reactor_operation(
|
||||
const tracked_handler& h, const char* op_name,
|
||||
const boost::system::error_code& ec)
|
||||
{
|
||||
handler_tracking_timestamp timestamp;
|
||||
|
||||
write_line(
|
||||
#if defined(BOOST_ASIO_WINDOWS)
|
||||
"@asio|%I64u.%06I64u|.%I64u|%s,ec=%.20s:%d\n",
|
||||
#else // defined(BOOST_ASIO_WINDOWS)
|
||||
"@asio|%llu.%06llu|.%llu|%s,ec=%.20s:%d\n",
|
||||
#endif // defined(BOOST_ASIO_WINDOWS)
|
||||
timestamp.seconds, timestamp.microseconds,
|
||||
h.id_, op_name, ec.category().name(), ec.value());
|
||||
}
|
||||
|
||||
void handler_tracking::reactor_operation(
|
||||
const tracked_handler& h, const char* op_name,
|
||||
const boost::system::error_code& ec, std::size_t bytes_transferred)
|
||||
{
|
||||
handler_tracking_timestamp timestamp;
|
||||
|
||||
write_line(
|
||||
#if defined(BOOST_ASIO_WINDOWS)
|
||||
"@asio|%I64u.%06I64u|.%I64u|%s,ec=%.20s:%d,bytes_transferred=%I64u\n",
|
||||
#else // defined(BOOST_ASIO_WINDOWS)
|
||||
"@asio|%llu.%06llu|.%llu|%s,ec=%.20s:%d,bytes_transferred=%llu\n",
|
||||
#endif // defined(BOOST_ASIO_WINDOWS)
|
||||
timestamp.seconds, timestamp.microseconds,
|
||||
h.id_, op_name, ec.category().name(), ec.value(),
|
||||
static_cast<uint64_t>(bytes_transferred));
|
||||
}
|
||||
|
||||
void handler_tracking::write_line(const char* format, ...)
|
||||
{
|
||||
using namespace std; // For sprintf (or equivalent).
|
||||
@@ -287,7 +336,11 @@ void handler_tracking::write_line(const char* format, ...)
|
||||
|
||||
va_end(args);
|
||||
|
||||
#if defined(BOOST_ASIO_WINDOWS)
|
||||
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
||||
wchar_t wline[256] = L"";
|
||||
mbstowcs_s(0, wline, sizeof(wline) / sizeof(wchar_t), line, length);
|
||||
::OutputDebugStringW(wline);
|
||||
#elif defined(BOOST_ASIO_WINDOWS)
|
||||
HANDLE stderr_handle = ::GetStdHandle(STD_ERROR_HANDLE);
|
||||
DWORD bytes_written = 0;
|
||||
::WriteFile(stderr_handle, line, length, &bytes_written, 0);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/impl/kqueue_reactor.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
@@ -44,16 +44,16 @@ void kqueue_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
|
||||
const typename Time_Traits::time_type& time,
|
||||
typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op)
|
||||
{
|
||||
boost::asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
mutex::scoped_lock lock(mutex_);
|
||||
|
||||
if (shutdown_)
|
||||
{
|
||||
io_service_.post_immediate_completion(op, false);
|
||||
scheduler_.post_immediate_completion(op, false);
|
||||
return;
|
||||
}
|
||||
|
||||
bool earliest = queue.enqueue_timer(time, timer, op);
|
||||
io_service_.work_started();
|
||||
scheduler_.work_started();
|
||||
if (earliest)
|
||||
interrupt();
|
||||
}
|
||||
@@ -63,14 +63,27 @@ std::size_t kqueue_reactor::cancel_timer(timer_queue<Time_Traits>& queue,
|
||||
typename timer_queue<Time_Traits>::per_timer_data& timer,
|
||||
std::size_t max_cancelled)
|
||||
{
|
||||
boost::asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
mutex::scoped_lock lock(mutex_);
|
||||
op_queue<operation> ops;
|
||||
std::size_t n = queue.cancel_timer(timer, ops, max_cancelled);
|
||||
lock.unlock();
|
||||
io_service_.post_deferred_completions(ops);
|
||||
scheduler_.post_deferred_completions(ops);
|
||||
return n;
|
||||
}
|
||||
|
||||
template <typename Time_Traits>
|
||||
void kqueue_reactor::move_timer(timer_queue<Time_Traits>& queue,
|
||||
typename timer_queue<Time_Traits>::per_timer_data& target,
|
||||
typename timer_queue<Time_Traits>::per_timer_data& source)
|
||||
{
|
||||
mutex::scoped_lock lock(mutex_);
|
||||
op_queue<operation> ops;
|
||||
queue.cancel_timer(target, ops);
|
||||
queue.move_timer(target, source);
|
||||
lock.unlock();
|
||||
scheduler_.post_deferred_completions(ops);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/impl/kqueue_reactor.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
@@ -21,6 +21,7 @@
|
||||
#if defined(BOOST_ASIO_HAS_KQUEUE)
|
||||
|
||||
#include <boost/asio/detail/kqueue_reactor.hpp>
|
||||
#include <boost/asio/detail/scheduler.hpp>
|
||||
#include <boost/asio/detail/throw_error.hpp>
|
||||
#include <boost/asio/error.hpp>
|
||||
|
||||
@@ -39,13 +40,15 @@ namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
kqueue_reactor::kqueue_reactor(boost::asio::io_service& io_service)
|
||||
: boost::asio::detail::service_base<kqueue_reactor>(io_service),
|
||||
io_service_(use_service<io_service_impl>(io_service)),
|
||||
mutex_(),
|
||||
kqueue_reactor::kqueue_reactor(boost::asio::execution_context& ctx)
|
||||
: execution_context_service_base<kqueue_reactor>(ctx),
|
||||
scheduler_(use_service<scheduler>(ctx)),
|
||||
mutex_(BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(
|
||||
REACTOR_REGISTRATION, scheduler_.concurrency_hint())),
|
||||
kqueue_fd_(do_kqueue_create()),
|
||||
interrupter_(),
|
||||
shutdown_(false)
|
||||
shutdown_(false),
|
||||
registered_descriptors_mutex_(mutex_.enabled())
|
||||
{
|
||||
struct kevent events[1];
|
||||
BOOST_ASIO_KQUEUE_EV_SET(&events[0], interrupter_.read_descriptor(),
|
||||
@@ -63,7 +66,7 @@ kqueue_reactor::~kqueue_reactor()
|
||||
close(kqueue_fd_);
|
||||
}
|
||||
|
||||
void kqueue_reactor::shutdown_service()
|
||||
void kqueue_reactor::shutdown()
|
||||
{
|
||||
mutex::scoped_lock lock(mutex_);
|
||||
shutdown_ = true;
|
||||
@@ -81,12 +84,13 @@ void kqueue_reactor::shutdown_service()
|
||||
|
||||
timer_queues_.get_all_timers(ops);
|
||||
|
||||
io_service_.abandon_operations(ops);
|
||||
scheduler_.abandon_operations(ops);
|
||||
}
|
||||
|
||||
void kqueue_reactor::fork_service(boost::asio::io_service::fork_event fork_ev)
|
||||
void kqueue_reactor::notify_fork(
|
||||
boost::asio::execution_context::fork_event fork_ev)
|
||||
{
|
||||
if (fork_ev == boost::asio::io_service::fork_child)
|
||||
if (fork_ev == boost::asio::execution_context::fork_child)
|
||||
{
|
||||
// The kqueue descriptor is automatically closed in the child.
|
||||
kqueue_fd_ = -1;
|
||||
@@ -128,7 +132,7 @@ void kqueue_reactor::fork_service(boost::asio::io_service::fork_event fork_ev)
|
||||
|
||||
void kqueue_reactor::init_task()
|
||||
{
|
||||
io_service_.init_task();
|
||||
scheduler_.init_task();
|
||||
}
|
||||
|
||||
int kqueue_reactor::register_descriptor(socket_type descriptor,
|
||||
@@ -136,6 +140,10 @@ int kqueue_reactor::register_descriptor(socket_type descriptor,
|
||||
{
|
||||
descriptor_data = allocate_descriptor_state();
|
||||
|
||||
BOOST_ASIO_HANDLER_REACTOR_REGISTRATION((
|
||||
context(), static_cast<uintmax_t>(descriptor),
|
||||
reinterpret_cast<uintmax_t>(descriptor_data)));
|
||||
|
||||
mutex::scoped_lock lock(descriptor_data->mutex_);
|
||||
|
||||
descriptor_data->descriptor_ = descriptor;
|
||||
@@ -151,6 +159,10 @@ int kqueue_reactor::register_internal_descriptor(
|
||||
{
|
||||
descriptor_data = allocate_descriptor_state();
|
||||
|
||||
BOOST_ASIO_HANDLER_REACTOR_REGISTRATION((
|
||||
context(), static_cast<uintmax_t>(descriptor),
|
||||
reinterpret_cast<uintmax_t>(descriptor_data)));
|
||||
|
||||
mutex::scoped_lock lock(descriptor_data->mutex_);
|
||||
|
||||
descriptor_data->descriptor_ = descriptor;
|
||||
@@ -205,7 +217,7 @@ void kqueue_reactor::start_op(int op_type, socket_type descriptor,
|
||||
if (op->perform())
|
||||
{
|
||||
descriptor_lock.unlock();
|
||||
io_service_.post_immediate_completion(op, is_continuation);
|
||||
scheduler_.post_immediate_completion(op, is_continuation);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -224,7 +236,7 @@ void kqueue_reactor::start_op(int op_type, socket_type descriptor,
|
||||
{
|
||||
op->ec_ = boost::system::error_code(errno,
|
||||
boost::asio::error::get_system_category());
|
||||
io_service_.post_immediate_completion(op, is_continuation);
|
||||
scheduler_.post_immediate_completion(op, is_continuation);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -244,7 +256,7 @@ void kqueue_reactor::start_op(int op_type, socket_type descriptor,
|
||||
}
|
||||
|
||||
descriptor_data->op_queue_[op_type].push(op);
|
||||
io_service_.work_started();
|
||||
scheduler_.work_started();
|
||||
}
|
||||
|
||||
void kqueue_reactor::cancel_ops(socket_type,
|
||||
@@ -268,7 +280,7 @@ void kqueue_reactor::cancel_ops(socket_type,
|
||||
|
||||
descriptor_lock.unlock();
|
||||
|
||||
io_service_.post_deferred_completions(ops);
|
||||
scheduler_.post_deferred_completions(ops);
|
||||
}
|
||||
|
||||
void kqueue_reactor::deregister_descriptor(socket_type descriptor,
|
||||
@@ -312,10 +324,20 @@ void kqueue_reactor::deregister_descriptor(socket_type descriptor,
|
||||
|
||||
descriptor_lock.unlock();
|
||||
|
||||
free_descriptor_state(descriptor_data);
|
||||
descriptor_data = 0;
|
||||
BOOST_ASIO_HANDLER_REACTOR_DEREGISTRATION((
|
||||
context(), static_cast<uintmax_t>(descriptor),
|
||||
reinterpret_cast<uintmax_t>(descriptor_data)));
|
||||
|
||||
io_service_.post_deferred_completions(ops);
|
||||
scheduler_.post_deferred_completions(ops);
|
||||
|
||||
// Leave descriptor_data set so that it will be freed by the subsequent
|
||||
// call to cleanup_descriptor_data.
|
||||
}
|
||||
else
|
||||
{
|
||||
// We are shutting down, so prevent cleanup_descriptor_data from freeing
|
||||
// the descriptor_data object and let the destructor free it instead.
|
||||
descriptor_data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,18 +367,38 @@ void kqueue_reactor::deregister_internal_descriptor(socket_type descriptor,
|
||||
|
||||
descriptor_lock.unlock();
|
||||
|
||||
BOOST_ASIO_HANDLER_REACTOR_DEREGISTRATION((
|
||||
context(), static_cast<uintmax_t>(descriptor),
|
||||
reinterpret_cast<uintmax_t>(descriptor_data)));
|
||||
|
||||
// Leave descriptor_data set so that it will be freed by the subsequent
|
||||
// call to cleanup_descriptor_data.
|
||||
}
|
||||
else
|
||||
{
|
||||
// We are shutting down, so prevent cleanup_descriptor_data from freeing
|
||||
// the descriptor_data object and let the destructor free it instead.
|
||||
descriptor_data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void kqueue_reactor::cleanup_descriptor_data(
|
||||
per_descriptor_data& descriptor_data)
|
||||
{
|
||||
if (descriptor_data)
|
||||
{
|
||||
free_descriptor_state(descriptor_data);
|
||||
descriptor_data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void kqueue_reactor::run(bool block, op_queue<operation>& ops)
|
||||
void kqueue_reactor::run(long usec, op_queue<operation>& ops)
|
||||
{
|
||||
mutex::scoped_lock lock(mutex_);
|
||||
|
||||
// Determine how long to block while waiting for events.
|
||||
timespec timeout_buf = { 0, 0 };
|
||||
timespec* timeout = block ? get_timeout(timeout_buf) : &timeout_buf;
|
||||
timespec* timeout = usec ? get_timeout(usec, timeout_buf) : &timeout_buf;
|
||||
|
||||
lock.unlock();
|
||||
|
||||
@@ -364,6 +406,31 @@ void kqueue_reactor::run(bool block, op_queue<operation>& ops)
|
||||
struct kevent events[128];
|
||||
int num_events = kevent(kqueue_fd_, 0, 0, events, 128, timeout);
|
||||
|
||||
#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
// Trace the waiting events.
|
||||
for (int i = 0; i < num_events; ++i)
|
||||
{
|
||||
void* ptr = reinterpret_cast<void*>(events[i].udata);
|
||||
if (ptr != &interrupter_)
|
||||
{
|
||||
unsigned event_mask = 0;
|
||||
switch (events[i].filter)
|
||||
{
|
||||
case EVFILT_READ:
|
||||
event_mask |= BOOST_ASIO_HANDLER_REACTOR_READ_EVENT;
|
||||
break;
|
||||
case EVFILT_WRITE:
|
||||
event_mask |= BOOST_ASIO_HANDLER_REACTOR_WRITE_EVENT;
|
||||
break;
|
||||
}
|
||||
if ((events[i].flags & (EV_ERROR | EV_OOBAND)) != 0)
|
||||
event_mask |= BOOST_ASIO_HANDLER_REACTOR_ERROR_EVENT;
|
||||
BOOST_ASIO_HANDLER_REACTOR_EVENTS((context(),
|
||||
reinterpret_cast<uintmax_t>(ptr), event_mask));
|
||||
}
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
|
||||
// Dispatch the waiting events.
|
||||
for (int i = 0; i < num_events; ++i)
|
||||
{
|
||||
@@ -454,7 +521,8 @@ int kqueue_reactor::do_kqueue_create()
|
||||
kqueue_reactor::descriptor_state* kqueue_reactor::allocate_descriptor_state()
|
||||
{
|
||||
mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
|
||||
return registered_descriptors_.alloc();
|
||||
return registered_descriptors_.alloc(BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(
|
||||
REACTOR_IO, scheduler_.concurrency_hint()));
|
||||
}
|
||||
|
||||
void kqueue_reactor::free_descriptor_state(kqueue_reactor::descriptor_state* s)
|
||||
@@ -475,11 +543,13 @@ void kqueue_reactor::do_remove_timer_queue(timer_queue_base& queue)
|
||||
timer_queues_.erase(&queue);
|
||||
}
|
||||
|
||||
timespec* kqueue_reactor::get_timeout(timespec& ts)
|
||||
timespec* kqueue_reactor::get_timeout(long usec, timespec& ts)
|
||||
{
|
||||
// By default we will wait no longer than 5 minutes. This will ensure that
|
||||
// any changes to the system clock are detected after no longer than this.
|
||||
long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000);
|
||||
const long max_usec = 5 * 60 * 1000 * 1000;
|
||||
usec = timer_queues_.wait_duration_usec(
|
||||
(usec < 0 || max_usec < usec) ? max_usec : usec);
|
||||
ts.tv_sec = usec / 1000000;
|
||||
ts.tv_nsec = (usec % 1000000) * 1000;
|
||||
return &ts;
|
||||
|
||||
76
winx64/include/boost/asio/detail/impl/null_event.ipp
Normal file
76
winx64/include/boost/asio/detail/impl/null_event.ipp
Normal file
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// detail/impl/null_event.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// 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_DETAIL_IMPL_NULL_EVENT_IPP
|
||||
#define BOOST_ASIO_DETAIL_IMPL_NULL_EVENT_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_WINDOWS_RUNTIME)
|
||||
# include <thread>
|
||||
#elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
||||
# include <boost/asio/detail/socket_types.hpp>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# if defined(__hpux)
|
||||
# include <sys/time.h>
|
||||
# endif
|
||||
# if !defined(__hpux) || defined(__SELECT)
|
||||
# include <sys/select.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
void null_event::do_wait()
|
||||
{
|
||||
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
||||
std::this_thread::sleep_until((std::chrono::steady_clock::time_point::max)());
|
||||
#elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
||||
::Sleep(INFINITE);
|
||||
#else
|
||||
::pause();
|
||||
#endif
|
||||
}
|
||||
|
||||
void null_event::do_wait_for_usec(long usec)
|
||||
{
|
||||
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(usec));
|
||||
#elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
||||
::Sleep(usec / 1000);
|
||||
#elif defined(__hpux) && defined(__SELECT)
|
||||
timespec ts;
|
||||
ts.tv_sec = usec / 1000000;
|
||||
ts.tv_nsec = (usec % 1000000) * 1000;
|
||||
::pselect(0, 0, 0, 0, &ts, 0);
|
||||
#else
|
||||
timeval tv;
|
||||
tv.tv_sec = usec / 1000000;
|
||||
tv.tv_usec = usec % 1000000;
|
||||
::select(0, 0, 0, 0, &tv);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_IMPL_NULL_EVENT_IPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/impl/pipe_select_interrupter.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// detail/impl/posix_event.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// 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)
|
||||
@@ -32,7 +32,19 @@ namespace detail {
|
||||
posix_event::posix_event()
|
||||
: state_(0)
|
||||
{
|
||||
#if (defined(__MACH__) && defined(__APPLE__)) \
|
||||
|| (defined(__ANDROID__) && (__ANDROID_API__ < 21))
|
||||
int error = ::pthread_cond_init(&cond_, 0);
|
||||
#else // (defined(__MACH__) && defined(__APPLE__))
|
||||
// || (defined(__ANDROID__) && (__ANDROID_API__ < 21))
|
||||
::pthread_condattr_t attr;
|
||||
::pthread_condattr_init(&attr);
|
||||
int error = ::pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
|
||||
if (error == 0)
|
||||
error = ::pthread_cond_init(&cond_, &attr);
|
||||
#endif // (defined(__MACH__) && defined(__APPLE__))
|
||||
// || (defined(__ANDROID__) && (__ANDROID_API__ < 21))
|
||||
|
||||
boost::system::error_code ec(error,
|
||||
boost::asio::error::get_system_category());
|
||||
boost::asio::detail::throw_error(ec, "event");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user