diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8ece7708..f62d9eea 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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
--------------------------------------------------------------------------------
diff --git a/doc/qbk/quickref.xml b/doc/qbk/quickref.xml
index efcca5f3..941c7255 100644
--- a/doc/qbk/quickref.xml
+++ b/doc/qbk/quickref.xml
@@ -357,6 +357,7 @@
ssl_streamhttp::icy_streamtest::fail_count
+ test::handler 🞲test::stream
@@ -364,6 +365,9 @@
Functionstest::connect
+ test::any_handler 🞲
+ test::fail_handler 🞲
+ test::success_handler 🞲
diff --git a/include/boost/beast/_experimental/test/handler.hpp b/include/boost/beast/_experimental/test/handler.hpp
index a2cb7e79..de889f95 100644
--- a/include/boost/beast/_experimental/test/handler.hpp
+++ b/include/boost/beast/_experimental/test/handler.hpp
@@ -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 ec_;
@@ -61,6 +70,14 @@ public:
pass_ = true;
}
+ void
+ operator()()
+ {
+ BEAST_EXPECT(! pass_); // can't call twice
+ BEAST_EXPECT(! ec_);
+ pass_ = true;
+ }
+
template::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
diff --git a/include/boost/beast/_experimental/test/stream.hpp b/include/boost/beast/_experimental/test/stream.hpp
index d8095f66..4869c0e1 100644
--- a/include/boost/beast/_experimental/test/stream.hpp
+++ b/include/boost/beast/_experimental/test/stream.hpp
@@ -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.
diff --git a/include/boost/beast/core/async_op_base.hpp b/include/boost/beast/core/async_op_base.hpp
index 201445cc..f33fb350 100644
--- a/include/boost/beast/core/async_op_base.hpp
+++ b/include/boost/beast/core/async_op_base.hpp
@@ -11,14 +11,17 @@
#define BOOST_BEAST_CORE_ASYNC_OP_BASE_HPP
#include
+#include
#include
#include
#include
#include
+#include
#include
#include
#include
#include
+#include
#include
#include
#include
@@ -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
+ 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)...)));
+ else
+ h_(std::forward(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
void
diff --git a/include/boost/beast/core/dynamic_buffer_ref.hpp b/include/boost/beast/core/dynamic_buffer_ref.hpp
index 523b1329..7763e3c0 100644
--- a/include/boost/beast/core/dynamic_buffer_ref.hpp
+++ b/include/boost/beast/core/dynamic_buffer_ref.hpp
@@ -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
std::size_t read_line (SyncReadStream& stream, flat_buffer& buffer)
diff --git a/include/boost/beast/http/basic_parser.hpp b/include/boost/beast/http/basic_parser.hpp
index cf17a90f..0f687ff5 100644
--- a/include/boost/beast/http/basic_parser.hpp
+++ b/include/boost/beast/http/basic_parser.hpp
@@ -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)
diff --git a/test/beast/core/async_op_base.cpp b/test/beast/core/async_op_base.cpp
index 9993dbb8..c5abdcd7 100644
--- a/test/beast/core/async_op_base.cpp
+++ b/test/beast/core/async_op_base.cpp
@@ -13,6 +13,7 @@
#include "test_handler.hpp"
#include
+#include
#include
#include
#include
@@ -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
diff --git a/test/beast/core/test_handler.hpp b/test/beast/core/test_handler.hpp
index 19faa735..40d98346 100644
--- a/test/beast/core/test_handler.hpp
+++ b/test/beast/core/test_handler.hpp
@@ -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
#include