beast support per-op cancellation

- websocket supports cancellation.
 - Iterating test for ws cancellation.
 - Only terminal cancellation is forwarded by default.
 - basic_stream supports cancellation.
 - supported cancellation is documented.
 - http cancellation additions.
 - Added cancellation_slot tests to http, utils and saved_handler.
 - Added post to write.cpp, to avoid SIGSEV in test.
 - Refresher describes cancellation in more detail.
This commit is contained in:
Klemens authored and Klemens Morgenstern committed 2022-10-27 22:56:19 +08:00
1 parent 0bf3d971a0
commit 3ebff60b1a
35 files changed
+1216 -29

No files matched your search

+1
View File
@@ -48,6 +48,7 @@ add_executable (tests-beast-core
file_posix.cpp
file_stdio.cpp
file_win32.cpp
filtering_cancellation_slot.cpp
flat_buffer.cpp
flat_static_buffer.cpp
flat_stream.cpp
+1
View File
@@ -39,6 +39,7 @@ local SOURCES =
file_posix.cpp
file_stdio.cpp
file_win32.cpp
filtering_cancellation_slot.cpp
flat_buffer.cpp
flat_static_buffer.cpp
flat_stream.cpp
@@ -0,0 +1,48 @@
//
// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Test that header file is self-contained.
#include <boost/beast/core/detail/filtering_cancellation_slot.hpp>
#include <boost/beast/_experimental/unit_test/suite.hpp>
namespace boost {
namespace beast {
struct filtering_cancellation_slot_test : beast::unit_test::suite
{
void
run()
{
using ct = net::cancellation_type;
ct fired = ct::none;
auto l = [&fired](ct tp){fired = tp;};
net::cancellation_signal sl;
detail::filtering_cancellation_slot<> slot{ct::terminal, sl.slot()};
slot.type |= ct::total;
slot = sl.slot();
slot.assign(l);
BEAST_EXPECT(fired == ct::none);
sl.emit(ct::total);
BEAST_EXPECT(fired == ct::total);
sl.emit(ct::partial);
BEAST_EXPECT(fired == ct::total);
sl.emit(ct::terminal);
BEAST_EXPECT(fired == ct::terminal);
}
};
BEAST_DEFINE_TESTSUITE(beast,core,filtering_cancellation_slot);
} // beast
} // boost
+83 -5
View File
@@ -9,7 +9,7 @@
// Test that header file is self-contained.
#include <boost/beast/core/saved_handler.hpp>
#include <boost/asio/bind_cancellation_slot.hpp>
#include <boost/beast/_experimental/unit_test/suite.hpp>
#include <stdexcept>
@@ -46,7 +46,7 @@ public:
}
void
operator()()
operator()(system::error_code ec_ = {})
{
failed_ = false;
}
@@ -74,7 +74,7 @@ public:
}
void
operator()()
operator()(system::error_code = {})
{
invoked_ = true;
}
@@ -90,7 +90,7 @@ public:
}
void
operator()()
operator()(system::error_code = {})
{
}
};
@@ -119,7 +119,7 @@ public:
{
saved_handler sh;
try
{
{
sh.emplace(throwing_handler{});
fail();
}
@@ -131,10 +131,88 @@ public:
}
}
void
testSavedHandlerCancellation()
{
{
net::cancellation_signal sig;
saved_handler sh;
BEAST_EXPECT(! sh.has_value());
sh.emplace(
net::bind_cancellation_slot(
sig.slot(), handler{}));
BEAST_EXPECT(sh.has_value());
BEAST_EXPECT(sig.slot().has_handler());
sig.emit(net::cancellation_type::all);
BEAST_EXPECT(! sh.has_value());
BEAST_EXPECT(!sig.slot().has_handler());
sh.emplace(
net::bind_cancellation_slot(
sig.slot(), handler{}));
BEAST_EXPECT(sh.has_value());
BEAST_EXPECT(sig.slot().has_handler());
sig.emit(net::cancellation_type::total);
BEAST_EXPECT(sh.has_value());
BEAST_EXPECT(sig.slot().has_handler());
sig.emit(net::cancellation_type::terminal);
BEAST_EXPECT(! sh.has_value());
BEAST_EXPECT(!sig.slot().has_handler());
sh.emplace(
net::bind_cancellation_slot(
sig.slot(), handler{}),
net::cancellation_type::total);
BEAST_EXPECT(sh.has_value());
BEAST_EXPECT(sig.slot().has_handler());
sig.emit(net::cancellation_type::total);
BEAST_EXPECT(! sh.has_value());
BEAST_EXPECT(!sig.slot().has_handler());
{
saved_handler sh_inner;
sh_inner.emplace(
net::bind_cancellation_slot(
sig.slot(), handler{}));
sh = std::move(sh_inner);
}
BEAST_EXPECT(sh.has_value());
BEAST_EXPECT(sig.slot().has_handler());
sig.emit(net::cancellation_type::all);
BEAST_EXPECT(! sh.has_value());
BEAST_EXPECT(!sig.slot().has_handler());
}
{
saved_handler sh;
net::cancellation_signal sig;
try
{
sh.emplace(
net::bind_cancellation_slot(
sig.slot(),
throwing_handler{}));
fail();
}
catch(std::exception const&)
{
pass();
}
BEAST_EXPECT(!sig.slot().has_handler());
BEAST_EXPECT(! sh.has_value());
}
}
void
run() override
{
testSavedHandler();
testSavedHandlerCancellation();
}
};