Handle expired timers in basic_stream transfer_op

Previously, the code only handled expired timers when the buffer was empty.
This commit is contained in:
Mohammad Nejati
2024-05-13 07:36:11 +00:00
committed by Mohammad Nejati
parent 95f0cfb926
commit 2dcdef3890
3 changed files with 36 additions and 7 deletions

View File

@ -132,6 +132,11 @@ struct stream_base
return (time_point::max)();
}
static time_point now() noexcept
{
return clock_type::now();
}
static std::size_t constexpr no_limit =
(std::numeric_limits<std::size_t>::max)();
};

View File

@ -313,6 +313,26 @@ public:
{
BOOST_ASIO_CORO_REENTER(*this)
{
// apply the timeout manually, otherwise
// behavior varies across platforms.
if(state().timer.expiry() <= now())
{
BOOST_ASIO_CORO_YIELD
{
BOOST_ASIO_HANDLER_LOCATION((
__FILE__, __LINE__,
(isRead ? "basic_stream::async_read_some"
: "basic_stream::async_write_some")));
net::dispatch(this->get_immediate_executor(),
net::prepend(std::move(*this), ec, 0));
}
impl_->close();
BOOST_BEAST_ASSIGN_EC(ec, beast::error::timeout);
goto upcall;
}
// handle empty buffers
if(detail::buffers_empty(b_))
{
@ -326,13 +346,6 @@ public:
async_perform(0, is_read{});
}
// apply the timeout manually, otherwise
// behavior varies across platforms.
if(state().timer.expiry() <= clock_type::now())
{
impl_->close();
BOOST_BEAST_ASSIGN_EC(ec, beast::error::timeout);
}
goto upcall;
}

View File

@ -656,6 +656,17 @@ public:
ioc.restart();
}
{
// non-empty buffer, timeout
test_server srv("*", ep, log);
stream_type s(ioc);
s.socket().connect(srv.local_endpoint());
s.expires_after(std::chrono::seconds(0));
s.async_write_some(cb, handler(error::timeout, 0));
ioc.run();
ioc.restart();
}
// abandoned operation
{
stream_type s(ioc);