Does async_accept only access connection object raw pointer and wrapped it by shared pointer internally?
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.
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
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@gmail.com office: +442032898513 home: +376841522 mobile: +376380212 (this will be *expensive* outside Andorra!) skype: madmongo facebook: hodges.r
Thanks Richard, appreciate it.
On 12/26/18, Richard Hodges via Boost
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
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@gmail.com office: +442032898513 home: +376841522 mobile: +376380212 (this will be *expensive* outside Andorra!) skype: madmongo facebook: hodges.r
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On Tue, Dec 25, 2018 at 10:13 PM Richard Hodges via Boost
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:
I explain all of this in simple terms, in my CppCon 2018 presentation titled "Get rich quick! Using Boost.Beast WebSockets and Networking TS", available here: https://www.youtube.com/watch?v=7FQwAjELMek All of the source code for the program developed in the video is part of Boost.Beast 1.69.0. Regards
participants (3)
-
hh h
-
Richard Hodges
-
Vinnie Falco