пытаясь понять пример наддува httpserver3. Что-то непонятное с методом сброса shared_ptr

Я работаю с Boost пример httpserver3: http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/examples.html#boost_asio.examples.http_server_3

Я не могу четко понять, что происходит, когда вызывается метод сброса new_connection_

void server::start_accept()
{
new_connection_.reset(new connection(io_service_, request_handler_));
acceptor_.async_accept(new_connection_->socket(),
boost::bind(&server::handle_accept, this,
boost::asio::placeholders::error));
}

void server::handle_accept(const boost::system::error_code& e)
{
if (!e)
{
new_connection_->start();
}
std::cout<<"handle_accept"<<std::endl;
start_accept();
}

Я знаю, что «сброс» приведет к удалению предыдущего объекта, как сказано в документации.
что происходит, если объект сервера принимает новое соединение, в то время как предыдущий объект соединения обрабатывает свой запрос? предыдущее соединение будет немедленно разорвано или оно получит ошибку и завершит работу?

void connection::handle_read(const boost::system::error_code& e,
std::size_t bytes_transferred)
{
if (!e)
{
boost::tribool result;
boost::tie(result, boost::tuples::ignore) = request_parser_.parse(
request_, buffer_.data(), buffer_.data() + bytes_transferred);

if (result)
{
request_handler_.handle_request(request_, reply_);
boost::asio::async_write(socket_, reply_.to_buffers(),
strand_.wrap(
boost::bind(&connection::handle_write, shared_from_this(),
boost::asio::placeholders::error)));
}
else if (!result)
{
reply_ = reply::stock_reply(reply::bad_request);
boost::asio::async_write(socket_, reply_.to_buffers(),
strand_.wrap(
boost::bind(&connection::handle_write, shared_from_this(),
boost::asio::placeholders::error)));
}
else
{
socket_.async_read_some(boost::asio::buffer(buffer_),
strand_.wrap(
boost::bind(&connection::handle_read, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)));
}
}

// If an error occurs then no new asynchronous operations are started. This
// means that all shared_ptr references to the connection object will
// disappear and the object will be destroyed automatically after this
// handler returns. The connection class's destructor closes the socket.
}

void connection::handle_write(const boost::system::error_code& e)
{
if (!e)
{
// Initiate graceful connection closure.
boost::system::error_code ignored_ec;
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
}

// No new asynchronous operations are started. This means that all shared_ptr
// references to the connection object will disappear and the object will be
// destroyed automatically after this handler returns. The connection class's
// destructor closes the socket.
}

0

Решение

Ах, магия shared_from_this(), Вы пропустили эту часть кода:

void connection::start()
{
socket_.async_read_some(boost::asio::buffer(buffer_),
strand_.wrap(
boost::bind(&connection::handle_read, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)));
}

Что происходит, это:

  1. server::handle_accept() звонки new_connection_->start(),
  2. connection::start() планирует операцию чтения и создает копию исходного общего указателя с shared_from_this() вызов.
  3. Сейчас server::handle_accept() звонки server::start_accept(),
  4. server::start_accept() делает reset() исходный общий указатель, но у службы ASIO есть его копия, так что пока обратные вызовы соединения продолжают планировать больше операций, используя shared_from_this(), соединение не будет уничтожено (потому что будет хотя бы один общий указатель, все еще указывающий на выделенную кучу connection объект).
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]