mirror of
https://github.com/boostorg/beast.git
synced 2025-08-02 06:15:24 +02:00
Add tests for async_op_base
This commit is contained in:
@@ -7,6 +7,7 @@ Version 202
|
|||||||
* Use async_op_base
|
* Use async_op_base
|
||||||
* async_op_base is a public interface
|
* async_op_base is a public interface
|
||||||
* Add tests for bind_back_handler
|
* Add tests for bind_back_handler
|
||||||
|
* Add tests for async_op_base
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@@ -61,8 +61,8 @@ public:
|
|||||||
Handler_&& h)
|
Handler_&& h)
|
||||||
: async_op_base<Handler,
|
: async_op_base<Handler,
|
||||||
detail::get_executor_type<flat_stream>>(
|
detail::get_executor_type<flat_stream>>(
|
||||||
s.get_executor(),
|
std::forward<Handler_>(h),
|
||||||
std::forward<Handler_>(h))
|
s.get_executor())
|
||||||
, s_(s)
|
, s_(s)
|
||||||
, b_(b)
|
, b_(b)
|
||||||
, p_(nullptr, deleter{alloc_type{}})
|
, p_(nullptr, deleter{alloc_type{}})
|
||||||
|
@@ -151,9 +151,9 @@ public:
|
|||||||
Handler_&& h,
|
Handler_&& h,
|
||||||
icy_stream& s,
|
icy_stream& s,
|
||||||
MutableBufferSequence const& b)
|
MutableBufferSequence const& b)
|
||||||
: beast::stable_async_op_base<Handler,
|
: stable_async_op_base<Handler,
|
||||||
beast::detail::get_executor_type<icy_stream>>(
|
beast::detail::get_executor_type<icy_stream>>(
|
||||||
s.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h), s.get_executor())
|
||||||
, d_(beast::allocate_stable<data>(*this, s, b))
|
, d_(beast::allocate_stable<data>(*this, s, b))
|
||||||
{
|
{
|
||||||
(*this)({}, 0);
|
(*this)({}, 0);
|
||||||
|
@@ -91,7 +91,7 @@ namespace beast {
|
|||||||
AsyncReadStream& stream,
|
AsyncReadStream& stream,
|
||||||
net::mutable_buffer buffer,
|
net::mutable_buffer buffer,
|
||||||
handler_type& handler)
|
handler_type& handler)
|
||||||
: base_type(stream.get_executor(), std::move(handler))
|
: base_type(std::move(handler), stream.get_executor())
|
||||||
, stream_(stream)
|
, stream_(stream)
|
||||||
, buffer_(buffer)
|
, buffer_(buffer)
|
||||||
, total_bytes_transferred_(0)
|
, total_bytes_transferred_(0)
|
||||||
@@ -197,6 +197,56 @@ class async_op_base
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/** Constructor
|
||||||
|
|
||||||
|
@param handler The final completion handler. The type of this
|
||||||
|
object must meet the requirements of <em>CompletionHandler</em>.
|
||||||
|
|
||||||
|
@param ex1 The executor associated with the implied I/O object
|
||||||
|
target of the operation. The implementation shall maintain an
|
||||||
|
executor work guard for the lifetime of the operation, or until
|
||||||
|
the final completion handler is invoked, whichever is shorter.
|
||||||
|
|
||||||
|
@param alloc The allocator to be associated with objects
|
||||||
|
derived from this class. If `Allocator` is default-constructible,
|
||||||
|
this parameter is optional and may be omitted.
|
||||||
|
*/
|
||||||
|
#if BOOST_BEAST_DOXYGEN
|
||||||
|
template<class Handler>
|
||||||
|
async_op_base(
|
||||||
|
Handler&& handler,
|
||||||
|
Executor1 const& ex1,
|
||||||
|
Allocator const& alloc = Allocator());
|
||||||
|
#else
|
||||||
|
template<
|
||||||
|
class Handler_,
|
||||||
|
class = typename std::enable_if<
|
||||||
|
! std::is_same<typename
|
||||||
|
std::decay<Handler_>::type,
|
||||||
|
async_op_base
|
||||||
|
>::value>::type
|
||||||
|
>
|
||||||
|
async_op_base(
|
||||||
|
Handler_&& handler,
|
||||||
|
Executor1 const& ex1)
|
||||||
|
: h_(std::forward<Handler_>(handler))
|
||||||
|
, wg_(ex1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Handler_>
|
||||||
|
async_op_base(
|
||||||
|
Handler_&& handler,
|
||||||
|
Executor1 const& ex1,
|
||||||
|
Allocator const& alloc)
|
||||||
|
: boost::empty_value<Allocator>(
|
||||||
|
boost::empty_init_t{}, alloc)
|
||||||
|
, h_(std::forward<Handler_>(handler))
|
||||||
|
, wg_(ex1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Move Constructor
|
/// Move Constructor
|
||||||
async_op_base(async_op_base&& other) = default;
|
async_op_base(async_op_base&& other) = default;
|
||||||
|
|
||||||
@@ -264,56 +314,6 @@ public:
|
|||||||
return std::move(h_);
|
return std::move(h_);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
|
||||||
/** Constructor
|
|
||||||
|
|
||||||
@param handler The final completion handler. The type of this
|
|
||||||
object must meet the requirements of <em>CompletionHandler</em>.
|
|
||||||
|
|
||||||
@param ex1 The executor associated with the implied I/O object
|
|
||||||
target of the operation. The implementation shall maintain an
|
|
||||||
executor work guard for the lifetime of the operation, or until
|
|
||||||
the final completion handler is invoked, whichever is shorter.
|
|
||||||
|
|
||||||
@param alloc The allocator to be associated with objects
|
|
||||||
derived from this class. If `Allocator` is default-constructible,
|
|
||||||
this parameter is optional and may be omitted.
|
|
||||||
*/
|
|
||||||
#if BOOST_BEAST_DOXYGEN
|
|
||||||
template<class Handler>
|
|
||||||
async_op_base(
|
|
||||||
Executor1 const& ex1,
|
|
||||||
Handler&& handler,
|
|
||||||
Allocator const& alloc = Allocator());
|
|
||||||
#else
|
|
||||||
template<
|
|
||||||
class Handler_,
|
|
||||||
class = typename std::enable_if<
|
|
||||||
! std::is_same<typename
|
|
||||||
std::decay<Handler_>::type,
|
|
||||||
async_op_base
|
|
||||||
>::value>::type
|
|
||||||
>
|
|
||||||
async_op_base(
|
|
||||||
Executor1 const& ex1,
|
|
||||||
Handler_&& handler)
|
|
||||||
: h_(std::forward<Handler_>(handler))
|
|
||||||
, wg_(ex1)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Handler_>
|
|
||||||
async_op_base(
|
|
||||||
Executor1 const& ex1,
|
|
||||||
Handler_&& handler,
|
|
||||||
Allocator const& alloc)
|
|
||||||
: boost::empty_value<Allocator>(alloc)
|
|
||||||
, h_(std::forward<Handler_>(handler))
|
|
||||||
, wg_(ex1)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Invoke the final completion handler.
|
/** Invoke the final completion handler.
|
||||||
|
|
||||||
This invokes the final completion handler with the specified
|
This invokes the final completion handler with the specified
|
||||||
@@ -334,7 +334,6 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if ! BOOST_BEAST_DOXYGEN
|
#if ! BOOST_BEAST_DOXYGEN
|
||||||
public:
|
|
||||||
template<
|
template<
|
||||||
class Handler_,
|
class Handler_,
|
||||||
class Executor1_,
|
class Executor1_,
|
||||||
@@ -480,7 +479,7 @@ public:
|
|||||||
enum { starting, waiting, writing } state_;
|
enum { starting, waiting, writing } state_;
|
||||||
|
|
||||||
op(AsyncWriteStream& stream, std::size_t repeats, std::string message, handler_type& handler)
|
op(AsyncWriteStream& stream, std::size_t repeats, std::string message, handler_type& handler)
|
||||||
: base_type(stream.get_executor(), std::move(handler))
|
: base_type(std::move(handler), stream.get_executor())
|
||||||
, stream_(stream)
|
, stream_(stream)
|
||||||
, repeats_(repeats)
|
, repeats_(repeats)
|
||||||
, state_(starting)
|
, state_(starting)
|
||||||
@@ -570,15 +569,6 @@ class stable_async_op_base
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Move Constructor
|
|
||||||
stable_async_op_base(stable_async_op_base&& other)
|
|
||||||
: async_op_base<Handler, Executor1, Allocator>(
|
|
||||||
std::move(other))
|
|
||||||
, list_(boost::exchange(other.list_, nullptr))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/** Constructor
|
/** Constructor
|
||||||
|
|
||||||
@param handler The final completion handler. The type of this
|
@param handler The final completion handler. The type of this
|
||||||
@@ -609,26 +599,34 @@ protected:
|
|||||||
>::value>::type
|
>::value>::type
|
||||||
>
|
>
|
||||||
stable_async_op_base(
|
stable_async_op_base(
|
||||||
Executor1 const& ex1,
|
Handler_&& handler,
|
||||||
Handler_&& handler)
|
Executor1 const& ex1)
|
||||||
: async_op_base<
|
: async_op_base<
|
||||||
Handler, Executor1, Allocator>(
|
Handler, Executor1, Allocator>(
|
||||||
ex1, std::forward<Handler_>(handler))
|
std::forward<Handler_>(handler), ex1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Handler_>
|
template<class Handler_>
|
||||||
stable_async_op_base(
|
stable_async_op_base(
|
||||||
Executor1 const& ex1,
|
|
||||||
Handler_&& handler,
|
Handler_&& handler,
|
||||||
|
Executor1 const& ex1,
|
||||||
Allocator const& alloc)
|
Allocator const& alloc)
|
||||||
: async_op_base<
|
: async_op_base<
|
||||||
Handler, Executor1, Allocator>(
|
Handler, Executor1, Allocator>(
|
||||||
ex1, std::forward<Handler_>(handler))
|
std::forward<Handler_>(handler), ex1, alloc)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// Move Constructor
|
||||||
|
stable_async_op_base(stable_async_op_base&& other)
|
||||||
|
: async_op_base<Handler, Executor1, Allocator>(
|
||||||
|
std::move(other))
|
||||||
|
, list_(boost::exchange(other.list_, nullptr))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/** Destructor
|
/** Destructor
|
||||||
|
|
||||||
If the completion handler was not invoked, then any
|
If the completion handler was not invoked, then any
|
||||||
@@ -676,6 +674,40 @@ void asio_handler_invoke(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<class State, class Allocator>
|
||||||
|
struct allocate_stable_state final
|
||||||
|
: stable_base
|
||||||
|
, boost::empty_value<Allocator>
|
||||||
|
{
|
||||||
|
State value;
|
||||||
|
|
||||||
|
template<class... Args>
|
||||||
|
explicit
|
||||||
|
allocate_stable_state(
|
||||||
|
Allocator const& alloc,
|
||||||
|
Args&&... args)
|
||||||
|
: boost::empty_value<Allocator>(
|
||||||
|
boost::empty_init_t{}, alloc)
|
||||||
|
, value{std::forward<Args>(args)...}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy() override
|
||||||
|
{
|
||||||
|
using A = typename allocator_traits<
|
||||||
|
Allocator>::template rebind_alloc<
|
||||||
|
allocate_stable_state>;
|
||||||
|
|
||||||
|
A a(this->get());
|
||||||
|
detail::allocator_traits<A>::destroy(a, this);
|
||||||
|
detail::allocator_traits<A>::deallocate(a, this, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // detail
|
||||||
|
|
||||||
/** Allocate a temporary object to hold stable asynchronous operation state.
|
/** Allocate a temporary object to hold stable asynchronous operation state.
|
||||||
|
|
||||||
The object will be destroyed just before the completion
|
The object will be destroyed just before the completion
|
||||||
@@ -695,44 +727,19 @@ allocate_stable(
|
|||||||
Handler, Executor1, Allocator>& base,
|
Handler, Executor1, Allocator>& base,
|
||||||
Args&&... args)
|
Args&&... args)
|
||||||
{
|
{
|
||||||
struct state;
|
|
||||||
|
|
||||||
using allocator_type = typename stable_async_op_base<
|
using allocator_type = typename stable_async_op_base<
|
||||||
Handler, Executor1, Allocator>::allocator_type;
|
Handler, Executor1, Allocator>::allocator_type;
|
||||||
|
|
||||||
using A = typename detail::allocator_traits<
|
using A = typename detail::allocator_traits<
|
||||||
allocator_type>::template rebind_alloc<state>;
|
allocator_type>::template rebind_alloc<
|
||||||
|
detail::allocate_stable_state<
|
||||||
struct state final
|
State, allocator_type>>;
|
||||||
: detail::stable_base
|
|
||||||
, boost::empty_value<allocator_type>
|
|
||||||
{
|
|
||||||
State value;
|
|
||||||
|
|
||||||
explicit
|
|
||||||
state(
|
|
||||||
allocator_type const& alloc,
|
|
||||||
detail::stable_base*& list,
|
|
||||||
Args&&... args)
|
|
||||||
: detail::stable_base(list)
|
|
||||||
, boost::empty_value<allocator_type>(
|
|
||||||
boost::empty_init_t{}, alloc)
|
|
||||||
, value{std::forward<Args>(args)...}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroy() override
|
|
||||||
{
|
|
||||||
A a(this->get());
|
|
||||||
detail::allocator_traits<A>::destroy(a, this);
|
|
||||||
detail::allocator_traits<A>::deallocate(a, this, 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct deleter
|
struct deleter
|
||||||
{
|
{
|
||||||
allocator_type alloc;
|
allocator_type alloc;
|
||||||
state* ptr;
|
detail::allocate_stable_state<
|
||||||
|
State, allocator_type>* ptr;
|
||||||
|
|
||||||
~deleter()
|
~deleter()
|
||||||
{
|
{
|
||||||
@@ -748,9 +755,9 @@ allocate_stable(
|
|||||||
deleter d{base.get_allocator(), nullptr};
|
deleter d{base.get_allocator(), nullptr};
|
||||||
d.ptr = detail::allocator_traits<A>::allocate(a, 1);
|
d.ptr = detail::allocator_traits<A>::allocate(a, 1);
|
||||||
detail::allocator_traits<A>::construct(a, d.ptr,
|
detail::allocator_traits<A>::construct(a, d.ptr,
|
||||||
d.alloc,
|
d.alloc, std::forward<Args>(args)...);
|
||||||
base.list_,
|
d.ptr->next_ = base.list_;
|
||||||
std::forward<Args>(args)...);
|
base.list_ = d.ptr;
|
||||||
return boost::exchange(d.ptr, nullptr)->value;
|
return boost::exchange(d.ptr, nullptr)->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -30,14 +30,13 @@ struct stable_base
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stable_base* next_ = nullptr;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
stable_base* next_;
|
stable_base() = default;
|
||||||
virtual void destroy() = 0;
|
|
||||||
virtual ~stable_base() = default;
|
virtual ~stable_base() = default;
|
||||||
explicit stable_base(stable_base*& list)
|
|
||||||
: next_(boost::exchange(list, this))
|
virtual void destroy() = 0;
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
|
@@ -18,9 +18,6 @@
|
|||||||
#include <boost/asio/coroutine.hpp>
|
#include <boost/asio/coroutine.hpp>
|
||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
|
|
||||||
// REMOVE
|
|
||||||
#define BOOST_BEAST_ENABLE_NON_BLOCKING
|
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace beast {
|
namespace beast {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@@ -56,9 +53,10 @@ public:
|
|||||||
DynamicBuffer& b,
|
DynamicBuffer& b,
|
||||||
Condition cond,
|
Condition cond,
|
||||||
Handler_&& h)
|
Handler_&& h)
|
||||||
: async_op_base<
|
: async_op_base<Handler,
|
||||||
Handler, get_executor_type<Stream>>(
|
get_executor_type<Stream>>(
|
||||||
s.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h),
|
||||||
|
s.get_executor())
|
||||||
, s_(s)
|
, s_(s)
|
||||||
, b_(b)
|
, b_(b)
|
||||||
, cond_(cond)
|
, cond_(cond)
|
||||||
|
@@ -107,7 +107,7 @@ public:
|
|||||||
Buffers const& b,
|
Buffers const& b,
|
||||||
Handler_&& h)
|
Handler_&& h)
|
||||||
: async_op_base<Handler, Executor>(
|
: async_op_base<Handler, Executor>(
|
||||||
s.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h), s.get_executor())
|
||||||
, impl_(*s.impl_)
|
, impl_(*s.impl_)
|
||||||
, pg_(impl_.read_pending)
|
, pg_(impl_.read_pending)
|
||||||
, b_(b)
|
, b_(b)
|
||||||
@@ -224,7 +224,7 @@ public:
|
|||||||
Buffers const& b,
|
Buffers const& b,
|
||||||
Handler_&& h)
|
Handler_&& h)
|
||||||
: async_op_base<Handler, Executor>(
|
: async_op_base<Handler, Executor>(
|
||||||
s.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h), s.get_executor())
|
||||||
, impl_(*s.impl_)
|
, impl_(*s.impl_)
|
||||||
, pg_(impl_.write_pending)
|
, pg_(impl_.write_pending)
|
||||||
, b_(b)
|
, b_(b)
|
||||||
@@ -350,7 +350,7 @@ public:
|
|||||||
Condition cond,
|
Condition cond,
|
||||||
Handler_&& h)
|
Handler_&& h)
|
||||||
: async_op_base<Handler, Executor>(
|
: async_op_base<Handler, Executor>(
|
||||||
s.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h), s.get_executor())
|
||||||
, impl_(*s.impl_)
|
, impl_(*s.impl_)
|
||||||
, pg0_(impl_.read_pending)
|
, pg0_(impl_.read_pending)
|
||||||
, pg1_(impl_.write_pending)
|
, pg1_(impl_.write_pending)
|
||||||
@@ -377,7 +377,7 @@ public:
|
|||||||
Condition cond,
|
Condition cond,
|
||||||
Handler_&& h)
|
Handler_&& h)
|
||||||
: async_op_base<Handler, Executor>(
|
: async_op_base<Handler, Executor>(
|
||||||
s.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h), s.get_executor())
|
||||||
, impl_(*s.impl_)
|
, impl_(*s.impl_)
|
||||||
, pg0_(impl_.read_pending)
|
, pg0_(impl_.read_pending)
|
||||||
, pg1_(impl_.write_pending)
|
, pg1_(impl_.write_pending)
|
||||||
|
@@ -44,7 +44,7 @@ public:
|
|||||||
MutableBufferSequence const& b)
|
MutableBufferSequence const& b)
|
||||||
: async_op_base<
|
: async_op_base<
|
||||||
Handler, detail::get_executor_type<buffered_read_stream>>(
|
Handler, detail::get_executor_type<buffered_read_stream>>(
|
||||||
s.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h), s.get_executor())
|
||||||
, s_(s)
|
, s_(s)
|
||||||
, b_(b)
|
, b_(b)
|
||||||
{
|
{
|
||||||
|
@@ -350,11 +350,11 @@ public:
|
|||||||
net::basic_stream_socket<Protocol>& s,
|
net::basic_stream_socket<Protocol>& s,
|
||||||
serializer<isRequest,
|
serializer<isRequest,
|
||||||
basic_file_body<file_win32>,Fields>& sr)
|
basic_file_body<file_win32>,Fields>& sr)
|
||||||
: beast::async_op_base<
|
: async_op_base<
|
||||||
Handler, typename net::basic_stream_socket<
|
Handler, typename net::basic_stream_socket<
|
||||||
Protocol>::executor_type>(
|
Protocol>::executor_type>(
|
||||||
s.get_executor(),
|
std::forward<Handler_>(h),
|
||||||
std::forward<Handler_>(h))
|
s.get_executor())
|
||||||
, sock_(s)
|
, sock_(s)
|
||||||
, sr_(sr)
|
, sr_(sr)
|
||||||
{
|
{
|
||||||
|
@@ -184,9 +184,9 @@ public:
|
|||||||
DynamicBuffer& b,
|
DynamicBuffer& b,
|
||||||
message_type& m,
|
message_type& m,
|
||||||
Handler_&& h)
|
Handler_&& h)
|
||||||
: beast::stable_async_op_base<
|
: stable_async_op_base<
|
||||||
Handler, beast::detail::get_executor_type<Stream>>(
|
Handler, beast::detail::get_executor_type<Stream>>(
|
||||||
s.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h), s.get_executor())
|
||||||
, d_(beast::allocate_stable<data>(
|
, d_(beast::allocate_stable<data>(
|
||||||
*this, s, m))
|
*this, s, m))
|
||||||
{
|
{
|
||||||
|
@@ -72,9 +72,9 @@ public:
|
|||||||
Handler_&& h,
|
Handler_&& h,
|
||||||
Stream& s,
|
Stream& s,
|
||||||
serializer<isRequest, Body, Fields>& sr)
|
serializer<isRequest, Body, Fields>& sr)
|
||||||
: beast::async_op_base<
|
: async_op_base<
|
||||||
Handler, beast::detail::get_executor_type<Stream>>(
|
Handler, beast::detail::get_executor_type<Stream>>(
|
||||||
s.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h), s.get_executor())
|
||||||
, s_(s)
|
, s_(s)
|
||||||
, sr_(sr)
|
, sr_(sr)
|
||||||
{
|
{
|
||||||
@@ -168,9 +168,9 @@ public:
|
|||||||
Handler_&& h,
|
Handler_&& h,
|
||||||
Stream& s,
|
Stream& s,
|
||||||
serializer<isRequest, Body, Fields>& sr)
|
serializer<isRequest, Body, Fields>& sr)
|
||||||
: beast::async_op_base<
|
: async_op_base<
|
||||||
Handler, beast::detail::get_executor_type<Stream>>(
|
Handler, beast::detail::get_executor_type<Stream>>(
|
||||||
s.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h), s.get_executor())
|
||||||
, s_(s)
|
, s_(s)
|
||||||
, sr_(sr)
|
, sr_(sr)
|
||||||
{
|
{
|
||||||
@@ -229,9 +229,9 @@ public:
|
|||||||
Stream& s,
|
Stream& s,
|
||||||
Handler_&& h,
|
Handler_&& h,
|
||||||
Args&&... args)
|
Args&&... args)
|
||||||
: beast::stable_async_op_base<
|
: stable_async_op_base<
|
||||||
Handler, beast::detail::get_executor_type<Stream>>(
|
Handler, beast::detail::get_executor_type<Stream>>(
|
||||||
s.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h), s.get_executor())
|
||||||
, s_(s)
|
, s_(s)
|
||||||
, sr_(beast::allocate_stable<
|
, sr_(beast::allocate_stable<
|
||||||
serializer<isRequest, Body, Fields>>(
|
serializer<isRequest, Body, Fields>>(
|
||||||
|
@@ -68,9 +68,9 @@ public:
|
|||||||
Handler_&& h,
|
Handler_&& h,
|
||||||
stream<NextLayer, deflateSupported>& ws,
|
stream<NextLayer, deflateSupported>& ws,
|
||||||
Args&&... args)
|
Args&&... args)
|
||||||
: beast::stable_async_op_base<
|
: stable_async_op_base<
|
||||||
Handler, beast::detail::get_executor_type<stream>>(
|
Handler, beast::detail::get_executor_type<stream>>(
|
||||||
ws.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h), ws.get_executor())
|
||||||
, d_(beast::allocate_stable<data>(
|
, d_(beast::allocate_stable<data>(
|
||||||
*this, ws, std::forward<Args>(args)...))
|
*this, ws, std::forward<Args>(args)...))
|
||||||
{
|
{
|
||||||
@@ -136,9 +136,9 @@ public:
|
|||||||
Handler_&& h,
|
Handler_&& h,
|
||||||
stream<NextLayer, deflateSupported>& ws,
|
stream<NextLayer, deflateSupported>& ws,
|
||||||
Args&&... args)
|
Args&&... args)
|
||||||
: beast::stable_async_op_base<
|
: stable_async_op_base<
|
||||||
Handler, beast::detail::get_executor_type<stream>>(
|
Handler, beast::detail::get_executor_type<stream>>(
|
||||||
ws.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h), ws.get_executor())
|
||||||
, d_(beast::allocate_stable<data>(
|
, d_(beast::allocate_stable<data>(
|
||||||
*this, ws, std::forward<Args>(args)...))
|
*this, ws, std::forward<Args>(args)...))
|
||||||
{
|
{
|
||||||
|
@@ -67,9 +67,9 @@ public:
|
|||||||
Handler_&& h,
|
Handler_&& h,
|
||||||
stream<NextLayer, deflateSupported>& ws,
|
stream<NextLayer, deflateSupported>& ws,
|
||||||
close_reason const& cr)
|
close_reason const& cr)
|
||||||
: beast::stable_async_op_base<
|
: stable_async_op_base<
|
||||||
Handler, beast::detail::get_executor_type<stream>>(
|
Handler, beast::detail::get_executor_type<stream>>(
|
||||||
ws.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h), ws.get_executor())
|
||||||
, d_(beast::allocate_stable<state>(
|
, d_(beast::allocate_stable<state>(
|
||||||
*this, ws, cr))
|
*this, ws, cr))
|
||||||
{
|
{
|
||||||
|
@@ -71,9 +71,9 @@ public:
|
|||||||
handshake_op(
|
handshake_op(
|
||||||
Handler_&& h,
|
Handler_&& h,
|
||||||
stream& ws, Args&&... args)
|
stream& ws, Args&&... args)
|
||||||
: beast::stable_async_op_base<Handler,
|
: stable_async_op_base<Handler,
|
||||||
beast::detail::get_executor_type<stream>>(
|
beast::detail::get_executor_type<stream>>(
|
||||||
ws.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h), ws.get_executor())
|
||||||
, d_(beast::allocate_stable<data>(
|
, d_(beast::allocate_stable<data>(
|
||||||
*this, ws, std::forward<Args>(args)...))
|
*this, ws, std::forward<Args>(args)...))
|
||||||
{
|
{
|
||||||
|
@@ -66,9 +66,9 @@ public:
|
|||||||
stream<NextLayer, deflateSupported>& ws,
|
stream<NextLayer, deflateSupported>& ws,
|
||||||
detail::opcode op,
|
detail::opcode op,
|
||||||
ping_data const& payload)
|
ping_data const& payload)
|
||||||
: beast::stable_async_op_base<
|
: stable_async_op_base<
|
||||||
Handler, beast::detail::get_executor_type<stream>>(
|
Handler, beast::detail::get_executor_type<stream>>(
|
||||||
ws.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h), ws.get_executor())
|
||||||
, d_(beast::allocate_stable<state>(
|
, d_(beast::allocate_stable<state>(
|
||||||
*this, ws, op, payload))
|
*this, ws, op, payload))
|
||||||
{
|
{
|
||||||
|
@@ -98,9 +98,9 @@ public:
|
|||||||
Handler_&& h,
|
Handler_&& h,
|
||||||
stream<NextLayer, deflateSupported>& ws,
|
stream<NextLayer, deflateSupported>& ws,
|
||||||
MutableBufferSequence const& bs)
|
MutableBufferSequence const& bs)
|
||||||
: beast::async_op_base<
|
: async_op_base<
|
||||||
Handler, beast::detail::get_executor_type<stream>>(
|
Handler, beast::detail::get_executor_type<stream>>(
|
||||||
ws.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h), ws.get_executor())
|
||||||
, ws_(ws)
|
, ws_(ws)
|
||||||
, bs_(bs)
|
, bs_(bs)
|
||||||
, cb_(bs)
|
, cb_(bs)
|
||||||
@@ -690,9 +690,9 @@ public:
|
|||||||
DynamicBuffer& b,
|
DynamicBuffer& b,
|
||||||
std::size_t limit,
|
std::size_t limit,
|
||||||
bool some)
|
bool some)
|
||||||
: beast::async_op_base<
|
: async_op_base<
|
||||||
Handler, beast::detail::get_executor_type<stream>>(
|
Handler, beast::detail::get_executor_type<stream>>(
|
||||||
ws.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h), ws.get_executor())
|
||||||
, ws_(ws)
|
, ws_(ws)
|
||||||
, b_(b)
|
, b_(b)
|
||||||
, limit_(limit ? limit : (
|
, limit_(limit ? limit : (
|
||||||
|
@@ -43,10 +43,10 @@ public:
|
|||||||
Handler_&& h,
|
Handler_&& h,
|
||||||
socket_type& s,
|
socket_type& s,
|
||||||
role_type role)
|
role_type role)
|
||||||
: beast::async_op_base<
|
: async_op_base<Handler,
|
||||||
Handler, beast::detail::get_executor_type<
|
beast::detail::get_executor_type<
|
||||||
net::ip::tcp::socket>>(s.get_executor(),
|
net::ip::tcp::socket>>(
|
||||||
std::forward<Handler_>(h))
|
std::forward<Handler_>(h), s.get_executor())
|
||||||
, s_(s)
|
, s_(s)
|
||||||
, role_(role)
|
, role_(role)
|
||||||
{
|
{
|
||||||
|
@@ -161,9 +161,9 @@ public:
|
|||||||
stream<NextLayer, deflateSupported>& ws,
|
stream<NextLayer, deflateSupported>& ws,
|
||||||
bool fin,
|
bool fin,
|
||||||
Buffers const& bs)
|
Buffers const& bs)
|
||||||
: beast::async_op_base<
|
: beast::async_op_base<Handler,
|
||||||
Handler, beast::detail::get_executor_type<stream>>(
|
beast::detail::get_executor_type<stream>>(
|
||||||
ws.get_executor(), std::forward<Handler_>(h))
|
std::forward<Handler_>(h), ws.get_executor())
|
||||||
, ws_(ws)
|
, ws_(ws)
|
||||||
, cb_(bs)
|
, cb_(bs)
|
||||||
, fin_(fin)
|
, fin_(fin)
|
||||||
|
@@ -16,6 +16,9 @@ add_executable (tests-beast-core
|
|||||||
${EXTRAS_FILES}
|
${EXTRAS_FILES}
|
||||||
${TEST_MAIN}
|
${TEST_MAIN}
|
||||||
Jamfile
|
Jamfile
|
||||||
|
buffer_test.hpp
|
||||||
|
file_test.hpp
|
||||||
|
test_handler.hpp
|
||||||
_detail_base64.cpp
|
_detail_base64.cpp
|
||||||
_detail_buffer.cpp
|
_detail_buffer.cpp
|
||||||
_detail_clamp.cpp
|
_detail_clamp.cpp
|
||||||
@@ -25,8 +28,6 @@ add_executable (tests-beast-core
|
|||||||
_detail_variant.cpp
|
_detail_variant.cpp
|
||||||
_detail_varint.cpp
|
_detail_varint.cpp
|
||||||
async_op_base.cpp
|
async_op_base.cpp
|
||||||
buffer_test.hpp
|
|
||||||
file_test.hpp
|
|
||||||
basic_stream_socket.cpp
|
basic_stream_socket.cpp
|
||||||
bind_handler.cpp
|
bind_handler.cpp
|
||||||
buffer_traits.cpp
|
buffer_traits.cpp
|
||||||
|
@@ -10,6 +10,8 @@
|
|||||||
// Test that header file is self-contained.
|
// Test that header file is self-contained.
|
||||||
#include <boost/beast/core/async_op_base.hpp>
|
#include <boost/beast/core/async_op_base.hpp>
|
||||||
|
|
||||||
|
#include "test_handler.hpp"
|
||||||
|
|
||||||
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
||||||
#include <boost/beast/_experimental/test/stream.hpp>
|
#include <boost/beast/_experimental/test/stream.hpp>
|
||||||
#include <boost/beast/core/error.hpp>
|
#include <boost/beast/core/error.hpp>
|
||||||
@@ -19,6 +21,7 @@
|
|||||||
#include <boost/asio/system_executor.hpp>
|
#include <boost/asio/system_executor.hpp>
|
||||||
#include <boost/asio/write.hpp>
|
#include <boost/asio/write.hpp>
|
||||||
#include <boost/core/ignore_unused.hpp>
|
#include <boost/core/ignore_unused.hpp>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -104,61 +107,6 @@ struct handler<intrusive_ex, no_alloc>
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
struct legacy_handler
|
|
||||||
{
|
|
||||||
bool invoked = false;
|
|
||||||
struct executor
|
|
||||||
{
|
|
||||||
void* context() { return nullptr; }
|
|
||||||
void on_work_started() {}
|
|
||||||
void on_work_finished() {}
|
|
||||||
template<class F> void dispatch(F&&) {}
|
|
||||||
template<class F> void post(F&&) {}
|
|
||||||
template<class F> void defer(F&&) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
executor
|
|
||||||
get_executor() const noexcept
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Function>
|
|
||||||
void
|
|
||||||
asio_handler_invoke(
|
|
||||||
Function&& f,
|
|
||||||
legacy_handler* p)
|
|
||||||
{
|
|
||||||
p->invoked = true;
|
|
||||||
f();
|
|
||||||
}
|
|
||||||
|
|
||||||
void*
|
|
||||||
asio_handler_allocate(
|
|
||||||
std::size_t,
|
|
||||||
legacy_handler* p)
|
|
||||||
{
|
|
||||||
p->invoked = true;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
asio_handler_deallocate(
|
|
||||||
void*, std::size_t,
|
|
||||||
legacy_handler* p)
|
|
||||||
{
|
|
||||||
p->invoked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
asio_handler_is_continuation(
|
|
||||||
legacy_handler* p)
|
|
||||||
{
|
|
||||||
p->invoked = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // (anon)
|
} // (anon)
|
||||||
|
|
||||||
} // beast
|
} // beast
|
||||||
@@ -207,35 +155,6 @@ struct associated_executor<
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Allocator>
|
|
||||||
struct associated_allocator<
|
|
||||||
boost::beast::legacy_handler, Allocator>
|
|
||||||
{
|
|
||||||
using type = std::allocator<int>;
|
|
||||||
|
|
||||||
static type get(
|
|
||||||
boost::beast::legacy_handler const& h,
|
|
||||||
Allocator const& a = Allocator()) noexcept
|
|
||||||
{
|
|
||||||
return type{};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Executor>
|
|
||||||
struct associated_executor<
|
|
||||||
boost::beast::legacy_handler, Executor>
|
|
||||||
{
|
|
||||||
using type = typename
|
|
||||||
boost::beast::legacy_handler::executor;
|
|
||||||
|
|
||||||
static type get(
|
|
||||||
boost::beast::legacy_handler const&,
|
|
||||||
Executor const& = Executor()) noexcept
|
|
||||||
{
|
|
||||||
return type{};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // asio
|
} // asio
|
||||||
} // boost
|
} // boost
|
||||||
|
|
||||||
@@ -436,75 +355,195 @@ public:
|
|||||||
net::system_executor // ignored
|
net::system_executor // ignored
|
||||||
>>::value);
|
>>::value);
|
||||||
|
|
||||||
struct test_op : async_op_base<
|
struct final_handler
|
||||||
legacy_handler, ex1_type>
|
|
||||||
{
|
|
||||||
test_op()
|
|
||||||
: async_op_base<
|
|
||||||
legacy_handler,
|
|
||||||
ex1_type>(
|
|
||||||
ex1_type{}, legacy_handler{})
|
|
||||||
{
|
{
|
||||||
|
bool& invoked;
|
||||||
|
|
||||||
}
|
void
|
||||||
|
operator()()
|
||||||
bool invoked() const noexcept
|
|
||||||
{
|
{
|
||||||
return this->handler().invoked;
|
invoked = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
testLegacyHooks()
|
testBase()
|
||||||
{
|
{
|
||||||
// asio_handler_invoke
|
// get_allocator
|
||||||
|
{
|
||||||
|
simple_allocator alloc;
|
||||||
|
simple_allocator alloc2;
|
||||||
|
async_op_base<
|
||||||
|
move_only_handler,
|
||||||
|
simple_executor,
|
||||||
|
simple_allocator> op(
|
||||||
|
move_only_handler{}, {}, alloc);
|
||||||
|
BEAST_EXPECT(op.get_allocator() == alloc);
|
||||||
|
BEAST_EXPECT(op.get_allocator() != alloc2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get_executor
|
||||||
|
{
|
||||||
|
simple_executor ex;
|
||||||
|
simple_executor ex2;
|
||||||
|
async_op_base<
|
||||||
|
move_only_handler,
|
||||||
|
simple_executor> op(
|
||||||
|
move_only_handler{}, ex);
|
||||||
|
BEAST_EXPECT(op.get_executor() == ex);
|
||||||
|
BEAST_EXPECT(op.get_executor() != ex2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// move construction
|
||||||
|
{
|
||||||
|
async_op_base<
|
||||||
|
move_only_handler,
|
||||||
|
simple_executor> op(
|
||||||
|
move_only_handler{}, {});
|
||||||
|
auto op2 = std::move(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
// observers
|
||||||
|
{
|
||||||
|
bool b = false;
|
||||||
|
async_op_base<
|
||||||
|
legacy_handler,
|
||||||
|
simple_executor> op(
|
||||||
|
legacy_handler{b}, {});
|
||||||
|
BEAST_EXPECT(! op.handler().hook_invoked);
|
||||||
|
b = true;
|
||||||
|
BEAST_EXPECT(op.handler().hook_invoked);
|
||||||
|
b = false;
|
||||||
|
BEAST_EXPECT(! op.release_handler().hook_invoked);
|
||||||
|
}
|
||||||
|
|
||||||
|
// invocation
|
||||||
{
|
{
|
||||||
test_op h;
|
|
||||||
BEAST_EXPECT(! h.invoked());
|
|
||||||
bool invoked = false;
|
bool invoked = false;
|
||||||
using net::asio_handler_invoke;
|
async_op_base<
|
||||||
asio_handler_invoke(
|
final_handler,
|
||||||
[&invoked]
|
simple_executor> op(
|
||||||
{
|
final_handler{invoked}, {});
|
||||||
invoked =true;
|
op.invoke();
|
||||||
}, &h);
|
|
||||||
BEAST_EXPECT(invoked);
|
BEAST_EXPECT(invoked);
|
||||||
BEAST_EXPECT(h.invoked());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// asio_handler_allocate
|
// legacy hooks
|
||||||
|
legacy_handler::test(*this,
|
||||||
|
[](legacy_handler h)
|
||||||
{
|
{
|
||||||
test_op h;
|
return async_op_base<
|
||||||
BEAST_EXPECT(! h.invoked());
|
legacy_handler,
|
||||||
using net::asio_handler_allocate;
|
simple_executor>(
|
||||||
asio_handler_allocate(0, &h);
|
std::move(h), {});
|
||||||
BEAST_EXPECT(h.invoked());
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// asio_handler_deallocate
|
|
||||||
{
|
|
||||||
test_op h;
|
|
||||||
BEAST_EXPECT(! h.invoked());
|
|
||||||
using net::asio_handler_deallocate;
|
|
||||||
asio_handler_deallocate(nullptr, 0, &h);
|
|
||||||
BEAST_EXPECT(h.invoked());
|
|
||||||
}
|
|
||||||
|
|
||||||
// asio_handler_deallocate
|
|
||||||
{
|
|
||||||
test_op h;
|
|
||||||
BEAST_EXPECT(! h.invoked());
|
|
||||||
using net::asio_handler_is_continuation;
|
|
||||||
asio_handler_is_continuation(&h);
|
|
||||||
BEAST_EXPECT(h.invoked());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
testSpecialMembers()
|
testStableBase()
|
||||||
{
|
{
|
||||||
test_op h1;
|
// get_allocator
|
||||||
test_op h2(std::move(h1));
|
{
|
||||||
|
simple_allocator alloc;
|
||||||
|
simple_allocator alloc2;
|
||||||
|
stable_async_op_base<
|
||||||
|
move_only_handler,
|
||||||
|
simple_executor,
|
||||||
|
simple_allocator> op(
|
||||||
|
move_only_handler{}, {}, alloc);
|
||||||
|
BEAST_EXPECT(op.get_allocator() == alloc);
|
||||||
|
BEAST_EXPECT(op.get_allocator() != alloc2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get_executor
|
||||||
|
{
|
||||||
|
simple_executor ex;
|
||||||
|
simple_executor ex2;
|
||||||
|
stable_async_op_base<
|
||||||
|
move_only_handler,
|
||||||
|
simple_executor> op(
|
||||||
|
move_only_handler{}, ex);
|
||||||
|
BEAST_EXPECT(op.get_executor() == ex);
|
||||||
|
BEAST_EXPECT(op.get_executor() != ex2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// move construction
|
||||||
|
{
|
||||||
|
stable_async_op_base<
|
||||||
|
move_only_handler,
|
||||||
|
simple_executor> op(
|
||||||
|
move_only_handler{}, {});
|
||||||
|
auto op2 = std::move(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
// invocation
|
||||||
|
{
|
||||||
|
bool invoked = false;
|
||||||
|
stable_async_op_base<
|
||||||
|
final_handler,
|
||||||
|
simple_executor> op(
|
||||||
|
final_handler{invoked}, {});
|
||||||
|
op.invoke();
|
||||||
|
BEAST_EXPECT(invoked);
|
||||||
|
}
|
||||||
|
|
||||||
|
// legacy hooks
|
||||||
|
legacy_handler::test(*this,
|
||||||
|
[](legacy_handler h)
|
||||||
|
{
|
||||||
|
return stable_async_op_base<
|
||||||
|
legacy_handler,
|
||||||
|
simple_executor>(
|
||||||
|
std::move(h), {});
|
||||||
|
});
|
||||||
|
|
||||||
|
// allocate_stable
|
||||||
|
|
||||||
|
{
|
||||||
|
bool destroyed = false;
|
||||||
|
{
|
||||||
|
struct data
|
||||||
|
{
|
||||||
|
bool& destroyed;
|
||||||
|
|
||||||
|
~data()
|
||||||
|
{
|
||||||
|
destroyed = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
stable_async_op_base<
|
||||||
|
move_only_handler,
|
||||||
|
simple_executor> op(
|
||||||
|
move_only_handler{}, {});
|
||||||
|
BEAST_EXPECT(! destroyed);
|
||||||
|
auto& d = allocate_stable<data>(op, destroyed);
|
||||||
|
BEAST_EXPECT(! d.destroyed);
|
||||||
|
}
|
||||||
|
BEAST_EXPECT(destroyed);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
struct throwing_data
|
||||||
|
{
|
||||||
|
throwing_data()
|
||||||
|
{
|
||||||
|
BOOST_THROW_EXCEPTION(
|
||||||
|
std::exception{});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
stable_async_op_base<
|
||||||
|
move_only_handler,
|
||||||
|
simple_executor> op(
|
||||||
|
move_only_handler{}, {});
|
||||||
|
try
|
||||||
|
{
|
||||||
|
allocate_stable<throwing_data>(op);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch(std::exception const&)
|
||||||
|
{
|
||||||
|
pass();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
@@ -527,7 +566,7 @@ public:
|
|||||||
AsyncReadStream& stream,
|
AsyncReadStream& stream,
|
||||||
net::mutable_buffer buffer,
|
net::mutable_buffer buffer,
|
||||||
handler_type& handler)
|
handler_type& handler)
|
||||||
: base_type(stream.get_executor(), std::move(handler))
|
: base_type(std::move(handler), stream.get_executor())
|
||||||
, stream_(stream)
|
, stream_(stream)
|
||||||
, buffer_(buffer)
|
, buffer_(buffer)
|
||||||
, total_bytes_transferred_(0)
|
, total_bytes_transferred_(0)
|
||||||
@@ -599,7 +638,7 @@ public:
|
|||||||
temporary_data& data_;
|
temporary_data& data_;
|
||||||
|
|
||||||
op(AsyncWriteStream& stream, std::size_t repeats, std::string message, handler_type& handler)
|
op(AsyncWriteStream& stream, std::size_t repeats, std::string message, handler_type& handler)
|
||||||
: base_type(stream.get_executor(), std::move(handler))
|
: base_type(std::move(handler), stream.get_executor())
|
||||||
, state_(starting)
|
, state_(starting)
|
||||||
, stream_(stream)
|
, stream_(stream)
|
||||||
, repeats_(repeats)
|
, repeats_(repeats)
|
||||||
@@ -672,8 +711,8 @@ public:
|
|||||||
void
|
void
|
||||||
run() override
|
run() override
|
||||||
{
|
{
|
||||||
testLegacyHooks();
|
testBase();
|
||||||
testSpecialMembers();
|
testStableBase();
|
||||||
testJavadocs();
|
testJavadocs();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -21,22 +21,90 @@
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
namespace beast {
|
namespace beast {
|
||||||
|
|
||||||
// Used to test the legacy handler hooks
|
class simple_allocator
|
||||||
struct legacy_handler
|
|
||||||
{
|
{
|
||||||
bool& hook_invoked;
|
std::size_t id_;
|
||||||
|
|
||||||
struct executor
|
public:
|
||||||
|
simple_allocator()
|
||||||
|
: id_([]
|
||||||
{
|
{
|
||||||
|
static std::size_t n = 0;
|
||||||
|
return ++n;
|
||||||
|
}())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
bool operator==(
|
||||||
|
simple_allocator const& lhs,
|
||||||
|
simple_allocator const& rhs) noexcept
|
||||||
|
{
|
||||||
|
return lhs.id_ == rhs.id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
bool operator!=(
|
||||||
|
simple_allocator const& lhs,
|
||||||
|
simple_allocator const& rhs) noexcept
|
||||||
|
{
|
||||||
|
return lhs.id_ != rhs.id_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class simple_executor
|
||||||
|
{
|
||||||
|
std::size_t id_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
simple_executor()
|
||||||
|
: id_([]
|
||||||
|
{
|
||||||
|
static std::size_t n = 0;
|
||||||
|
return ++n;
|
||||||
|
}())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void* context() { return nullptr; }
|
void* context() { return nullptr; }
|
||||||
void on_work_started() {}
|
void on_work_started() {}
|
||||||
void on_work_finished() {}
|
void on_work_finished() {}
|
||||||
template<class F> void dispatch(F&&) {}
|
template<class F> void dispatch(F&&) {}
|
||||||
template<class F> void post(F&&) {}
|
template<class F> void post(F&&) {}
|
||||||
template<class F> void defer(F&&) {}
|
template<class F> void defer(F&&) {}
|
||||||
};
|
|
||||||
|
|
||||||
executor
|
friend
|
||||||
|
bool operator==(
|
||||||
|
simple_executor const& lhs,
|
||||||
|
simple_executor const& rhs) noexcept
|
||||||
|
{
|
||||||
|
return lhs.id_ == rhs.id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
bool operator!=(
|
||||||
|
simple_executor const& lhs,
|
||||||
|
simple_executor const& rhs) noexcept
|
||||||
|
{
|
||||||
|
return lhs.id_ != rhs.id_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// A move-only handler
|
||||||
|
struct move_only_handler
|
||||||
|
{
|
||||||
|
move_only_handler() = default;
|
||||||
|
move_only_handler(move_only_handler&&) = default;
|
||||||
|
move_only_handler(move_only_handler const&) = delete;
|
||||||
|
void operator()() const{};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Used to test the legacy handler hooks
|
||||||
|
struct legacy_handler
|
||||||
|
{
|
||||||
|
bool& hook_invoked;
|
||||||
|
|
||||||
|
simple_executor
|
||||||
get_executor() const noexcept
|
get_executor() const noexcept
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
@@ -126,4 +194,39 @@ asio_handler_is_continuation(
|
|||||||
} // beast
|
} // beast
|
||||||
} // boost
|
} // boost
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace asio {
|
||||||
|
|
||||||
|
template<class Allocator>
|
||||||
|
struct associated_allocator<
|
||||||
|
boost::beast::legacy_handler, Allocator>
|
||||||
|
{
|
||||||
|
using type = std::allocator<int>;
|
||||||
|
|
||||||
|
static type get(
|
||||||
|
boost::beast::legacy_handler const& h,
|
||||||
|
Allocator const& a = Allocator()) noexcept
|
||||||
|
{
|
||||||
|
return type{};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Executor>
|
||||||
|
struct associated_executor<
|
||||||
|
boost::beast::legacy_handler, Executor>
|
||||||
|
{
|
||||||
|
using type = typename
|
||||||
|
boost::beast::simple_executor;
|
||||||
|
|
||||||
|
static type get(
|
||||||
|
boost::beast::legacy_handler const&,
|
||||||
|
Executor const& = Executor()) noexcept
|
||||||
|
{
|
||||||
|
return type{};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // asio
|
||||||
|
} // boost
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user