Boost logo

Boost :

Subject: Re: [boost] Does async_accept only access connection object raw pointer and wrapped it by shared pointer internally?
From: Richard Hodges (hodges.r_at_[hidden])
Date: 2018-12-26 06:11:37


In this example, async_accept is not accepting any raw pointer. The raw
pointer is being bound to the handler.

What you are not doing is preserving the lifetime of the session because
you're not storing new_session anywhere.

It becomes a little easier to follow if you use a lambda:

auto new_session = std::make_shared<session>(io_service_, context_);

auto handler = [new_session, this](auto ec) mutable // 1
{
  // 2
  if (ec == boost::system::error_code()) // no error
    new_session->start(); // 3
  else
    this->report_error(ec);
};

acceptor_.async_accept(new_session->socket(), std::move(handler));

Notes:
1: recent versions of asio understand rvalues and avoid copying mutable
handlers.
2: note that the shared_ptr to session has been captured by the handler.
This will keep it alive until after the handler has been invoked.
3. session::start would capture itself when issuing async operations on the
socket. You would derive it from std::enable_shared_from_this<session>. e.g.

void session::initiate_read()
{
  auto handler = [self = shared_from_this()](auto ec, auto
bytes_transferred) mutable //4
  {
    if (ec == system::error_code()) // no error
    {
        self->handle_data(bytes_transferred);
        self->initiate_read();
    }
    else
      self->handle_read_error(ec);
  };

  asio::async_read_until(socket, read_buffer, '\n', std::move(handler));
// for example
}

4: note that we have captured the lifetime of the session before the async
handler for async_accept has completed. Therefore we extend the lifetime of
the session.

On Wed, 26 Dec 2018 at 05:22, hh h via Boost <boost_at_[hidden]> wrote:

> I don't like to use raw pointer by new and delete, but the following
> code will be crashed by double delete, can't async_accept accept
> shared pointer?
>
> std::shared_ptr<session> new_session =
> std::make_shared<session>(io_service_, context_);
> acceptor_.async_accept(new_session->socket(),
> boost::bind(&server::handle_accept, this, new_session.get(),
> boost::asio::placeholders::error));
>
> Thank you.
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>

-- 
Richard Hodges
hodges.r_at_[hidden]
office: +442032898513
home: +376841522
mobile: +376380212 (this will be *expensive* outside Andorra!)
skype: madmongo
facebook: hodges.r

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