mirror of
https://github.com/boostorg/beast.git
synced 2025-08-01 05:44:38 +02:00
Add tests for async_op_base
This commit is contained in:
@@ -7,6 +7,7 @@ Version 202
|
||||
* Use async_op_base
|
||||
* async_op_base is a public interface
|
||||
* Add tests for bind_back_handler
|
||||
* Add tests for async_op_base
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
@@ -61,8 +61,8 @@ public:
|
||||
Handler_&& h)
|
||||
: async_op_base<Handler,
|
||||
detail::get_executor_type<flat_stream>>(
|
||||
s.get_executor(),
|
||||
std::forward<Handler_>(h))
|
||||
std::forward<Handler_>(h),
|
||||
s.get_executor())
|
||||
, s_(s)
|
||||
, b_(b)
|
||||
, p_(nullptr, deleter{alloc_type{}})
|
||||
|
@@ -151,9 +151,9 @@ public:
|
||||
Handler_&& h,
|
||||
icy_stream& s,
|
||||
MutableBufferSequence const& b)
|
||||
: beast::stable_async_op_base<Handler,
|
||||
: stable_async_op_base<Handler,
|
||||
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))
|
||||
{
|
||||
(*this)({}, 0);
|
||||
|
@@ -91,7 +91,7 @@ namespace beast {
|
||||
AsyncReadStream& stream,
|
||||
net::mutable_buffer buffer,
|
||||
handler_type& handler)
|
||||
: base_type(stream.get_executor(), std::move(handler))
|
||||
: base_type(std::move(handler), stream.get_executor())
|
||||
, stream_(stream)
|
||||
, buffer_(buffer)
|
||||
, total_bytes_transferred_(0)
|
||||
@@ -197,6 +197,56 @@ class async_op_base
|
||||
}
|
||||
|
||||
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
|
||||
async_op_base(async_op_base&& other) = default;
|
||||
|
||||
@@ -264,56 +314,6 @@ public:
|
||||
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.
|
||||
|
||||
This invokes the final completion handler with the specified
|
||||
@@ -334,7 +334,6 @@ protected:
|
||||
}
|
||||
|
||||
#if ! BOOST_BEAST_DOXYGEN
|
||||
public:
|
||||
template<
|
||||
class Handler_,
|
||||
class Executor1_,
|
||||
@@ -480,7 +479,7 @@ public:
|
||||
enum { starting, waiting, writing } state_;
|
||||
|
||||
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)
|
||||
, repeats_(repeats)
|
||||
, state_(starting)
|
||||
@@ -570,15 +569,6 @@ class stable_async_op_base
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@param handler The final completion handler. The type of this
|
||||
@@ -609,26 +599,34 @@ protected:
|
||||
>::value>::type
|
||||
>
|
||||
stable_async_op_base(
|
||||
Executor1 const& ex1,
|
||||
Handler_&& handler)
|
||||
Handler_&& handler,
|
||||
Executor1 const& ex1)
|
||||
: async_op_base<
|
||||
Handler, Executor1, Allocator>(
|
||||
ex1, std::forward<Handler_>(handler))
|
||||
std::forward<Handler_>(handler), ex1)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Handler_>
|
||||
stable_async_op_base(
|
||||
Executor1 const& ex1,
|
||||
Handler_&& handler,
|
||||
Executor1 const& ex1,
|
||||
Allocator const& alloc)
|
||||
: async_op_base<
|
||||
Handler, Executor1, Allocator>(
|
||||
ex1, std::forward<Handler_>(handler))
|
||||
std::forward<Handler_>(handler), ex1, alloc)
|
||||
{
|
||||
}
|
||||
#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
|
||||
|
||||
If the completion handler was not invoked, then any
|
||||
@@ -676,6 +674,40 @@ void asio_handler_invoke(
|
||||
}
|
||||
#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.
|
||||
|
||||
The object will be destroyed just before the completion
|
||||
@@ -695,44 +727,19 @@ allocate_stable(
|
||||
Handler, Executor1, Allocator>& base,
|
||||
Args&&... args)
|
||||
{
|
||||
struct state;
|
||||
|
||||
using allocator_type = typename stable_async_op_base<
|
||||
Handler, Executor1, Allocator>::allocator_type;
|
||||
|
||||
using A = typename detail::allocator_traits<
|
||||
allocator_type>::template rebind_alloc<state>;
|
||||
|
||||
struct state final
|
||||
: 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);
|
||||
}
|
||||
};
|
||||
allocator_type>::template rebind_alloc<
|
||||
detail::allocate_stable_state<
|
||||
State, allocator_type>>;
|
||||
|
||||
struct deleter
|
||||
{
|
||||
allocator_type alloc;
|
||||
state* ptr;
|
||||
detail::allocate_stable_state<
|
||||
State, allocator_type>* ptr;
|
||||
|
||||
~deleter()
|
||||
{
|
||||
@@ -748,9 +755,9 @@ allocate_stable(
|
||||
deleter d{base.get_allocator(), nullptr};
|
||||
d.ptr = detail::allocator_traits<A>::allocate(a, 1);
|
||||
detail::allocator_traits<A>::construct(a, d.ptr,
|
||||
d.alloc,
|
||||
base.list_,
|
||||
std::forward<Args>(args)...);
|
||||
d.alloc, std::forward<Args>(args)...);
|
||||
d.ptr->next_ = base.list_;
|
||||
base.list_ = d.ptr;
|
||||
return boost::exchange(d.ptr, nullptr)->value;
|
||||
}
|
||||
|
||||
|
@@ -30,14 +30,13 @@ struct stable_base
|
||||
}
|
||||
}
|
||||
|
||||
stable_base* next_ = nullptr;
|
||||
|
||||
protected:
|
||||
stable_base* next_;
|
||||
virtual void destroy() = 0;
|
||||
stable_base() = default;
|
||||
virtual ~stable_base() = default;
|
||||
explicit stable_base(stable_base*& list)
|
||||
: next_(boost::exchange(list, this))
|
||||
{
|
||||
}
|
||||
|
||||
virtual void destroy() = 0;
|
||||
};
|
||||
|
||||
} // detail
|
||||
|
@@ -18,9 +18,6 @@
|
||||
#include <boost/asio/coroutine.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
// REMOVE
|
||||
#define BOOST_BEAST_ENABLE_NON_BLOCKING
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
@@ -56,9 +53,10 @@ public:
|
||||
DynamicBuffer& b,
|
||||
Condition cond,
|
||||
Handler_&& h)
|
||||
: async_op_base<
|
||||
Handler, get_executor_type<Stream>>(
|
||||
s.get_executor(), std::forward<Handler_>(h))
|
||||
: async_op_base<Handler,
|
||||
get_executor_type<Stream>>(
|
||||
std::forward<Handler_>(h),
|
||||
s.get_executor())
|
||||
, s_(s)
|
||||
, b_(b)
|
||||
, cond_(cond)
|
||||
|
@@ -107,7 +107,7 @@ public:
|
||||
Buffers const& b,
|
||||
Handler_&& h)
|
||||
: async_op_base<Handler, Executor>(
|
||||
s.get_executor(), std::forward<Handler_>(h))
|
||||
std::forward<Handler_>(h), s.get_executor())
|
||||
, impl_(*s.impl_)
|
||||
, pg_(impl_.read_pending)
|
||||
, b_(b)
|
||||
@@ -224,7 +224,7 @@ public:
|
||||
Buffers const& b,
|
||||
Handler_&& h)
|
||||
: async_op_base<Handler, Executor>(
|
||||
s.get_executor(), std::forward<Handler_>(h))
|
||||
std::forward<Handler_>(h), s.get_executor())
|
||||
, impl_(*s.impl_)
|
||||
, pg_(impl_.write_pending)
|
||||
, b_(b)
|
||||
@@ -350,7 +350,7 @@ public:
|
||||
Condition cond,
|
||||
Handler_&& h)
|
||||
: async_op_base<Handler, Executor>(
|
||||
s.get_executor(), std::forward<Handler_>(h))
|
||||
std::forward<Handler_>(h), s.get_executor())
|
||||
, impl_(*s.impl_)
|
||||
, pg0_(impl_.read_pending)
|
||||
, pg1_(impl_.write_pending)
|
||||
@@ -377,7 +377,7 @@ public:
|
||||
Condition cond,
|
||||
Handler_&& h)
|
||||
: async_op_base<Handler, Executor>(
|
||||
s.get_executor(), std::forward<Handler_>(h))
|
||||
std::forward<Handler_>(h), s.get_executor())
|
||||
, impl_(*s.impl_)
|
||||
, pg0_(impl_.read_pending)
|
||||
, pg1_(impl_.write_pending)
|
||||
|
@@ -44,7 +44,7 @@ public:
|
||||
MutableBufferSequence const& b)
|
||||
: async_op_base<
|
||||
Handler, detail::get_executor_type<buffered_read_stream>>(
|
||||
s.get_executor(), std::forward<Handler_>(h))
|
||||
std::forward<Handler_>(h), s.get_executor())
|
||||
, s_(s)
|
||||
, b_(b)
|
||||
{
|
||||
|
@@ -350,11 +350,11 @@ public:
|
||||
net::basic_stream_socket<Protocol>& s,
|
||||
serializer<isRequest,
|
||||
basic_file_body<file_win32>,Fields>& sr)
|
||||
: beast::async_op_base<
|
||||
: async_op_base<
|
||||
Handler, typename net::basic_stream_socket<
|
||||
Protocol>::executor_type>(
|
||||
s.get_executor(),
|
||||
std::forward<Handler_>(h))
|
||||
std::forward<Handler_>(h),
|
||||
s.get_executor())
|
||||
, sock_(s)
|
||||
, sr_(sr)
|
||||
{
|
||||
|
@@ -184,9 +184,9 @@ public:
|
||||
DynamicBuffer& b,
|
||||
message_type& m,
|
||||
Handler_&& h)
|
||||
: beast::stable_async_op_base<
|
||||
: stable_async_op_base<
|
||||
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>(
|
||||
*this, s, m))
|
||||
{
|
||||
|
@@ -72,9 +72,9 @@ public:
|
||||
Handler_&& h,
|
||||
Stream& s,
|
||||
serializer<isRequest, Body, Fields>& sr)
|
||||
: beast::async_op_base<
|
||||
: async_op_base<
|
||||
Handler, beast::detail::get_executor_type<Stream>>(
|
||||
s.get_executor(), std::forward<Handler_>(h))
|
||||
std::forward<Handler_>(h), s.get_executor())
|
||||
, s_(s)
|
||||
, sr_(sr)
|
||||
{
|
||||
@@ -168,9 +168,9 @@ public:
|
||||
Handler_&& h,
|
||||
Stream& s,
|
||||
serializer<isRequest, Body, Fields>& sr)
|
||||
: beast::async_op_base<
|
||||
: async_op_base<
|
||||
Handler, beast::detail::get_executor_type<Stream>>(
|
||||
s.get_executor(), std::forward<Handler_>(h))
|
||||
std::forward<Handler_>(h), s.get_executor())
|
||||
, s_(s)
|
||||
, sr_(sr)
|
||||
{
|
||||
@@ -229,9 +229,9 @@ public:
|
||||
Stream& s,
|
||||
Handler_&& h,
|
||||
Args&&... args)
|
||||
: beast::stable_async_op_base<
|
||||
: stable_async_op_base<
|
||||
Handler, beast::detail::get_executor_type<Stream>>(
|
||||
s.get_executor(), std::forward<Handler_>(h))
|
||||
std::forward<Handler_>(h), s.get_executor())
|
||||
, s_(s)
|
||||
, sr_(beast::allocate_stable<
|
||||
serializer<isRequest, Body, Fields>>(
|
||||
|
@@ -68,9 +68,9 @@ public:
|
||||
Handler_&& h,
|
||||
stream<NextLayer, deflateSupported>& ws,
|
||||
Args&&... args)
|
||||
: beast::stable_async_op_base<
|
||||
: stable_async_op_base<
|
||||
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>(
|
||||
*this, ws, std::forward<Args>(args)...))
|
||||
{
|
||||
@@ -136,9 +136,9 @@ public:
|
||||
Handler_&& h,
|
||||
stream<NextLayer, deflateSupported>& ws,
|
||||
Args&&... args)
|
||||
: beast::stable_async_op_base<
|
||||
: stable_async_op_base<
|
||||
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>(
|
||||
*this, ws, std::forward<Args>(args)...))
|
||||
{
|
||||
|
@@ -67,9 +67,9 @@ public:
|
||||
Handler_&& h,
|
||||
stream<NextLayer, deflateSupported>& ws,
|
||||
close_reason const& cr)
|
||||
: beast::stable_async_op_base<
|
||||
: stable_async_op_base<
|
||||
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>(
|
||||
*this, ws, cr))
|
||||
{
|
||||
|
@@ -71,9 +71,9 @@ public:
|
||||
handshake_op(
|
||||
Handler_&& h,
|
||||
stream& ws, Args&&... args)
|
||||
: beast::stable_async_op_base<Handler,
|
||||
: stable_async_op_base<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>(
|
||||
*this, ws, std::forward<Args>(args)...))
|
||||
{
|
||||
|
@@ -66,9 +66,9 @@ public:
|
||||
stream<NextLayer, deflateSupported>& ws,
|
||||
detail::opcode op,
|
||||
ping_data const& payload)
|
||||
: beast::stable_async_op_base<
|
||||
: stable_async_op_base<
|
||||
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>(
|
||||
*this, ws, op, payload))
|
||||
{
|
||||
|
@@ -98,9 +98,9 @@ public:
|
||||
Handler_&& h,
|
||||
stream<NextLayer, deflateSupported>& ws,
|
||||
MutableBufferSequence const& bs)
|
||||
: beast::async_op_base<
|
||||
: async_op_base<
|
||||
Handler, beast::detail::get_executor_type<stream>>(
|
||||
ws.get_executor(), std::forward<Handler_>(h))
|
||||
std::forward<Handler_>(h), ws.get_executor())
|
||||
, ws_(ws)
|
||||
, bs_(bs)
|
||||
, cb_(bs)
|
||||
@@ -690,9 +690,9 @@ public:
|
||||
DynamicBuffer& b,
|
||||
std::size_t limit,
|
||||
bool some)
|
||||
: beast::async_op_base<
|
||||
: async_op_base<
|
||||
Handler, beast::detail::get_executor_type<stream>>(
|
||||
ws.get_executor(), std::forward<Handler_>(h))
|
||||
std::forward<Handler_>(h), ws.get_executor())
|
||||
, ws_(ws)
|
||||
, b_(b)
|
||||
, limit_(limit ? limit : (
|
||||
|
@@ -43,10 +43,10 @@ public:
|
||||
Handler_&& h,
|
||||
socket_type& s,
|
||||
role_type role)
|
||||
: beast::async_op_base<
|
||||
Handler, beast::detail::get_executor_type<
|
||||
net::ip::tcp::socket>>(s.get_executor(),
|
||||
std::forward<Handler_>(h))
|
||||
: async_op_base<Handler,
|
||||
beast::detail::get_executor_type<
|
||||
net::ip::tcp::socket>>(
|
||||
std::forward<Handler_>(h), s.get_executor())
|
||||
, s_(s)
|
||||
, role_(role)
|
||||
{
|
||||
|
@@ -161,9 +161,9 @@ public:
|
||||
stream<NextLayer, deflateSupported>& ws,
|
||||
bool fin,
|
||||
Buffers const& bs)
|
||||
: beast::async_op_base<
|
||||
Handler, beast::detail::get_executor_type<stream>>(
|
||||
ws.get_executor(), std::forward<Handler_>(h))
|
||||
: beast::async_op_base<Handler,
|
||||
beast::detail::get_executor_type<stream>>(
|
||||
std::forward<Handler_>(h), ws.get_executor())
|
||||
, ws_(ws)
|
||||
, cb_(bs)
|
||||
, fin_(fin)
|
||||
|
@@ -16,6 +16,9 @@ add_executable (tests-beast-core
|
||||
${EXTRAS_FILES}
|
||||
${TEST_MAIN}
|
||||
Jamfile
|
||||
buffer_test.hpp
|
||||
file_test.hpp
|
||||
test_handler.hpp
|
||||
_detail_base64.cpp
|
||||
_detail_buffer.cpp
|
||||
_detail_clamp.cpp
|
||||
@@ -25,8 +28,6 @@ add_executable (tests-beast-core
|
||||
_detail_variant.cpp
|
||||
_detail_varint.cpp
|
||||
async_op_base.cpp
|
||||
buffer_test.hpp
|
||||
file_test.hpp
|
||||
basic_stream_socket.cpp
|
||||
bind_handler.cpp
|
||||
buffer_traits.cpp
|
||||
|
@@ -10,6 +10,8 @@
|
||||
// Test that header file is self-contained.
|
||||
#include <boost/beast/core/async_op_base.hpp>
|
||||
|
||||
#include "test_handler.hpp"
|
||||
|
||||
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
||||
#include <boost/beast/_experimental/test/stream.hpp>
|
||||
#include <boost/beast/core/error.hpp>
|
||||
@@ -19,6 +21,7 @@
|
||||
#include <boost/asio/system_executor.hpp>
|
||||
#include <boost/asio/write.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)
|
||||
|
||||
} // 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
|
||||
} // boost
|
||||
|
||||
@@ -436,75 +355,195 @@ public:
|
||||
net::system_executor // ignored
|
||||
>>::value);
|
||||
|
||||
struct test_op : async_op_base<
|
||||
legacy_handler, ex1_type>
|
||||
struct final_handler
|
||||
{
|
||||
test_op()
|
||||
: async_op_base<
|
||||
legacy_handler,
|
||||
ex1_type>(
|
||||
ex1_type{}, legacy_handler{})
|
||||
{
|
||||
bool& invoked;
|
||||
|
||||
}
|
||||
|
||||
bool invoked() const noexcept
|
||||
void
|
||||
operator()()
|
||||
{
|
||||
return this->handler().invoked;
|
||||
invoked = true;
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
using net::asio_handler_invoke;
|
||||
asio_handler_invoke(
|
||||
[&invoked]
|
||||
{
|
||||
invoked =true;
|
||||
}, &h);
|
||||
async_op_base<
|
||||
final_handler,
|
||||
simple_executor> op(
|
||||
final_handler{invoked}, {});
|
||||
op.invoke();
|
||||
BEAST_EXPECT(invoked);
|
||||
BEAST_EXPECT(h.invoked());
|
||||
}
|
||||
|
||||
// asio_handler_allocate
|
||||
{
|
||||
test_op h;
|
||||
BEAST_EXPECT(! h.invoked());
|
||||
using net::asio_handler_allocate;
|
||||
asio_handler_allocate(0, &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());
|
||||
}
|
||||
// legacy hooks
|
||||
legacy_handler::test(*this,
|
||||
[](legacy_handler h)
|
||||
{
|
||||
return async_op_base<
|
||||
legacy_handler,
|
||||
simple_executor>(
|
||||
std::move(h), {});
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
testSpecialMembers()
|
||||
testStableBase()
|
||||
{
|
||||
test_op h1;
|
||||
test_op h2(std::move(h1));
|
||||
// get_allocator
|
||||
{
|
||||
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,
|
||||
net::mutable_buffer buffer,
|
||||
handler_type& handler)
|
||||
: base_type(stream.get_executor(), std::move(handler))
|
||||
: base_type(std::move(handler), stream.get_executor())
|
||||
, stream_(stream)
|
||||
, buffer_(buffer)
|
||||
, total_bytes_transferred_(0)
|
||||
@@ -599,7 +638,7 @@ public:
|
||||
temporary_data& data_;
|
||||
|
||||
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)
|
||||
, stream_(stream)
|
||||
, repeats_(repeats)
|
||||
@@ -672,8 +711,8 @@ public:
|
||||
void
|
||||
run() override
|
||||
{
|
||||
testLegacyHooks();
|
||||
testSpecialMembers();
|
||||
testBase();
|
||||
testStableBase();
|
||||
testJavadocs();
|
||||
}
|
||||
};
|
||||
|
@@ -21,22 +21,90 @@
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
|
||||
class simple_allocator
|
||||
{
|
||||
std::size_t id_;
|
||||
|
||||
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 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&&) {}
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
simple_executor
|
||||
get_executor() const noexcept
|
||||
{
|
||||
return {};
|
||||
@@ -126,4 +194,39 @@ asio_handler_is_continuation(
|
||||
} // beast
|
||||
} // 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
|
||||
|
Reference in New Issue
Block a user