Initiating functions no longer perform mutating operations

Using `asio::deferred` as a completion token defers the initiation of
operations and creates a lazy operation which might even be discarded.
We need to move mutating operations to the initiator function objects or
the constructor of operation objects, which are guaranteed to run when
the deferred operation is launched.
This commit is contained in:
Mohammad Nejati
2024-08-05 15:41:57 +00:00
committed by Mohammad Nejati
parent fee9be0be1
commit 5f5507f647
3 changed files with 13 additions and 11 deletions

View File

@@ -190,13 +190,15 @@ public:
write_op( write_op(
Handler_&& h, Handler_&& h,
Stream& s, Stream& s,
serializer<isRequest, Body, Fields>& sr) serializer<isRequest, Body, Fields>& sr,
bool split)
: async_base< : async_base<
Handler, beast::executor_type<Stream>>( Handler, beast::executor_type<Stream>>(
std::forward<Handler_>(h), s.get_executor()) std::forward<Handler_>(h), s.get_executor())
, s_(s) , s_(s)
, sr_(sr) , sr_(sr)
{ {
sr.split(split);
(*this)(); (*this)();
} }
@@ -358,7 +360,8 @@ struct run_write_op
operator()( operator()(
WriteHandler&& h, WriteHandler&& h,
Predicate const&, Predicate const&,
serializer<isRequest, Body, Fields>* sr) serializer<isRequest, Body, Fields>* sr,
bool split)
{ {
// If you get an error on the following line it means // If you get an error on the following line it means
// that your handler does not meet the documented type // that your handler does not meet the documented type
@@ -374,7 +377,7 @@ struct run_write_op
AsyncWriteStream, AsyncWriteStream,
Predicate, Predicate,
isRequest, Body, Fields>( isRequest, Body, Fields>(
std::forward<WriteHandler>(h), *stream, *sr); std::forward<WriteHandler>(h), *stream, *sr, split);
} }
}; };
@@ -686,14 +689,14 @@ async_write_header(
"Body type requirements not met"); "Body type requirements not met");
static_assert(is_body_writer<Body>::value, static_assert(is_body_writer<Body>::value,
"BodyWriter type requirements not met"); "BodyWriter type requirements not met");
sr.split(true);
return net::async_initiate< return net::async_initiate<
WriteHandler, WriteHandler,
void(error_code, std::size_t)>( void(error_code, std::size_t)>(
detail::run_write_op<AsyncWriteStream>{&stream}, detail::run_write_op<AsyncWriteStream>{&stream},
handler, handler,
detail::serializer_is_header_done{}, detail::serializer_is_header_done{},
&sr); &sr,
true);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -758,14 +761,14 @@ async_write(
"Body type requirements not met"); "Body type requirements not met");
static_assert(is_body_writer<Body>::value, static_assert(is_body_writer<Body>::value,
"BodyWriter type requirements not met"); "BodyWriter type requirements not met");
sr.split(false);
return net::async_initiate< return net::async_initiate<
WriteHandler, WriteHandler,
void(error_code, std::size_t)>( void(error_code, std::size_t)>(
detail::run_write_op<AsyncWriteStream>{&stream}, detail::run_write_op<AsyncWriteStream>{&stream},
handler, handler,
detail::serializer_is_done{}, detail::serializer_is_done{},
&sr); &sr,
false);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@@ -296,6 +296,7 @@ public:
, d_(decorator) , d_(decorator)
{ {
auto& impl = *sp; auto& impl = *sp;
impl.reset();
error_code ec; error_code ec;
auto const mb = auto const mb =
beast::detail::dynamic_buffer_prepare( beast::detail::dynamic_buffer_prepare(
@@ -629,7 +630,6 @@ async_accept(
{ {
static_assert(is_async_stream<next_layer_type>::value, static_assert(is_async_stream<next_layer_type>::value,
"AsyncStream type requirements not met"); "AsyncStream type requirements not met");
impl_->reset();
return net::async_initiate< return net::async_initiate<
AcceptHandler, AcceptHandler,
void(error_code)>( void(error_code)>(
@@ -661,7 +661,6 @@ async_accept(
static_assert(net::is_const_buffer_sequence< static_assert(net::is_const_buffer_sequence<
ConstBufferSequence>::value, ConstBufferSequence>::value,
"ConstBufferSequence type requirements not met"); "ConstBufferSequence type requirements not met");
impl_->reset();
return net::async_initiate< return net::async_initiate<
AcceptHandler, AcceptHandler,
void(error_code)>( void(error_code)>(
@@ -683,7 +682,6 @@ async_accept(
{ {
static_assert(is_async_stream<next_layer_type>::value, static_assert(is_async_stream<next_layer_type>::value,
"AsyncStream type requirements not met"); "AsyncStream type requirements not met");
impl_->reset();
return net::async_initiate< return net::async_initiate<
AcceptHandler, AcceptHandler,
void(error_code)>( void(error_code)>(

View File

@@ -80,6 +80,8 @@ public:
*this, std::move(req))) *this, std::move(req)))
{ {
sp->reset(); // VFALCO I don't like this sp->reset(); // VFALCO I don't like this
if(res_p)
res_p->result(http::status::internal_server_error);
(*this)({}, 0, false); (*this)({}, 0, false);
} }
@@ -342,7 +344,6 @@ async_handshake(
detail::sec_ws_key_type key; detail::sec_ws_key_type key;
auto req = impl_->build_request( auto req = impl_->build_request(
key, host, target, &default_decorate_req); key, host, target, &default_decorate_req);
res.result(http::status::internal_server_error);
return net::async_initiate< return net::async_initiate<
HandshakeHandler, HandshakeHandler,
void(error_code)>( void(error_code)>(