mirror of
https://github.com/boostorg/beast.git
synced 2025-07-31 13:27:33 +02:00
Add async_op_base::invoke
This commit is contained in:
@ -6,6 +6,7 @@ Version 215:
|
|||||||
* Examples use bind_front_handler
|
* Examples use bind_front_handler
|
||||||
* Add experimental test/handler.hpp
|
* Add experimental test/handler.hpp
|
||||||
* Rename to async_op_base::invoke_now
|
* 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__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__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__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>
|
<member><link linkend="beast.ref.boost__beast__test__stream">test::stream</link></member>
|
||||||
</simplelist>
|
</simplelist>
|
||||||
</entry>
|
</entry>
|
||||||
@ -364,6 +365,9 @@
|
|||||||
<bridgehead renderas="sect3">Functions</bridgehead>
|
<bridgehead renderas="sect3">Functions</bridgehead>
|
||||||
<simplelist type="vert" columns="1">
|
<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__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>
|
</simplelist>
|
||||||
</entry>
|
</entry>
|
||||||
<entry valign="top">
|
<entry valign="top">
|
||||||
|
@ -19,8 +19,17 @@ namespace boost {
|
|||||||
namespace beast {
|
namespace beast {
|
||||||
namespace test {
|
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
|
class handler
|
||||||
{
|
{
|
||||||
boost::optional<error_code> ec_;
|
boost::optional<error_code> ec_;
|
||||||
@ -61,6 +70,14 @@ public:
|
|||||||
pass_ = true;
|
pass_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
operator()()
|
||||||
|
{
|
||||||
|
BEAST_EXPECT(! pass_); // can't call twice
|
||||||
|
BEAST_EXPECT(! ec_);
|
||||||
|
pass_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
template<class Arg0, class... Args,
|
template<class Arg0, class... Args,
|
||||||
class = typename std::enable_if<
|
class = typename std::enable_if<
|
||||||
! std::is_convertible<Arg0, error_code>::value>::type>
|
! std::is_convertible<Arg0, error_code>::value>::type>
|
||||||
@ -73,8 +90,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // detail
|
|
||||||
|
|
||||||
/** Return a test CompletionHandler which requires success.
|
/** Return a test CompletionHandler which requires success.
|
||||||
|
|
||||||
The returned handler can be invoked with any signature whose
|
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.
|
@li The handler is invoked with a non-successful error code.
|
||||||
*/
|
*/
|
||||||
inline
|
inline
|
||||||
#if BOOST_BEAST_DOXYGEN
|
handler
|
||||||
__implementation_defined__
|
|
||||||
#else
|
|
||||||
detail::handler
|
|
||||||
#endif
|
|
||||||
success_handler() noexcept
|
success_handler() noexcept
|
||||||
{
|
{
|
||||||
return detail::handler(error_code{});
|
return handler(error_code{});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return a test CompletionHandler which requires invocation.
|
/** Return a test CompletionHandler which requires invocation.
|
||||||
@ -104,14 +115,10 @@ success_handler() noexcept
|
|||||||
@li The handler is destroyed without being invoked.
|
@li The handler is destroyed without being invoked.
|
||||||
*/
|
*/
|
||||||
inline
|
inline
|
||||||
#if BOOST_BEAST_DOXYGEN
|
handler
|
||||||
__implementation_defined__
|
|
||||||
#else
|
|
||||||
detail::handler
|
|
||||||
#endif
|
|
||||||
any_handler() noexcept
|
any_handler() noexcept
|
||||||
{
|
{
|
||||||
return detail::handler(boost::none);
|
return handler(boost::none);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return a test CompletionHandler which requires a specific error code.
|
/** Return a test CompletionHandler which requires a specific error code.
|
||||||
@ -127,14 +134,10 @@ any_handler() noexcept
|
|||||||
@param ec The error code to specify.
|
@param ec The error code to specify.
|
||||||
*/
|
*/
|
||||||
inline
|
inline
|
||||||
#if BOOST_BEAST_DOXYGEN
|
handler
|
||||||
__implementation_defined__
|
|
||||||
#else
|
|
||||||
detail::handler
|
|
||||||
#endif
|
|
||||||
fail_handler(error_code ec) noexcept
|
fail_handler(error_code ec) noexcept
|
||||||
{
|
{
|
||||||
return detail::handler(ec);
|
return handler(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // test
|
} // test
|
||||||
|
@ -61,8 +61,8 @@ namespace test {
|
|||||||
To facilitate testing, these streams support some additional
|
To facilitate testing, these streams support some additional
|
||||||
features:
|
features:
|
||||||
|
|
||||||
@li The input area, represented by a @ref flat_buffer, may
|
@li The input area, represented by a @ref basic_flat_buffer,
|
||||||
be directly accessed by the caller to inspect the contents
|
may be directly accessed by the caller to inspect the contents
|
||||||
before or after the remote endpoint writes data. This allows
|
before or after the remote endpoint writes data. This allows
|
||||||
a unit test to verify that the received data matches.
|
a unit test to verify that the received data matches.
|
||||||
|
|
||||||
|
@ -11,14 +11,17 @@
|
|||||||
#define BOOST_BEAST_CORE_ASYNC_OP_BASE_HPP
|
#define BOOST_BEAST_CORE_ASYNC_OP_BASE_HPP
|
||||||
|
|
||||||
#include <boost/beast/core/detail/config.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/allocator.hpp>
|
||||||
#include <boost/beast/core/detail/async_op_base.hpp>
|
#include <boost/beast/core/detail/async_op_base.hpp>
|
||||||
#include <boost/asio/associated_allocator.hpp>
|
#include <boost/asio/associated_allocator.hpp>
|
||||||
#include <boost/asio/associated_executor.hpp>
|
#include <boost/asio/associated_executor.hpp>
|
||||||
|
#include <boost/asio/bind_executor.hpp>
|
||||||
#include <boost/asio/executor_work_guard.hpp>
|
#include <boost/asio/executor_work_guard.hpp>
|
||||||
#include <boost/asio/handler_alloc_hook.hpp>
|
#include <boost/asio/handler_alloc_hook.hpp>
|
||||||
#include <boost/asio/handler_continuation_hook.hpp>
|
#include <boost/asio/handler_continuation_hook.hpp>
|
||||||
#include <boost/asio/handler_invoke_hook.hpp>
|
#include <boost/asio/handler_invoke_hook.hpp>
|
||||||
|
#include <boost/asio/post.hpp>
|
||||||
#include <boost/core/exchange.hpp>
|
#include <boost/core/exchange.hpp>
|
||||||
#include <boost/core/empty_value.hpp>
|
#include <boost/core/empty_value.hpp>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -314,15 +317,54 @@ public:
|
|||||||
return std::move(h_);
|
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
|
This invokes the final completion handler with the specified
|
||||||
arguments forwarded. It is undefined to call this member
|
arguments forwarded. It is undefined to call either of
|
||||||
function more than once.
|
@ref invoke or @ref invoke_now more than once.
|
||||||
|
|
||||||
Any temporary objects allocated with @ref allocate_stable will
|
Any temporary objects allocated with @ref allocate_stable will
|
||||||
be automatically destroyed before the final completion handler
|
be automatically destroyed before the final completion handler
|
||||||
is invoked.
|
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>
|
template<class... Args>
|
||||||
void
|
void
|
||||||
|
@ -110,7 +110,7 @@ public:
|
|||||||
|
|
||||||
@par Example
|
@par Example
|
||||||
This function reads a line of text from a stream into a
|
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
|
@code
|
||||||
template <class SyncReadStream>
|
template <class SyncReadStream>
|
||||||
std::size_t read_line (SyncReadStream& stream, flat_buffer& buffer)
|
std::size_t read_line (SyncReadStream& stream, flat_buffer& buffer)
|
||||||
|
@ -38,10 +38,10 @@ namespace http {
|
|||||||
fields.
|
fields.
|
||||||
The parser is optimized for the case where the input buffer
|
The parser is optimized for the case where the input buffer
|
||||||
sequence consists of a single contiguous buffer. The
|
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
|
that the input sequence of the stream buffer will be represented
|
||||||
by exactly one contiguous buffer. To ensure the optimum performance
|
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.
|
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
|
Alternatively, the caller may use custom techniques to ensure that
|
||||||
the structured portion of the HTTP message (header or chunk header)
|
the structured portion of the HTTP message (header or chunk header)
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "test_handler.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/handler.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>
|
||||||
#include <boost/asio/async_result.hpp>
|
#include <boost/asio/async_result.hpp>
|
||||||
@ -419,13 +420,28 @@ public:
|
|||||||
|
|
||||||
// invocation
|
// invocation
|
||||||
{
|
{
|
||||||
bool invoked = false;
|
net::io_context ioc;
|
||||||
async_op_base<
|
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(
|
simple_executor> op(
|
||||||
final_handler{invoked}, {});
|
test::any_handler(), {});
|
||||||
op.invoke();
|
op.invoke_now();
|
||||||
BEAST_EXPECT(invoked);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// legacy hooks
|
// legacy hooks
|
||||||
@ -478,13 +494,28 @@ public:
|
|||||||
|
|
||||||
// invocation
|
// invocation
|
||||||
{
|
{
|
||||||
bool invoked = false;
|
net::io_context ioc;
|
||||||
stable_async_op_base<
|
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(
|
simple_executor> op(
|
||||||
final_handler{invoked}, {});
|
test::any_handler(), {});
|
||||||
op.invoke();
|
op.invoke_now();
|
||||||
BEAST_EXPECT(invoked);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// legacy hooks
|
// legacy hooks
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
// Official repository: https://github.com/boostorg/beast
|
// Official repository: https://github.com/boostorg/beast
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef BOOST_BEAST_TEST_HANDLER_HPP
|
#ifndef BOOST_BEAST_TEST_HANDLER_XXX_HPP
|
||||||
#define BOOST_BEAST_TEST_HANDLER_HPP
|
#define BOOST_BEAST_TEST_HANDLER_XXX_HPP
|
||||||
|
|
||||||
#include <boost/beast/core/detail/config.hpp>
|
#include <boost/beast/core/detail/config.hpp>
|
||||||
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
||||||
|
Reference in New Issue
Block a user