Add executor rebind to test::stream

closes #2139
This commit is contained in:
Richard Hodges
2020-12-16 21:11:29 +01:00
parent a87330e53f
commit 8913a3cd21
13 changed files with 619 additions and 400 deletions
+19
View File
@@ -14,7 +14,11 @@
#include <boost/beast/_experimental/test/handler.hpp>
#include <boost/asio/ssl/stream.hpp>
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
#include <boost/asio/use_awaitable.hpp>
#endif
#define DEF boost::asio::use_future_t
namespace boost {
namespace beast {
@@ -153,6 +157,18 @@ public:
test::stream>::value);
}
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
net::awaitable<void>
testRebind(net::mutable_buffer& b)
{
auto ex = co_await net::this_coro::executor;
auto s1 = test::stream(ex);
auto s2 = net::use_awaitable.as_default_on(std::move(s1));
auto bt = co_await s2.async_read_some(b);
bt = co_await s2.async_write_some(b);
}
#endif
void
run() override
{
@@ -160,6 +176,9 @@ public:
testSharedAbandon();
//testLifetimeViolation();
boost::ignore_unused(&stream_test::testAsioSSLCompat);
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
boost::ignore_unused(&stream_test::testRebind);
#endif
}
};
+10 -4
View File
@@ -34,12 +34,18 @@ namespace beast {
namespace {
#if defined(BOOST_ASIO_NO_TS_EXECUTORS)
static struct ex1_context : net::execution_context
{
} ex1ctx;
struct ex1_type
{
net::execution_context &
query(net::execution::context_t c) const noexcept
{ return *reinterpret_cast<net::execution_context *>(0); }
{ return *reinterpret_cast<net::execution_context *>(&ex1ctx); }
net::execution::blocking_t
query(net::execution::blocking_t) const noexcept
@@ -716,9 +722,9 @@ public:
net::steady_timer timer;
temporary_data(std::string message_, net::io_context& ctx)
temporary_data(std::string message_, net::any_io_executor ex)
: message(std::move(message_))
, timer(ctx)
, timer(std::move(ex))
{
}
};
@@ -733,7 +739,7 @@ public:
, repeats_(repeats)
, data_(allocate_stable<temporary_data>(*this,
std::move(message),
net::query(stream.get_executor(), net::execution::context)))
stream.get_executor()))
{
(*this)(); // start the operation
}
+9
View File
@@ -16,7 +16,9 @@
#include <boost/beast/core/bind_handler.hpp>
#include <boost/beast/test/yield_to.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/asio/execution.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/any_io_executor.hpp>
#include <boost/asio/read.hpp>
#include <boost/asio/strand.hpp>
#include <boost/optional.hpp>
@@ -41,10 +43,17 @@ public:
buffered_read_stream<test::stream, multi_buffer> srs(ioc);
buffered_read_stream<test::stream, multi_buffer> srs2(std::move(srs));
srs = std::move(srs2);
#if defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
BEAST_EXPECT(&srs.get_executor().context() == &ioc);
BEAST_EXPECT(
&srs.get_executor().context() ==
&srs2.get_executor().context());
#else
BEAST_EXPECT(&net::query(srs.get_executor(), net::execution::context) == &ioc);
BEAST_EXPECT(
&net::query(srs.get_executor(), net::execution::context) ==
&net::query(srs2.get_executor(), net::execution::context));
#endif
}
{
test::stream ts{ioc};
+31 -27
View File
@@ -55,7 +55,9 @@ public:
static
void
fail_loop(
std::function<void(stream<test::stream>&)> f,
std::function<void(
stream<test::basic_stream<net::io_context::executor_type>>&)>
f,
std::chrono::steady_clock::duration amount =
std::chrono::seconds(5))
{
@@ -68,7 +70,8 @@ public:
test::fail_count fc(n);
try
{
stream<test::stream> ws(ioc, fc);
stream<test::basic_stream<net::io_context::executor_type>>
ws(ioc, fc);
auto tr = connect(ws.next_layer());
f(ws);
break;
@@ -101,7 +104,7 @@ public:
net::io_context ioc;
// request in stream
fail_loop([&](stream<test::stream>& ws)
fail_loop([&](stream<test::basic_stream<net::io_context::executor_type>>& ws)
{
ws.next_layer().append(
"GET / HTTP/1.1\r\n"
@@ -116,7 +119,7 @@ public:
});
// request in stream, decorator
fail_loop([&](stream<test::stream>& ws)
fail_loop([&](stream<test::basic_stream<net::io_context::executor_type>>& ws)
{
ws.next_layer().append(
"GET / HTTP/1.1\r\n"
@@ -135,7 +138,7 @@ public:
});
// request in buffers
fail_loop([&](stream<test::stream>& ws)
fail_loop([&](stream<test::basic_stream<net::io_context::executor_type>>& ws)
{
api.accept(ws, sbuf(
"GET / HTTP/1.1\r\n"
@@ -149,7 +152,7 @@ public:
});
// request in buffers, decorator
fail_loop([&](stream<test::stream>& ws)
fail_loop([&](stream<test::basic_stream<net::io_context::executor_type>>& ws)
{
bool called = false;
ws.set_option(stream_base::decorator(
@@ -166,7 +169,7 @@ public:
});
// request in buffers and stream
fail_loop([&](stream<test::stream>& ws)
fail_loop([&](stream<test::basic_stream<net::io_context::executor_type>>& ws)
{
ws.next_layer().append(
"Connection: upgrade\r\n"
@@ -183,7 +186,7 @@ public:
});
// request in buffers and stream, decorator
fail_loop([&](stream<test::stream>& ws)
fail_loop([&](stream<test::basic_stream<net::io_context::executor_type>>& ws)
{
ws.next_layer().append(
"Connection: upgrade\r\n"
@@ -213,7 +216,7 @@ public:
req.insert(http::field::sec_websocket_key, "dGhlIHNhbXBsZSBub25jZQ==");
req.insert(http::field::sec_websocket_version, "13");
fail_loop([&](stream<test::stream>& ws)
fail_loop([&](stream<test::basic_stream<net::io_context::executor_type>>& ws)
{
api.accept(ws, req);
});
@@ -231,7 +234,7 @@ public:
req.insert(http::field::sec_websocket_key, "dGhlIHNhbXBsZSBub25jZQ==");
req.insert(http::field::sec_websocket_version, "13");
fail_loop([&](stream<test::stream>& ws)
fail_loop([&](stream<test::basic_stream<net::io_context::executor_type>>& ws)
{
bool called = false;
ws.set_option(stream_base::decorator(
@@ -253,7 +256,7 @@ public:
req.insert(http::field::sec_websocket_key, "dGhlIHNhbXBsZSBub25jZQ==");
req.insert(http::field::sec_websocket_version, "13");
fail_loop([&](stream<test::stream>& ws)
fail_loop([&](stream<test::basic_stream<net::io_context::executor_type>>& ws)
{
ws.next_layer().append("\x88\x82\xff\xff\xff\xff\xfc\x17");
api.accept(ws, req);
@@ -272,7 +275,7 @@ public:
}
// failed handshake (missing Sec-WebSocket-Key)
fail_loop([&](stream<test::stream>& ws)
fail_loop([&](stream<test::basic_stream<net::io_context::executor_type>>& ws)
{
ws.next_layer().append(
"GET / HTTP/1.1\r\n"
@@ -311,7 +314,7 @@ public:
// request in stream
{
stream<test::stream> ws{ioc,
stream<test::basic_stream<net::io_context::executor_type>> ws{ioc,
"GET / HTTP/1.1\r\n"
"Host: localhost\r\n"
"Upgrade: websocket\r\n"
@@ -337,7 +340,7 @@ public:
// request in stream, decorator
{
stream<test::stream> ws{ioc,
stream<test::basic_stream<net::io_context::executor_type>> ws{ioc,
"GET / HTTP/1.1\r\n"
"Host: localhost\r\n"
"Upgrade: websocket\r\n"
@@ -366,7 +369,7 @@ public:
// request in buffers
{
stream<test::stream> ws{ioc};
stream<test::basic_stream<net::io_context::executor_type>> ws{ioc};
auto tr = connect(ws.next_layer());
try
{
@@ -392,7 +395,7 @@ public:
// request in buffers, decorator
{
stream<test::stream> ws{ioc};
stream<test::basic_stream<net::io_context::executor_type>> ws{ioc};
auto tr = connect(ws.next_layer());
try
{
@@ -420,7 +423,7 @@ public:
// request in buffers and stream
{
stream<test::stream> ws{ioc,
stream<test::basic_stream<net::io_context::executor_type>> ws{ioc,
"Connection: upgrade\r\n"
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
"Sec-WebSocket-Version: 13\r\n"
@@ -446,7 +449,7 @@ public:
// request in buffers and stream, decorator
{
stream<test::stream> ws{ioc,
stream<test::basic_stream<net::io_context::executor_type>> ws{ioc,
"Connection: upgrade\r\n"
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
"Sec-WebSocket-Version: 13\r\n"
@@ -497,7 +500,7 @@ public:
n = s.size() - 1;
break;
}
stream<test::stream> ws(ioc);
stream<test::basic_stream<net::io_context::executor_type>> ws(ioc);
auto tr = connect(ws.next_layer());
ws.next_layer().append(
s.substr(n, s.size() - n));
@@ -658,7 +661,7 @@ public:
{
net::io_context ioc;
{
stream<test::stream> ws(ioc);
stream<test::basic_stream<net::io_context::executor_type>> ws(ioc);
auto tr = connect(ws.next_layer());
tr.close();
try
@@ -675,7 +678,8 @@ public:
}
}
{
stream<test::stream> ws(ioc);
stream<test::basic_stream<net::io_context::executor_type>>
ws(ioc.get_executor());
auto tr = connect(ws.next_layer());
tr.close();
try
@@ -713,8 +717,8 @@ public:
}
{
stream<test::stream> ws1(ioc);
stream<test::stream> ws2(ioc);
stream<test::basic_stream<net::io_context::executor_type>> ws1(ioc);
stream<test::basic_stream<net::io_context::executor_type>> ws2(ioc);
test::connect(ws1.next_layer(), ws2.next_layer());
ws1.async_handshake("test", "/", test::success_handler());
@@ -739,8 +743,8 @@ public:
}
{
stream<test::stream> ws1(ioc);
stream<test::stream> ws2(ioc);
stream<test::basic_stream<net::io_context::executor_type>> ws1(ioc);
stream<test::basic_stream<net::io_context::executor_type>> ws2(ioc);
test::connect(ws1.next_layer(), ws2.next_layer());
ws1.set_option(stream_base::timeout{
@@ -768,8 +772,8 @@ public:
}
{
stream<test::stream> ws1(ioc);
stream<test::stream> ws2(ioc);
stream<test::basic_stream<net::io_context::executor_type>> ws1(ioc);
stream<test::basic_stream<net::io_context::executor_type>> ws2(ioc);
test::connect(ws1.next_layer(), ws2.next_layer());
ws1.set_option(stream_base::timeout{
@@ -35,8 +35,9 @@ protected:
net::io_context ioc_;
private:
detail::select_work_guard_t<net::io_context::executor_type>
work_;
beast::detail::select_work_guard_t<
net::io_context::executor_type>
work_;
std::vector<std::thread> threads_;
std::mutex m_;
std::condition_variable cv_;
@@ -49,7 +50,8 @@ public:
explicit
enable_yield_to(std::size_t concurrency = 1)
: work_(detail::make_work_guard(ioc_.get_executor()))
: work_(beast::detail::make_work_guard(
ioc_.get_executor()))
{
threads_.reserve(concurrency);
while(concurrency--)