Boost logo

Boost :

From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2021-09-22 14:33:36


wt., 21 wrz 2021 o 17:22 Дмитрий Архипов via Boost <boost_at_[hidden]>
napisał(a):

> I haven't tested it, but this should probably work:
>
> class session {
> public:
> session(tcp::socket socket)
> : session(std::make_unique<session_impl>(std::move(socket)))
> {}
>
> void start() { do_read(); }
>
> private:
> session(std::unique_ptr<session_impl> impl) : impl_(std::move(impl)) {}
>
> void do_read()
> {
> auto& impl = *impl_;
> impl.socket.async_read_some(
> boost::asio::buffer(impl.data, max_length),
> [impl = std::move(impl_)](boost::system::error_code ec,
> std::size_t length) mutable {
> if (ec) { return; }
> session(std::move(impl)).do_write(length);
> });
> }
>
> void do_write(std::size_t length) { ... }
>
> auto constexpr max_length = 1024;
> struct session_impl {
> session_impl(tcp::socket socket) : socket_(std::move(socket)) {}
> tcp::socket socket_;
> char data_[max_length];
> };
> };
>
> ...
>
> session(std::move(socket)).start();
>

Thank you for this example. I haven't compiled it yet, but my superficial
analysis tells me that it should work.
I asked the question, you gave the right answer, so I should only be
thankful, I guess.
But having seen the answer, I now realize that I asked the wrong question.
The question that I really wanted to ask is:
do I have to heap-allocate "IO" objects in order to use tem with
continuation-passing style completion handlers?

My observation about the example code:

  void do_read()
  {
    auto self(shared_from_this());
    *socket_ *// <-- socket passed in one place
    .async_read_some(boost::asio::buffer(data_, max_length),
        [this, *self*] // <-- socket passed in another place
        (boost::system::error_code ec, std::size_t length)
        {
          if (!ec)
          {
            do_write(length);
          }
        });
  }

is that I have to pass my socket in two places in one function invocation.
Whereas, at least at high level, I could imagine an interface when I only
pass it once (by movig) to function async_read_some, and after the function
has made the read it passes (via a move) the socket argument to the
handler. Is there something fundamental that makes this impossible?

Regards,
&rzej;

> вт, 21 сент. 2021 г. в 18:02, Andrzej Krzemienski via Boost
> <boost_at_[hidden]>:
> >
> > wt., 21 wrz 2021 o 16:50 Vinnie Falco via Boost <boost_at_[hidden]>
> > napisał(a):
> >
> > > On Tue, Sep 21, 2021 at 7:34 AM Andrzej Krzemienski via Boost
> > > <boost_at_[hidden]> wrote:
> > > > I am not trying to solve any specific problem. It just strikes me
> that a
> > > > shared_ptr is used in a demo example for the library. I was always
> of the
> > > > opinion that a shared_ptr is often abused as a way of doing an
> ad-hoc GC.
> > >
> > > In theory it should work since the echo protocol is half-duplex. What
> > > happens when you switch it to unique_ptr? Move-only handlers should
> > > work, but it is possible that Chris missed a place that is still doing
> > > a copy.
> > >
> >
> > It breaks when I pass a callback (completion handler), for instance in:
> >
> > void do_read()
> > {
> > auto self(shared_from_this());
> > socket_.async_read_some(boost::asio::buffer(data_, max_length),
> > [this, *self*](boost::system::error_code ec, std::size_t length)
> > {
> > if (!ec)
> > {
> > do_write(length);
> > }
> > });
> > }
> >
> > I would need to move the data inside the lambda capture, but if I do
> > it, the subsequent call to socket_.async_read_some() is UB.
> >
> > In order for this to work, the function `async_read_some()` would have
> > to pass the socket back to my handler after it has performed the read.
> >
> > Regards,
> > &rzej;
> >
> > _______________________________________________
> > Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk