I am using std::future
with boost::asio::async_connect
in order to cancel the operation when a timeout occurs, as suggested here: https://stackoverflow.com/a/30428941
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?
EDIT: SSCCE
#include <iostream>
#include <future>
#include <thread>
#include <boost/asio.hpp>
#include <boost/asio/use_future.hpp>
using boost::asio::ip::tcp;
int main(int argc, char* argv[]) {
boost::asio::io_service ioservice;
boost::asio::io_service::work work(ioservice);
std::thread t([&](){ioservice.run();});
tcp::resolver resolver(ioservice);
tcp::resolver::query query("127.0.0.1","27015"); // random unused adress
tcp::socket 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();
std::cout << "Timeout" << std::endl;
return 0;
} else if(status == std::future_status::deferred) {
std::cout << "Deferred" << std::endl;
}
// If the operation failed, then conn_result.get() will throw a
// boost::system::system_error.
try {
conn_result.get();
} catch(const boost::system::system_error& e) {
std::cerr << e.what() << std::endl;
}
ioservice.stop();
t.join();
return 0;
}
- Compiler: MSVC2012
- Boost 1.58