mirror of
https://github.com/boostorg/beast.git
synced 2025-07-29 20:37:31 +02:00
Add async_op_base::invoke
This commit is contained in:
@ -6,6 +6,7 @@ Version 215:
|
||||
* Examples use bind_front_handler
|
||||
* Add experimental test/handler.hpp
|
||||
* Rename to async_op_base::invoke_now
|
||||
* Add async_op_base::invoke
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
@ -357,6 +357,7 @@
|
||||
<member><link linkend="beast.ref.boost__beast__ssl_stream">ssl_stream</link></member>
|
||||
<member><link linkend="beast.ref.boost__beast__http__icy_stream">http::icy_stream</link></member>
|
||||
<member><link linkend="beast.ref.boost__beast__test__fail_count">test::fail_count</link></member>
|
||||
<member><link linkend="beast.ref.boost__beast__test__handler">test::handler</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__test__stream">test::stream</link></member>
|
||||
</simplelist>
|
||||
</entry>
|
||||
@ -364,6 +365,9 @@
|
||||
<bridgehead renderas="sect3">Functions</bridgehead>
|
||||
<simplelist type="vert" columns="1">
|
||||
<member><link linkend="beast.ref.boost__beast__test__connect">test::connect</link></member>
|
||||
<member><link linkend="beast.ref.boost__beast__test__any_handler">test::any_handler</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__test__fail_handler">test::fail_handler</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__test__success_handler">test::success_handler</link> <emphasis role="green">🞲</emphasis></member>
|
||||
</simplelist>
|
||||
</entry>
|
||||
<entry valign="top">
|
||||
|
@ -19,8 +19,17 @@ namespace boost {
|
||||
namespace beast {
|
||||
namespace test {
|
||||
|
||||
namespace detail {
|
||||
/** A CompletionHandler used for testing.
|
||||
|
||||
This completion handler is used by tests to ensure correctness
|
||||
of behavior. It is designed as a single type to reduce template
|
||||
instantiations, with configurable settings through constructor
|
||||
arguments. Typically this type will be used in type lists and
|
||||
not instantiated directly; instances of this class are returned
|
||||
by the helper functions listed below.
|
||||
|
||||
@see @ref success_handler, @ref fail_handler, @ref any_handler
|
||||
*/
|
||||
class handler
|
||||
{
|
||||
boost::optional<error_code> ec_;
|
||||
@ -61,6 +70,14 @@ public:
|
||||
pass_ = true;
|
||||
}
|
||||
|
||||
void
|
||||
operator()()
|
||||
{
|
||||
BEAST_EXPECT(! pass_); // can't call twice
|
||||
BEAST_EXPECT(! ec_);
|
||||
pass_ = true;
|
||||
}
|
||||
|
||||
template<class Arg0, class... Args,
|
||||
class = typename std::enable_if<
|
||||
! std::is_convertible<Arg0, error_code>::value>::type>
|
||||
@ -73,8 +90,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
|
||||
/** Return a test CompletionHandler which requires success.
|
||||
|
||||
The returned handler can be invoked with any signature whose
|
||||
@ -86,14 +101,10 @@ public:
|
||||
@li The handler is invoked with a non-successful error code.
|
||||
*/
|
||||
inline
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
__implementation_defined__
|
||||
#else
|
||||
detail::handler
|
||||
#endif
|
||||
handler
|
||||
success_handler() noexcept
|
||||
{
|
||||
return detail::handler(error_code{});
|
||||
return handler(error_code{});
|
||||
}
|
||||
|
||||
/** Return a test CompletionHandler which requires invocation.
|
||||
@ -104,14 +115,10 @@ success_handler() noexcept
|
||||
@li The handler is destroyed without being invoked.
|
||||
*/
|
||||
inline
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
__implementation_defined__
|
||||
#else
|
||||
detail::handler
|
||||
#endif
|
||||
handler
|
||||
any_handler() noexcept
|
||||
{
|
||||
return detail::handler(boost::none);
|
||||
return handler(boost::none);
|
||||
}
|
||||
|
||||
/** Return a test CompletionHandler which requires a specific error code.
|
||||
@ -127,14 +134,10 @@ any_handler() noexcept
|
||||
@param ec The error code to specify.
|
||||
*/
|
||||
inline
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
__implementation_defined__
|
||||
#else
|
||||
detail::handler
|
||||
#endif
|
||||
handler
|
||||
fail_handler(error_code ec) noexcept
|
||||
{
|
||||
return detail::handler(ec);
|
||||
return handler(ec);
|
||||
}
|
||||
|
||||
} // test
|
||||
|
@ -61,8 +61,8 @@ namespace test {
|
||||
To facilitate testing, these streams support some additional
|
||||
features:
|
||||
|
||||
@li The input area, represented by a @ref flat_buffer, may
|
||||
be directly accessed by the caller to inspect the contents
|
||||
@li The input area, represented by a @ref basic_flat_buffer,
|
||||
may be directly accessed by the caller to inspect the contents
|
||||
before or after the remote endpoint writes data. This allows
|
||||
a unit test to verify that the received data matches.
|
||||
|
||||
|
@ -11,14 +11,17 @@
|
||||
#define BOOST_BEAST_CORE_ASYNC_OP_BASE_HPP
|
||||
|
||||
#include <boost/beast/core/detail/config.hpp>
|
||||
#include <boost/beast/core/bind_handler.hpp>
|
||||
#include <boost/beast/core/detail/allocator.hpp>
|
||||
#include <boost/beast/core/detail/async_op_base.hpp>
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/bind_executor.hpp>
|
||||
#include <boost/asio/executor_work_guard.hpp>
|
||||
#include <boost/asio/handler_alloc_hook.hpp>
|
||||
#include <boost/asio/handler_continuation_hook.hpp>
|
||||
#include <boost/asio/handler_invoke_hook.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <boost/core/exchange.hpp>
|
||||
#include <boost/core/empty_value.hpp>
|
||||
#include <utility>
|
||||
@ -314,15 +317,54 @@ public:
|
||||
return std::move(h_);
|
||||
}
|
||||
|
||||
/** Invoke the final completion handler.
|
||||
/** Invoke the final completion handler, maybe using post.
|
||||
|
||||
This invokes the final completion handler with the specified
|
||||
arguments forwarded. It is undefined to call this member
|
||||
function more than once.
|
||||
arguments forwarded. It is undefined to call either of
|
||||
@ref invoke or @ref invoke_now more than once.
|
||||
|
||||
Any temporary objects allocated with @ref allocate_stable will
|
||||
be automatically destroyed before the final completion handler
|
||||
is invoked.
|
||||
|
||||
@param is_continuation If this value is `false`, then the
|
||||
handler will be submitted to the executor using `net::post`.
|
||||
Otherwise the handler will be invoked as if by calling
|
||||
@ref invoke_now.
|
||||
|
||||
@param args A list of optional parameters to invoke the handler
|
||||
with. The completion handler must be invocable with the parameter
|
||||
list, or else a compilation error will result.
|
||||
*/
|
||||
template<class... Args>
|
||||
void
|
||||
invoke(bool is_continuation, Args&&... args)
|
||||
{
|
||||
this->before_invoke_hook();
|
||||
wg1_.reset();
|
||||
if(! is_continuation)
|
||||
net::post(net::bind_executor(
|
||||
wg1_.get_executor(),
|
||||
beast::bind_front_handler(
|
||||
std::move(h_),
|
||||
std::forward<Args>(args)...)));
|
||||
else
|
||||
h_(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/** Invoke the final completion handler.
|
||||
|
||||
This invokes the final completion handler with the specified
|
||||
arguments forwarded. It is undefined to call either of
|
||||
@ref invoke or @ref invoke_now more than once.
|
||||
|
||||
Any temporary objects allocated with @ref allocate_stable will
|
||||
be automatically destroyed before the final completion handler
|
||||
is invoked.
|
||||
|
||||
@param args A list of optional parameters to invoke the handler
|
||||
with. The completion handler must be invocable with the parameter
|
||||
list, or else a compilation error will result.
|
||||
*/
|
||||
template<class... Args>
|
||||
void
|
||||
|
@ -110,7 +110,7 @@ public:
|
||||
|
||||
@par Example
|
||||
This function reads a line of text from a stream into a
|
||||
@ref flat_buffer, using the net function `async_read_until`. The
|
||||
@ref basic_flat_buffer, using the net function `async_read_until`.
|
||||
@code
|
||||
template <class SyncReadStream>
|
||||
std::size_t read_line (SyncReadStream& stream, flat_buffer& buffer)
|
||||
|
@ -38,10 +38,10 @@ namespace http {
|
||||
fields.
|
||||
The parser is optimized for the case where the input buffer
|
||||
sequence consists of a single contiguous buffer. The
|
||||
@ref flat_buffer class is provided, which guarantees
|
||||
@ref basic_flat_buffer class is provided, which guarantees
|
||||
that the input sequence of the stream buffer will be represented
|
||||
by exactly one contiguous buffer. To ensure the optimum performance
|
||||
of the parser, use @ref flat_buffer with HTTP algorithms
|
||||
of the parser, use @ref basic_flat_buffer with HTTP algorithms
|
||||
such as @ref read, @ref read_some, @ref async_read, and @ref async_read_some.
|
||||
Alternatively, the caller may use custom techniques to ensure that
|
||||
the structured portion of the HTTP message (header or chunk header)
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "test_handler.hpp"
|
||||
|
||||
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
||||
#include <boost/beast/_experimental/test/handler.hpp>
|
||||
#include <boost/beast/_experimental/test/stream.hpp>
|
||||
#include <boost/beast/core/error.hpp>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
@ -419,13 +420,28 @@ public:
|
||||
|
||||
// invocation
|
||||
{
|
||||
bool invoked = false;
|
||||
net::io_context ioc;
|
||||
async_op_base<
|
||||
final_handler,
|
||||
test::handler,
|
||||
net::io_context::executor_type> op(
|
||||
test::any_handler(), ioc.get_executor());
|
||||
op.invoke(true);
|
||||
}
|
||||
{
|
||||
net::io_context ioc;
|
||||
async_op_base<
|
||||
test::handler,
|
||||
net::io_context::executor_type> op(
|
||||
test::any_handler(), ioc.get_executor());
|
||||
op.invoke(false);
|
||||
ioc.run();
|
||||
}
|
||||
{
|
||||
async_op_base<
|
||||
test::handler,
|
||||
simple_executor> op(
|
||||
final_handler{invoked}, {});
|
||||
op.invoke();
|
||||
BEAST_EXPECT(invoked);
|
||||
test::any_handler(), {});
|
||||
op.invoke_now();
|
||||
}
|
||||
|
||||
// legacy hooks
|
||||
@ -478,13 +494,28 @@ public:
|
||||
|
||||
// invocation
|
||||
{
|
||||
bool invoked = false;
|
||||
net::io_context ioc;
|
||||
stable_async_op_base<
|
||||
final_handler,
|
||||
test::handler,
|
||||
net::io_context::executor_type> op(
|
||||
test::any_handler(), ioc.get_executor());
|
||||
op.invoke(true);
|
||||
}
|
||||
{
|
||||
net::io_context ioc;
|
||||
stable_async_op_base<
|
||||
test::handler,
|
||||
net::io_context::executor_type> op(
|
||||
test::any_handler(), ioc.get_executor());
|
||||
op.invoke(false);
|
||||
ioc.run();
|
||||
}
|
||||
{
|
||||
stable_async_op_base<
|
||||
test::handler,
|
||||
simple_executor> op(
|
||||
final_handler{invoked}, {});
|
||||
op.invoke();
|
||||
BEAST_EXPECT(invoked);
|
||||
test::any_handler(), {});
|
||||
op.invoke_now();
|
||||
}
|
||||
|
||||
// legacy hooks
|
||||
|
@ -7,8 +7,8 @@
|
||||
// Official repository: https://github.com/boostorg/beast
|
||||
//
|
||||
|
||||
#ifndef BOOST_BEAST_TEST_HANDLER_HPP
|
||||
#define BOOST_BEAST_TEST_HANDLER_HPP
|
||||
#ifndef BOOST_BEAST_TEST_HANDLER_XXX_HPP
|
||||
#define BOOST_BEAST_TEST_HANDLER_XXX_HPP
|
||||
|
||||
#include <boost/beast/core/detail/config.hpp>
|
||||
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
||||
|
Reference in New Issue
Block a user