mardi 21 juillet 2015

Waiting with timeout on boost::asio::async_connect fails (std::future::wait_for)

I am using std::future with boost::asio::async_connect in order to cancel the operation when a timeout occurs, as suggested here: http://ift.tt/1g0Z8Yw

However, std::future::wait_for() returns std::future_status::deferred immediately, i.e. the operation hasn't been started yet. conn_result.get() later blocks until a connection error is thrown because the remote host isn't listening. I don't want to rely on that because it could last very long until a socket error is thrown.

How do I wait properly on futures created by boost::asio?

bool TCPConnection::connectToServer(const std::string& host, size_t port) { 
    tcp::resolver resolver(ioservice);
    tcp::resolver::query query(host,std::to_string(port));

    socket.reset(new tcp::socket(ioservice));

    std::future<tcp::resolver::iterator> conn_result = boost::asio::async_connect(*socket,resolver.resolve(query),boost::asio::use_future);

    std::cout << "IO Service running: " << (!ioservice.stopped() ? "y":"n") << std::endl;
    auto status = conn_result.wait_for(std::chrono::milliseconds(500));
    if (status == std::future_status::timeout) {
        socket->cancel();
        socket.reset();
        throw timeout_error("Timeout");
    } else {
        conn_result.get();
    }

    return true;
}

  • The io service is running, see the std::cout line above.
  • socket is of type std::unique_ptr<tcp::socket>
  • Compiler: MSVC2012
  • Boost 1.58

Aucun commentaire:

Enregistrer un commentaire