diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a6633d8..cd8ce77b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Version 210: * Add executor_type trait * Fix hexadecimal string conversion table * is_completion_handler, type_traits.hpp are deprecated +* Fixes to test::stream::async_read API Changes: diff --git a/doc/qbk/release_notes.qbk b/doc/qbk/release_notes.qbk index 9682b6e8..4bdcbbad 100644 --- a/doc/qbk/release_notes.qbk +++ b/doc/qbk/release_notes.qbk @@ -210,13 +210,16 @@ New websocket-chat-multi example * `ostream` does not overflow or exceed the dynamic buffer's maximum size -* A handler work guard is maintained on paused websocket operations - -* All behavior of default-constructed iterators is conforming +* Fixes to + `test::stream::async_read` * `file_mode::append_existing` works correctly +* A handler work guard is maintained on paused websocket operations + +* All behavior of default-constructed iterators is conforming + [/-----------------------------------------------------------------------------] [heading Boost 1.69] diff --git a/include/boost/beast/_experimental/test/impl/stream.hpp b/include/boost/beast/_experimental/test/impl/stream.hpp index b31aecad..0b6bf0ec 100644 --- a/include/boost/beast/_experimental/test/impl/stream.hpp +++ b/include/boost/beast/_experimental/test/impl/stream.hpp @@ -427,7 +427,8 @@ TeardownHandler&& handler) s.in_->fc->fail(ec)) return net::post( s.get_executor(), - beast::bind_front_handler(std::move(handler), ec)); + beast::bind_front_handler( + std::move(handler), ec)); s.close(); if( s.in_->fc && s.in_->fc->fail(ec)) @@ -437,7 +438,8 @@ TeardownHandler&& handler) net::post( s.get_executor(), - beast::bind_front_handler(std::move(handler), ec)); + beast::bind_front_handler( + std::move(handler), ec)); } //------------------------------------------------------------------------------ @@ -445,15 +447,16 @@ TeardownHandler&& handler) template class stream::read_op : public stream::read_op_base { - using ex1_type = net::io_context::executor_type; - using ex2_type = net::associated_executor_t; + using ex1_type = + net::io_context::executor_type; + using ex2_type + = net::associated_executor_t; class lambda { state& s_; Buffers b_; Handler h_; - net::executor_work_guard wg1_; net::executor_work_guard wg2_; public: @@ -465,76 +468,66 @@ class stream::read_op : public stream::read_op_base : s_(s) , b_(b) , h_(std::forward(h)) - , wg1_(s_.ioc.get_executor()) , wg2_(net::get_associated_executor( h_, s_.ioc.get_executor())) { } - void - post() - { - net::post( - s_.ioc.get_executor(), - std::move(*this)); - wg1_.reset(); - wg2_.reset(); - } - void operator()() { std::unique_lock lock{s_.m}; + error_code ec; + std::size_t bytes_transferred = 0; BOOST_ASSERT(! s_.op); if(s_.b.size() > 0) { - auto const bytes_transferred = + bytes_transferred = net::buffer_copy( b_, s_.b.data(), s_.read_max); s_.b.consume(bytes_transferred); - auto& s = s_; - Handler h{std::move(h_)}; - lock.unlock(); - ++s.nread; - net::post( - s.ioc.get_executor(), - beast::bind_front_handler( - std::move(h), - error_code{}, - bytes_transferred)); + ++s_.nread; } else { BOOST_ASSERT(s_.code != status::ok); auto& s = s_; - Handler h{std::move(h_)}; - lock.unlock(); ++s.nread; - error_code ec; if(s.code == status::eof) ec = net::error::eof; else if(s.code == status::reset) ec = net::error::connection_reset; - net::post( - s.ioc.get_executor(), - beast::bind_front_handler(std::move(h), ec, 0)); + } + lock.unlock(); + auto alloc = net::get_associated_allocator(h_); + wg2_.get_executor().dispatch( + beast::bind_front_handler( + std::move(h_), + ec, + bytes_transferred), alloc); + wg2_.reset(); } }; lambda fn_; + net::executor_work_guard wg1_; public: template read_op(state& s, Buffers const& b, DeducedHandler&& h) : fn_(s, b, std::forward(h)) + , wg1_(s.ioc.get_executor()) { } void operator()() override { - fn_.post(); + net::post( + wg1_.get_executor(), + std::move(fn_)); + wg1_.reset(); } };