mirror of
https://github.com/boostorg/beast.git
synced 2026-05-06 08:26:19 +02:00
Use executor_work_guard in composed operations:
fix #1076 As per Asio and Networking TS requirements, composed operations must maintain an object of type executor_work_guard for the executor associated with the I/O object, for the lifetime of the asynchronous operation. This is in addition to the requirement for maintaining an object of type executor_work_guard for the executor associated with the handler.
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
#include <boost/beast/core/detail/config.hpp>
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/executor_work_guard.hpp>
|
||||
#include <boost/asio/handler_continuation_hook.hpp>
|
||||
#include <boost/asio/handler_invoke_hook.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
@@ -31,10 +32,12 @@ template<class MutableBufferSequence, class Handler>
|
||||
class buffered_read_stream<
|
||||
Stream, DynamicBuffer>::read_some_op
|
||||
{
|
||||
int step_ = 0;
|
||||
buffered_read_stream& s_;
|
||||
boost::asio::executor_work_guard<decltype(
|
||||
std::declval<Stream&>().get_executor())> wg_;
|
||||
MutableBufferSequence b_;
|
||||
Handler h_;
|
||||
int step_ = 0;
|
||||
|
||||
public:
|
||||
read_some_op(read_some_op&&) = default;
|
||||
@@ -45,6 +48,7 @@ public:
|
||||
buffered_read_stream& s,
|
||||
MutableBufferSequence const& b)
|
||||
: s_(s)
|
||||
, wg_(s_.get_executor())
|
||||
, b_(b)
|
||||
, h_(std::forward<DeducedHandler>(h))
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/basic_stream_socket.hpp>
|
||||
#include <boost/asio/executor_work_guard.hpp>
|
||||
#include <boost/asio/handler_continuation_hook.hpp>
|
||||
#include <boost/asio/handler_invoke_hook.hpp>
|
||||
#include <boost/asio/windows/overlapped_ptr.hpp>
|
||||
@@ -337,6 +338,8 @@ template<
|
||||
class write_some_win32_op
|
||||
{
|
||||
boost::asio::basic_stream_socket<Protocol>& sock_;
|
||||
boost::asio::executor_work_guard<decltype(std::declval<
|
||||
boost::asio::basic_stream_socket<Protocol>&>().get_executor())> wg_;
|
||||
serializer<isRequest,
|
||||
basic_file_body<file_win32>, Fields>& sr_;
|
||||
std::size_t bytes_transferred_ = 0;
|
||||
@@ -354,6 +357,7 @@ public:
|
||||
serializer<isRequest,
|
||||
basic_file_body<file_win32>,Fields>& sr)
|
||||
: sock_(s)
|
||||
, wg_(sock_.get_executor())
|
||||
, sr_(sr)
|
||||
, h_(std::forward<DeducedHandler>(h))
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/coroutine.hpp>
|
||||
#include <boost/asio/executor_work_guard.hpp>
|
||||
#include <boost/asio/handler_continuation_hook.hpp>
|
||||
#include <boost/asio/handler_invoke_hook.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
@@ -43,6 +44,8 @@ class read_some_op
|
||||
: public boost::asio::coroutine
|
||||
{
|
||||
Stream& s_;
|
||||
boost::asio::executor_work_guard<decltype(
|
||||
std::declval<Stream&>().get_executor())> wg_;
|
||||
DynamicBuffer& b_;
|
||||
basic_parser<isRequest, Derived>& p_;
|
||||
std::size_t bytes_transferred_ = 0;
|
||||
@@ -57,6 +60,7 @@ public:
|
||||
read_some_op(DeducedHandler&& h, Stream& s,
|
||||
DynamicBuffer& b, basic_parser<isRequest, Derived>& p)
|
||||
: s_(s)
|
||||
, wg_(s_.get_executor())
|
||||
, b_(b)
|
||||
, p_(p)
|
||||
, h_(std::forward<DeducedHandler>(h))
|
||||
@@ -170,10 +174,13 @@ operator()(
|
||||
|
||||
upcall:
|
||||
if(! cont_)
|
||||
return boost::asio::post(
|
||||
{
|
||||
BOOST_ASIO_CORO_YIELD
|
||||
boost::asio::post(
|
||||
s_.get_executor(),
|
||||
bind_handler(std::move(h_),
|
||||
bind_handler(std::move(*this),
|
||||
ec, bytes_transferred_));
|
||||
}
|
||||
h_(ec, bytes_transferred_);
|
||||
}
|
||||
}
|
||||
@@ -209,6 +216,8 @@ class read_op
|
||||
: public boost::asio::coroutine
|
||||
{
|
||||
Stream& s_;
|
||||
boost::asio::executor_work_guard<decltype(
|
||||
std::declval<Stream&>().get_executor())> wg_;
|
||||
DynamicBuffer& b_;
|
||||
basic_parser<isRequest, Derived>& p_;
|
||||
std::size_t bytes_transferred_ = 0;
|
||||
@@ -224,6 +233,7 @@ public:
|
||||
DynamicBuffer& b, basic_parser<isRequest,
|
||||
Derived>& p)
|
||||
: s_(s)
|
||||
, wg_(s_.get_executor())
|
||||
, b_(b)
|
||||
, p_(p)
|
||||
, h_(std::forward<DeducedHandler>(h))
|
||||
@@ -327,6 +337,8 @@ class read_msg_op
|
||||
struct data
|
||||
{
|
||||
Stream& s;
|
||||
boost::asio::executor_work_guard<decltype(
|
||||
std::declval<Stream&>().get_executor())> wg;
|
||||
DynamicBuffer& b;
|
||||
message_type& m;
|
||||
parser_type p;
|
||||
@@ -336,6 +348,7 @@ class read_msg_op
|
||||
data(Handler const&, Stream& s_,
|
||||
DynamicBuffer& b_, message_type& m_)
|
||||
: s(s_)
|
||||
, wg(s.get_executor())
|
||||
, b(b_)
|
||||
, m(m_)
|
||||
, p(std::move(m))
|
||||
@@ -432,7 +445,10 @@ operator()(
|
||||
}
|
||||
upcall:
|
||||
bytes_transferred = d.bytes_transferred;
|
||||
d_.invoke(ec, bytes_transferred);
|
||||
{
|
||||
auto wg = std::move(d.wg);
|
||||
d_.invoke(ec, bytes_transferred);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <boost/beast/core/detail/config.hpp>
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/executor_work_guard.hpp>
|
||||
#include <boost/asio/handler_continuation_hook.hpp>
|
||||
#include <boost/asio/handler_invoke_hook.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
@@ -38,6 +39,8 @@ template<
|
||||
class write_some_op
|
||||
{
|
||||
Stream& s_;
|
||||
boost::asio::executor_work_guard<decltype(
|
||||
std::declval<Stream&>().get_executor())> wg_;
|
||||
serializer<isRequest,Body, Fields>& sr_;
|
||||
Handler h_;
|
||||
|
||||
@@ -74,6 +77,7 @@ public:
|
||||
write_some_op(DeducedHandler&& h, Stream& s,
|
||||
serializer<isRequest, Body, Fields>& sr)
|
||||
: s_(s)
|
||||
, wg_(s_.get_executor())
|
||||
, sr_(sr)
|
||||
, h_(std::forward<DeducedHandler>(h))
|
||||
{
|
||||
@@ -204,11 +208,13 @@ template<
|
||||
bool isRequest, class Body, class Fields>
|
||||
class write_op
|
||||
{
|
||||
int state_ = 0;
|
||||
Stream& s_;
|
||||
boost::asio::executor_work_guard<decltype(
|
||||
std::declval<Stream&>().get_executor())> wg_;
|
||||
serializer<isRequest, Body, Fields>& sr_;
|
||||
std::size_t bytes_transferred_ = 0;
|
||||
Handler h_;
|
||||
int state_ = 0;
|
||||
|
||||
public:
|
||||
write_op(write_op&&) = default;
|
||||
@@ -218,6 +224,7 @@ public:
|
||||
write_op(DeducedHandler&& h, Stream& s,
|
||||
serializer<isRequest, Body, Fields>& sr)
|
||||
: s_(s)
|
||||
, wg_(s_.get_executor())
|
||||
, sr_(sr)
|
||||
, h_(std::forward<DeducedHandler>(h))
|
||||
{
|
||||
@@ -321,11 +328,14 @@ class write_msg_op
|
||||
struct data
|
||||
{
|
||||
Stream& s;
|
||||
boost::asio::executor_work_guard<decltype(
|
||||
std::declval<Stream&>().get_executor())> wg;
|
||||
serializer<isRequest, Body, Fields> sr;
|
||||
|
||||
data(Handler const&, Stream& s_, message<
|
||||
isRequest, Body, Fields>& m_)
|
||||
: s(s_)
|
||||
, wg(s.get_executor())
|
||||
, sr(m_)
|
||||
{
|
||||
}
|
||||
@@ -405,6 +415,7 @@ write_msg_op<
|
||||
Stream, Handler, isRequest, Body, Fields>::
|
||||
operator()(error_code ec, std::size_t bytes_transferred)
|
||||
{
|
||||
auto wg = std::move(d_->wg);
|
||||
d_.invoke(ec, bytes_transferred);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <boost/asio/coroutine.hpp>
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/executor_work_guard.hpp>
|
||||
#include <boost/asio/handler_continuation_hook.hpp>
|
||||
#include <boost/asio/handler_invoke_hook.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
@@ -43,6 +44,8 @@ class stream<NextLayer, deflateSupported>::response_op
|
||||
struct data
|
||||
{
|
||||
stream<NextLayer, deflateSupported>& ws;
|
||||
boost::asio::executor_work_guard<decltype(std::declval<
|
||||
stream<NextLayer, deflateSupported>&>().get_executor())> wg;
|
||||
error_code result;
|
||||
response_type res;
|
||||
|
||||
@@ -54,6 +57,7 @@ class stream<NextLayer, deflateSupported>::response_op
|
||||
http::basic_fields<Allocator>> const& req,
|
||||
Decorator const& decorator)
|
||||
: ws(ws_)
|
||||
, wg(ws.get_executor())
|
||||
, res(ws_.build_response(req, decorator, result))
|
||||
{
|
||||
}
|
||||
@@ -137,7 +141,10 @@ operator()(
|
||||
d.ws.do_pmd_config(d.res, is_deflate_supported{});
|
||||
d.ws.open(role_type::server);
|
||||
}
|
||||
d_.invoke(ec);
|
||||
{
|
||||
auto wg = std::move(d.wg);
|
||||
d_.invoke(ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,6 +160,8 @@ class stream<NextLayer, deflateSupported>::accept_op
|
||||
struct data
|
||||
{
|
||||
stream<NextLayer, deflateSupported>& ws;
|
||||
boost::asio::executor_work_guard<decltype(std::declval<
|
||||
stream<NextLayer, deflateSupported>&>().get_executor())> wg;
|
||||
Decorator decorator;
|
||||
http::request_parser<http::empty_body> p;
|
||||
data(
|
||||
@@ -160,6 +169,7 @@ class stream<NextLayer, deflateSupported>::accept_op
|
||||
stream<NextLayer, deflateSupported>& ws_,
|
||||
Decorator const& decorator_)
|
||||
: ws(ws_)
|
||||
, wg(ws.get_executor())
|
||||
, decorator(decorator_)
|
||||
{
|
||||
}
|
||||
@@ -284,6 +294,7 @@ operator()(error_code ec, std::size_t)
|
||||
auto& ws = d.ws;
|
||||
auto const req = d.p.release();
|
||||
auto const decorator = d.decorator;
|
||||
auto wg = std::move(d.wg);
|
||||
#if 1
|
||||
return response_op<Handler>{
|
||||
d_.release_handler(),
|
||||
@@ -297,7 +308,10 @@ operator()(error_code ec, std::size_t)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
d_.invoke(ec);
|
||||
{
|
||||
auto wg = std::move(d.wg);
|
||||
d_.invoke(ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/coroutine.hpp>
|
||||
#include <boost/asio/executor_work_guard.hpp>
|
||||
#include <boost/asio/handler_continuation_hook.hpp>
|
||||
#include <boost/asio/handler_invoke_hook.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
@@ -43,6 +44,8 @@ class stream<NextLayer, deflateSupported>::close_op
|
||||
struct state
|
||||
{
|
||||
stream<NextLayer, deflateSupported>& ws;
|
||||
boost::asio::executor_work_guard<decltype(std::declval<
|
||||
stream<NextLayer, deflateSupported>&>().get_executor())> wg;
|
||||
detail::frame_buffer fb;
|
||||
error_code ev;
|
||||
bool cont = false;
|
||||
@@ -52,6 +55,7 @@ class stream<NextLayer, deflateSupported>::close_op
|
||||
stream<NextLayer, deflateSupported>& ws_,
|
||||
close_reason const& cr)
|
||||
: ws(ws_)
|
||||
, wg(ws.get_executor())
|
||||
{
|
||||
// Serialize the close frame
|
||||
ws.template write_close<
|
||||
@@ -303,12 +307,15 @@ operator()(
|
||||
d.ws.paused_wr_.maybe_invoke();
|
||||
if(! d.cont)
|
||||
{
|
||||
auto& ws = d.ws;
|
||||
return boost::asio::post(
|
||||
ws.stream_.get_executor(),
|
||||
bind_handler(d_.release_handler(), ec));
|
||||
BOOST_ASIO_CORO_YIELD
|
||||
boost::asio::post(
|
||||
d.ws.get_executor(),
|
||||
bind_handler(std::move(*this), ec));
|
||||
}
|
||||
{
|
||||
auto wg = std::move(d.wg);
|
||||
d_.invoke(ec);
|
||||
}
|
||||
d_.invoke(ec);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/coroutine.hpp>
|
||||
#include <boost/asio/executor_work_guard.hpp>
|
||||
#include <boost/asio/handler_continuation_hook.hpp>
|
||||
#include <boost/asio/handler_invoke_hook.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
@@ -42,6 +43,8 @@ class stream<NextLayer, deflateSupported>::handshake_op
|
||||
struct data
|
||||
{
|
||||
stream<NextLayer, deflateSupported>& ws;
|
||||
boost::asio::executor_work_guard<decltype(std::declval<
|
||||
stream<NextLayer, deflateSupported>&>().get_executor())> wg;
|
||||
response_type* res_p;
|
||||
detail::sec_ws_key_type key;
|
||||
http::request<http::empty_body> req;
|
||||
@@ -56,6 +59,7 @@ class stream<NextLayer, deflateSupported>::handshake_op
|
||||
string_view target,
|
||||
Decorator const& decorator)
|
||||
: ws(ws_)
|
||||
, wg(ws.get_executor())
|
||||
, res_p(res_p_)
|
||||
, req(ws.build_request(key,
|
||||
host, target, decorator))
|
||||
@@ -155,7 +159,10 @@ operator()(error_code ec, std::size_t)
|
||||
if(d.res_p)
|
||||
swap(d.res, *d.res_p);
|
||||
upcall:
|
||||
d_.invoke(ec);
|
||||
{
|
||||
auto wg = std::move(d.wg);
|
||||
d_.invoke(ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/coroutine.hpp>
|
||||
#include <boost/asio/executor_work_guard.hpp>
|
||||
#include <boost/asio/handler_continuation_hook.hpp>
|
||||
#include <boost/asio/handler_invoke_hook.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
@@ -41,6 +42,8 @@ class stream<NextLayer, deflateSupported>::ping_op
|
||||
struct state
|
||||
{
|
||||
stream<NextLayer, deflateSupported>& ws;
|
||||
boost::asio::executor_work_guard<decltype(std::declval<
|
||||
stream<NextLayer, deflateSupported>&>().get_executor())> wg;
|
||||
detail::frame_buffer fb;
|
||||
|
||||
state(
|
||||
@@ -49,6 +52,7 @@ class stream<NextLayer, deflateSupported>::ping_op
|
||||
detail::opcode op,
|
||||
ping_data const& payload)
|
||||
: ws(ws_)
|
||||
, wg(ws.get_executor())
|
||||
{
|
||||
// Serialize the control frame
|
||||
ws.template write_ping<
|
||||
@@ -172,7 +176,10 @@ operator()(error_code ec, std::size_t)
|
||||
d.ws.paused_close_.maybe_invoke() ||
|
||||
d.ws.paused_rd_.maybe_invoke() ||
|
||||
d.ws.paused_wr_.maybe_invoke();
|
||||
d_.invoke(ec);
|
||||
{
|
||||
auto wg = std::move(d.wg);
|
||||
d_.invoke(ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/coroutine.hpp>
|
||||
#include <boost/asio/executor_work_guard.hpp>
|
||||
#include <boost/asio/handler_continuation_hook.hpp>
|
||||
#include <boost/asio/handler_invoke_hook.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
@@ -82,6 +83,8 @@ class stream<NextLayer, deflateSupported>::read_some_op
|
||||
{
|
||||
Handler h_;
|
||||
stream<NextLayer, deflateSupported>& ws_;
|
||||
boost::asio::executor_work_guard<decltype(std::declval<
|
||||
stream<NextLayer, deflateSupported>&>().get_executor())> wg_;
|
||||
MutableBufferSequence bs_;
|
||||
buffers_suffix<MutableBufferSequence> cb_;
|
||||
std::size_t bytes_written_ = 0;
|
||||
@@ -103,6 +106,7 @@ public:
|
||||
MutableBufferSequence const& bs)
|
||||
: h_(std::forward<DeducedHandler>(h))
|
||||
, ws_(ws)
|
||||
, wg_(ws_.get_executor())
|
||||
, bs_(bs)
|
||||
, cb_(bs)
|
||||
, code_(close_code::none)
|
||||
@@ -700,10 +704,13 @@ operator()(
|
||||
ws_.paused_ping_.maybe_invoke() ||
|
||||
ws_.paused_wr_.maybe_invoke();
|
||||
if(! cont_)
|
||||
return boost::asio::post(
|
||||
ws_.stream_.get_executor(),
|
||||
bind_handler(std::move(h_),
|
||||
{
|
||||
BOOST_ASIO_CORO_YIELD
|
||||
boost::asio::post(
|
||||
ws_.get_executor(),
|
||||
bind_handler(std::move(*this),
|
||||
ec, bytes_written_));
|
||||
}
|
||||
h_(ec, bytes_written_);
|
||||
}
|
||||
}
|
||||
@@ -719,6 +726,8 @@ class stream<NextLayer, deflateSupported>::read_op
|
||||
{
|
||||
Handler h_;
|
||||
stream<NextLayer, deflateSupported>& ws_;
|
||||
boost::asio::executor_work_guard<decltype(std::declval<
|
||||
stream<NextLayer, deflateSupported>&>().get_executor())> wg_;
|
||||
DynamicBuffer& b_;
|
||||
std::size_t limit_;
|
||||
std::size_t bytes_written_ = 0;
|
||||
@@ -740,6 +749,7 @@ public:
|
||||
bool some)
|
||||
: h_(std::forward<DeducedHandler>(h))
|
||||
, ws_(ws)
|
||||
, wg_(ws_.get_executor())
|
||||
, b_(b)
|
||||
, limit_(limit ? limit : (
|
||||
std::numeric_limits<std::size_t>::max)())
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/coroutine.hpp>
|
||||
#include <boost/asio/executor_work_guard.hpp>
|
||||
#include <boost/asio/handler_continuation_hook.hpp>
|
||||
#include <boost/asio/handler_invoke_hook.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
@@ -34,6 +35,8 @@ class teardown_tcp_op : public boost::asio::coroutine
|
||||
|
||||
Handler h_;
|
||||
socket_type& s_;
|
||||
boost::asio::executor_work_guard<decltype(std::declval<
|
||||
socket_type&>().get_executor())> wg_;
|
||||
role_type role_;
|
||||
bool nb_;
|
||||
|
||||
@@ -48,6 +51,7 @@ public:
|
||||
role_type role)
|
||||
: h_(std::forward<DeducedHandler>(h))
|
||||
, s_(s)
|
||||
, wg_(s_.get_executor())
|
||||
, role_(role)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/coroutine.hpp>
|
||||
#include <boost/asio/executor_work_guard.hpp>
|
||||
#include <boost/asio/handler_continuation_hook.hpp>
|
||||
#include <boost/asio/handler_invoke_hook.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
@@ -141,6 +142,8 @@ class stream<NextLayer, deflateSupported>::write_some_op
|
||||
{
|
||||
Handler h_;
|
||||
stream<NextLayer, deflateSupported>& ws_;
|
||||
boost::asio::executor_work_guard<decltype(std::declval<
|
||||
stream<NextLayer, deflateSupported>&>().get_executor())> wg_;
|
||||
buffers_suffix<Buffers> cb_;
|
||||
detail::frame_header fh_;
|
||||
detail::prepared_key key_;
|
||||
@@ -166,6 +169,7 @@ public:
|
||||
Buffers const& bs)
|
||||
: h_(std::forward<DeducedHandler>(h))
|
||||
, ws_(ws)
|
||||
, wg_(ws_.get_executor())
|
||||
, cb_(bs)
|
||||
, fin_(fin)
|
||||
{
|
||||
@@ -569,9 +573,12 @@ operator()(
|
||||
ws_.paused_rd_.maybe_invoke() ||
|
||||
ws_.paused_ping_.maybe_invoke();
|
||||
if(! cont_)
|
||||
return boost::asio::post(
|
||||
ws_.stream_.get_executor(),
|
||||
bind_handler(std::move(h_), ec, bytes_transferred_));
|
||||
{
|
||||
BOOST_ASIO_CORO_YIELD
|
||||
boost::asio::post(
|
||||
ws_.get_executor(),
|
||||
bind_handler(std::move(*this), ec, bytes_transferred_));
|
||||
}
|
||||
h_(ec, bytes_transferred_);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user