Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this ASIO example use members variables to pass state rather than using bind?

In the ASIO HTTP Server 3 example there is code like this:

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();
  }

  start_accept();
}

Essentially, new_connection_ is a member of the server class and is used to pass a connection from start_accept to handle_accept. Now, I'm curious as to why new_connection_ is implemented as a member variable.

Wouldn't it also work to pass the connection using bind instead of a member variable? Like this:

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

void server::handle_accept(boost::system::error_code const& error, std::shared_ptr<connection> new_connection)
{
  if (!error) {
    new_connection->start();
  }
  start_accept();
}

If so, why does the example use member variables? Is it to avoid the copying involved?

(note: I'm not comfortable with ASIO yet and so there may be a fundamental misconception here)

like image 707
Pubby Avatar asked Oct 05 '22 06:10

Pubby


1 Answers

Passing the socket variable inside a function created with std::bind is more or less the same as retaining it as a member variable in the http::server3::server class. Using bind will create temporaries whereas using the member variable will not. I don't think that is a big concern here as the std::shared_ptr is not terribly expensive to copy nor is this code path in the example a performance critical section.

When writing my own applications I find myself using both techniques. If the asynchronous call chain is very long I will typical retain the variables as members to simplify the handler's function signatures and prevent code repetition. For shorter call chains, keeping the state variables in the functor created from bind is a bit easier to understand the code's logic.

like image 103
Sam Miller Avatar answered Oct 13 '22 10:10

Sam Miller